写点什么

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

  • 2024-12-31
    福建
  • 本文字数:1421 字

    阅读完需:约 5 分钟

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


  • k8s 的 yaml 配置


apiVersion: apps/v1kind: Deploymentmetadata:  name: my-appspec:  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[i])); 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 生成器的改进


@Slf4jpublic 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(); }
复制代码


文章转载自:张占岭

原文链接:https://www.cnblogs.com/lori/p/18641362

体验地址:http://www.jnpfsoft.com/?from=infoq

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
springboot~多节点应用里的雪花算法唯一性_Spring Boot_快乐非自愿限量之名_InfoQ写作社区