美食家大橙子 发表于 2024-12-30 15:57:49

springboot~多节点应用里的雪花算法唯一性

雪花算法的唯一性,在单个节点中是可以保证的,对应kubernetes中的应用,如果是横向扩展后,进行多副本的情况下,大概出现重复的ID,这需要我们按着pod_name进行一个workId的生成,我照旧发起通过不引入第三方组件和网络哀求的条件下解决这个标题,以是我修改了kubernetes的yaml文件。

[*]k8s的yaml设置
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
    matchLabels:
      app: my-app
template:
    metadata:
      labels:
      app: my-app
    spec:
      containers:
      - name: my-container
      image: my-image:latest
      env:
      - name: POD_NAME
          valueFrom:
            fieldRef:
            fieldPath: metadata.name# 获取当前 Pod 的名称

[*]字符串(0~1024)数字方法,通过掩码的方式
public static int stringToNumber(String input) {
      // 使用CRC32计算字符串的哈希值
      CRC32 crc = new CRC32();
      byte[] bytes = input.getBytes(StandardCharsets.UTF_8);
      crc.update(bytes);
      
      // 获取哈希值并限制在0到1023之间
      long hashValue = crc.getValue();
      return (int) (hashValue % 1024);
    }

[*]获取服务器机器码
/**
       * 获取机器码.
       * @return
       */
        public static String getUniqueMachineId() {
                StringBuilder uniqueId = new StringBuilder();

                try {
                        // 获取本机的IP地址
                        InetAddress localHost = InetAddress.getLocalHost();
                        uniqueId.append(localHost.getHostAddress()).append("_");

                        // 获取网络接口并获取MAC地址
                        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
                        while (networkInterfaces.hasMoreElements()) {
                                NetworkInterface networkInterface = networkInterfaces.nextElement();
                                byte[] mac = networkInterface.getHardwareAddress();
                                if (mac != null) {
                                        for (int i = 0; i < mac.length; i++) {
                                                uniqueId.append(String.format("%02X", mac));
                                                if (i < mac.length - 1) {
                                                        uniqueId.append("-");
                                                }
                                        }
                                        uniqueId.append("_");
                                }
                        }

                        // 添加系统信息作为补充
                        String osName = System.getProperty("os.name");
                        String osVersion = System.getProperty("os.version");
                        String userName = System.getProperty("user.name");
                        uniqueId.append(osName).append("_").append(osVersion).append("_").append(userName);

                }
                catch (Exception e) {
                        e.printStackTrace();
                }

                return uniqueId.toString();
        }

[*]ID生成器的改进
@Slf4j
public class IdUtils {

        static SnowFlakeGenerator snowFlakeGenerator;

        public static String generateId() {
                if (snowFlakeGenerator == null) {
                        long podNameCode = stringToNumber(Optional.ofNullable(System.getenv("POD_NAME")).orElse(stringToNumber(getUniqueMachineId())));
                        log.debug("podNameCode:{}", podNameCode);
                        snowFlakeGenerator = new SnowFlakeGenerator(podNameCode);

                }
                return snowFlakeGenerator.hexNextId();
        }
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: springboot~多节点应用里的雪花算法唯一性