From 93a4a6bb976660324783f55e0cb282f90b3f268b Mon Sep 17 00:00:00 2001 From: khalil <842328916@qq.com> Date: Mon, 8 Sep 2025 17:39:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A6=E5=8D=95-=E9=9B=AA=E8=8A=B1=E4=B8=BB?= =?UTF-8?q?=E9=94=AE-workerId-=E9=80=9A=E8=BF=87docker=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=B3=A8=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/accompany/core/util/WorkerIdUtil.java | 83 +++++++++++++++---- .../sharding/config/MybatisPlusConfig.java | 5 +- 2 files changed, 69 insertions(+), 19 deletions(-) diff --git a/accompany-base/accompany-core/src/main/java/com/accompany/core/util/WorkerIdUtil.java b/accompany-base/accompany-core/src/main/java/com/accompany/core/util/WorkerIdUtil.java index da17c191a..d38bdf79b 100644 --- a/accompany-base/accompany-core/src/main/java/com/accompany/core/util/WorkerIdUtil.java +++ b/accompany-base/accompany-core/src/main/java/com/accompany/core/util/WorkerIdUtil.java @@ -12,26 +12,36 @@ import java.util.Enumeration; @Slf4j public class WorkerIdUtil { - public static long generateWorkerId() { + public static long generateDataCenterId() { InetAddress host = null; - try { - host = InetAddress.getByName("host.docker.internal"); - } catch (UnknownHostException e) { - log.error("[workerId] 获取不到docker宿主机的ip"); - } - - if (null == host){ - try { - host = InetAddress.getLocalHost(); - } catch (UnknownHostException e) { - log.error("[workerId] 获取不到localhost的ip"); - throw new RuntimeException(e); + String ip = null; + + // 优先使用Docker环境变量HOST_IP + String hostIpEnv = System.getenv("HOST_IP"); + if (hostIpEnv != null && !hostIpEnv.isEmpty()) { + ip = hostIpEnv; + log.info("[workerId] 使用环境变量HOST_IP: {}", ip); + } else { + // 如果没有设置HOST_IP环境变量,则使用原来的逻辑获取本地IP + if (null == host){ + try { + host = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + log.error("[workerId] 获取不到localhost的ip"); + throw new RuntimeException(e); + } } + ip = host.getHostAddress(); + } + + if (StringUtils.isBlank(ip)){ + log.error("[workerId] 获取不到ip"); + throw new RuntimeException("[workerId] 获取不到ip"); } - String ip = host.getHostAddress(); byte[] mac = null; + // 只有在没有使用环境变量且host不为null的情况下才尝试获取MAC地址 try { NetworkInterface networkInterface = NetworkInterface.getByInetAddress(host); if (networkInterface != null) { @@ -40,7 +50,7 @@ public class WorkerIdUtil { } catch (SocketException e) { log.error("[workerId] 获取不到ip {} 的 mac地址", ip); } - + // 如果通过InetAddress找不到MAC地址,则尝试遍历网络接口 if (mac == null) { try { @@ -62,14 +72,53 @@ public class WorkerIdUtil { if (mac == null) { log.warn("[workerId] 无法获取MAC地址,使用IP地址哈希生成workerId"); long workerId = Math.abs(ip.hashCode()) % 32; - log.info("Generated workerId: {} from IP: {}", workerId, ip); + log.info("[workerId] workerId: {} from IP: {}", workerId, ip); return workerId; } // 根据 MAC 或 IP 哈希生成 workerId long workerId = Math.abs(Arrays.hashCode(mac)) % 32; - log.info("Generated workerId: {} from IP: {} MAC: {}", workerId, ip, Arrays.toString(mac)); + log.info("[workerId] dataCenterId: {} from IP: {} MAC: {}", workerId, ip, Arrays.toString(mac)); return workerId; } + + /** + * 从Docker宿主机端口生成workerId + * 优先使用SERVICE_PORT环境变量,也可使用DOCKER_PORT或SERVER_PORT环境变量 + * 最后使用Spring Boot启动端口作为后备方案 + * + * @return 生成的workerId (0-31之间) + */ + public static long generateWorkerIdFromPort() { + // 优先使用SERVICE_PORT环境变量(根据用户的docker run命令) + String servicePortEnv = System.getenv("SERVICE_PORT"); + if (servicePortEnv != null && !servicePortEnv.isEmpty()) { + try { + int port = Integer.parseInt(servicePortEnv); + long workerId = Math.abs(port) % 32; + log.info("[workerId] 使用环境变量SERVICE_PORT: {}, 生成workerId: {}", port, workerId); + return workerId; + } catch (NumberFormatException e) { + log.warn("[workerId] SERVICE_PORT环境变量不是有效数字: {}", servicePortEnv); + } + } + + // 使用Spring Boot启动端口作为后备方案 + String springBootPort = System.getProperty("server.port"); + if (springBootPort != null && !springBootPort.isEmpty()) { + try { + int port = Integer.parseInt(springBootPort); + long workerId = Math.abs(port) % 32; + log.info("[workerId] 使用Spring Boot启动端口: {}, 生成workerId: {}", port, workerId); + return workerId; + } catch (NumberFormatException e) { + log.warn("[workerId] Spring Boot启动端口不是有效数字: {}", springBootPort); + } + } + + // 如果都没有设置,默认返回1 + log.warn("[workerId] 未设置SERVICE_PORT或者Spring Boot启动端口,默认使用workerId: 1"); + return 1; + } } \ No newline at end of file diff --git a/accompany-base/accompany-sharding/accompany-sharding-service/src/main/java/com/accompany/sharding/config/MybatisPlusConfig.java b/accompany-base/accompany-sharding/accompany-sharding-service/src/main/java/com/accompany/sharding/config/MybatisPlusConfig.java index 0c8061c35..1779f66ad 100644 --- a/accompany-base/accompany-sharding/accompany-sharding-service/src/main/java/com/accompany/sharding/config/MybatisPlusConfig.java +++ b/accompany-base/accompany-sharding/accompany-sharding-service/src/main/java/com/accompany/sharding/config/MybatisPlusConfig.java @@ -87,8 +87,9 @@ public class MybatisPlusConfig { @Bean public IdentifierGenerator idGenerator() { - long workerId = WorkerIdUtil.generateWorkerId(); - return new CustomIdGenerator(workerId, 1); // 设置你的 workerId 和 dataCenterId + long workerId = WorkerIdUtil.generateWorkerIdFromPort(); + long dataCenterId = WorkerIdUtil.generateDataCenterId(); + return new CustomIdGenerator(workerId, dataCenterId); // 设置你的 workerId 和 dataCenterId } public static class CustomIdGenerator implements IdentifierGenerator {