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[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生成器的改进
@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();
	}
posted @   张占岭  阅读(471)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2020-12-30 AES密文与明文长度的关系
2019-12-30 k8s~部署EFK框架
2015-12-30 大叔也说Xamarin~Android篇~监听返回键,单击返回某个webView,双击退出
2015-12-30 Lind.DDD.ExpressionExtensions动态构建表达式树,实现对数据集的权限控制
2014-12-30 知方可补不足~Sqlserver中的几把锁和.net中的事务级别
2012-12-30 vs2012~ 开发人员的福音
2011-12-30 基础才是重中之重~类是怎么执行的
点击右上角即可分享
微信分享提示