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

 更新时间:2024年12月31日 09:12:42   作者:张占岭  
雪花算法在单节点下唯一,但在多副本Kubernetes环境中可能重复,通过修改Pod名称生成workId,解决了这个问题,同时避免了第三方组件和网络请求,本文给大家介绍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();
	}

到此这篇关于springboot~多节点应用里的雪花算法唯一性的文章就介绍到这了,更多相关springboot雪花算法唯一性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot实现嵌入式 Servlet容器

    SpringBoot实现嵌入式 Servlet容器

    传统的Spring MVC工程部署时需要将WAR文件放置在servlet容器的文档目录内,而Spring Boot工程使用嵌入式servlet容器省去了这一步骤,本文就来设置一下相关配置,感兴趣的可以了解一下
    2023-12-12
  • mybatis plus 的动态表名的配置详解

    mybatis plus 的动态表名的配置详解

    这篇文章主要介绍了mybatis plus 的动态表名的配置详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 浅谈java日志格式化

    浅谈java日志格式化

    不管我们使用何种语言开发,一旦程序发生异常,日志是一个很重要的数据。但是并不是意味着打印的日志越多越好,我们需要的是有用的日志。下面小编来和大家一起学习以下知识
    2019-05-05
  • MyBatis-Plus中实现自定义复杂排序逻辑的详细步骤

    MyBatis-Plus中实现自定义复杂排序逻辑的详细步骤

    这篇文章主要介绍了MyBatis-Plus中实现自定义复杂排序逻辑,通过使用MyBatis-Plus的QueryWrapper和SQL原始片段,我们可以灵活地实现复杂的数据排序逻辑,这种方法尤其适用于需要对数据进行特定规则排序的场景,需要的朋友可以参考下
    2024-07-07
  • Java实现List与数组互相转换的两种方法

    Java实现List与数组互相转换的两种方法

    在 Java 编程中,List 和数组是两种常用的数据结构,List 提供了动态大小、丰富的操作方法,而数组则以其高效的随机访问和内存效率著称,在实际开发中,我们经常需要在这两者之间进行转换,本文将深入探讨 List 与数组之间的相互转换,需要的朋友可以参考下
    2025-12-12
  • Java Swing JFrame窗口的实现

    Java Swing JFrame窗口的实现

    这篇文章主要介绍了Java Swing JFrame窗口的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • SpringBoot整合SpringSecurity认证与授权

    SpringBoot整合SpringSecurity认证与授权

    在项目开发中,权限认证是很重要的,尤其是一些管理类的系统,对于权限要求更为严格,本文主要介绍了SpringBoot整合SpringSecurity认证与授权,感兴趣的可以了解一下
    2023-11-11
  • JAVA使用ElasticSearch查询in和not in的实现方式

    JAVA使用ElasticSearch查询in和not in的实现方式

    今天小编就为大家分享一篇关于JAVA使用Elasticsearch查询in和not in的实现方式,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • springboot中设置定时任务的三种方法小结

    springboot中设置定时任务的三种方法小结

    在我们开发项目过程中,经常需要定时任务来帮助我们来做一些内容,本文介绍了springboot中设置定时任务的三种方法,主要包括@Scheduled注解,Quartz框架和xxl-job框架的实现,感兴趣的可以了解一下
    2023-12-12
  • SpringBoot中YAML配置文件实例详解

    SpringBoot中YAML配置文件实例详解

    前面一直在使用properties配置文件,spring boot也支持yaml配置文件,下面这篇文章主要给大家介绍了关于SpringBoot中YAML配置文件的相关资料,需要的朋友可以参考下
    2023-04-04

最新评论