雪花算法workerid和datacenterid生成工具

前置要点:
在 Mybatis Plus 内置的雪花算法中,workerIddatacenterId 的最大长度为 5 位,即取值范围为:0~31。

核心代码:

// 计算 workerId 和 datacenterId
int loopCount = thirdSectionNum % MAX_IP_THIRD_SECTION_COUNT;
int workerId = (fourthSectionNum / 32) + (loopCount * 8);
int datacenterId = fourthSectionNum % 32;

代码说明:

  1. 本工具类总共可获取1024对 workerIddatacenterId
  2. thirdSectionNum 变量为IPv4地址中第三段的IP地址部分。
  3. MAX_IP_THIRD_SECTION_COUNT 为常量值:4,表示最大可使用4个连续的IPv4第三段地址。(例:10.10.103.x, 10.10.104.xx, 10.10.105.xxx, 10.10.106.x)
  4. fourthSectionNum 变量表示IPv4地址中第四段的值,本段内容没有限制,可以取 0~255 中任意值。
  5. 代码总体思路:根据IP地址的值不同,将录入的IP平均分配到1024对 workerIddatacenterId 的组合中。
  6. 第一行代码含义:取轮次。因为 workerId 最多可取32个值,IPv4第三段地址最大可使用4个连续的值,所以把32等分成4份,每份8个值, 余数的范围为:0~3。
  7. 第二行代码含义:计算 workerId。因为第四段IP地址最大值为255,而 workerId 的最大值为31,所以当前半部分的最大商为7时,后半部分的最大积为24时,仍可满足 workerId 的最大值要求。
  8. 第三行代码含义:计算 datacenterId。第四段IP地址对32取余,结果范围为0~31,符合 datacenterId 的最大值要求。

局限性:

  1. 需要运维同学配合设置pod的IP地址范围,且必须满足地址的前两段不变,IP地址第三段存在多个可用的地址时,取值为连续的值(最多四个)。
  2. 本方法最多可获取到1024种不同结果,即最多启动1024个pod。

完整代码:

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 获取雪花算法 workerId 和 datacenterId 工具类
 *
 * 局限性:1. 服务必须可获取到pod的 IP 地址,且 IP 地址的前两段不变,第三段若存在多个可用地址,其必须为连续的值(最多四个)
 *       2. 最多可获取到 1024 种不同结果
 */
public class IPBasedUniqueWorkerIdAndDatacenterIdGenerator {
    /**
     * IP地址第三段编号最大个数(32*32/256=4)
     */
    private static final int MAX_IP_THIRD_SECTION_COUNT = 4;
    /**
     * IPv4 正则表达式验证规则
     */
    private static final Pattern IPV4_PATTERN = Pattern.compile(
            "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
    /**
     * 雪花算法 workerId
     */
    public static final String KEY_WORKER_ID = "workerId";
    /**
     * 雪花算法 datacenterId
     */
    public static final String KEY_DATACENTER_ID = "datacenterId";

    /**
     * 获取雪花算法 workerId 和 datacenterId(IP地址第三、四段都有变化)
     *
     * @param ip IP地址
     *
     * @return {@link Map<String, Integer>} workerId 和 datacenterId
     * @author Supreme_Sir
     * @date 2024/6/11 17:40
     */
    public static Map<String, Integer> getWorkerIdAndDatacenterId(String ip) {
        if (!isValidIPv4(ip)){
            throw new RuntimeException("ip is not valid");
        }

        // 切分 IP 地址,获取第三段和第四段内容
        String[] split = ip.split("\\.");
        int thirdSectionNum = Integer.parseInt(split[2]);
        int fourthSectionNum =  Integer.parseInt(split[3]);

        // 计算 workerId 和 datacenterId
        int loopCount = thirdSectionNum % MAX_IP_THIRD_SECTION_COUNT;
        int workerId = (fourthSectionNum / 32) + (loopCount * 8);
        int datacenterId = fourthSectionNum % 32;

        // 返回结果
        Map<String, Integer> result = new HashMap<>();
        result.put(KEY_WORKER_ID, workerId);
        result.put(KEY_DATACENTER_ID, datacenterId);

        return result;
    }

    /**
     * 验证给定的字符串是否为有效的IPv4地址。
     *
     * @param ip 要验证的IP地址字符串
     * @return 如果是有效的IPv4地址则返回true,否则返回false
     */
    public static boolean isValidIPv4(String ip) {
        Matcher matcher = IPV4_PATTERN.matcher(ip);
        return matcher.matches();
    }
}

---------------------------------------每个人都很努力,并不是只有你一个人满腹委屈。-------------------------------------

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值