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);
      }
    
  • 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("1"));
      		log.debug("podNameCode:{}", podNameCode);
      		snowFlakeGenerator = new SnowFlakeGenerator(podNameCode);
    
      	}
      	return snowFlakeGenerator.hexNextId();
      }