当前使用版本(必填,否则不予处理)

3.5.3.1

该问题是如何引起的?(确定最新版也有问题再提!!!)

在集群下 插入日志表偶然告警了一次 我一共就四台机器 经过查看一台成功插入 一台主键冲突报错

重现步骤(如果有就写完整)

无 不知道如何复现

报错信息

MyBatis-Plus ASSIGN_ID在集群下出现了重复

Comment From: oday-xiexin

我是老版本升级上来的 老版本的ID_WORKER_STR好像没出现这个问题过倒是新版的ASSIGN_ID出现过

Comment From: miemieYaho

新老版本没有区别,你是docker容器内?java11及以上使用如下命令查看应用的数据标识 ID是否有重复

tee ~/H.java <<EOF
import java.net.InetAddress;
import java.net.NetworkInterface;
public class HelloWorld{
    public static void main(String args[]) throws Exception{
        InetAddress inetAddress = InetAddress.getLocalHost();
        NetworkInterface network = NetworkInterface.getByInetAddress(inetAddress);
        long id = 0L;
        if (null == network) {
            id = 1L;
        } else {
            byte[] mac = network.getHardwareAddress();
            if (null != mac) {
                id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6;
                id = id % (32);
            }
        }
        System.out.println(id);
    }
}
EOF
java ~/H.java

Comment From: oday-xiexin

新老版本没有区别,你是docker容器内?java11及以上使用如下命令查看应用的数据标识 ID是否有重复

shell tee ~/H.java <<EOF import java.net.InetAddress; import java.net.NetworkInterface; public class HelloWorld{ public static void main(String args[]) throws Exception{ InetAddress inetAddress = InetAddress.getLocalHost(); NetworkInterface network = NetworkInterface.getByInetAddress(inetAddress); long id = 0L; if (null == network) { id = 1L; } else { byte[] mac = network.getHardwareAddress(); if (null != mac) { id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6; id = id % (32); } } System.out.println(id); } } EOF java ~/H.java

不是docker环境 就是正常的liunx脚本部署

Comment From: oday-xiexin

新老版本没有区别,你是docker容器内?java11及以上使用如下命令查看应用的数据标识 ID是否有重复

shell tee ~/H.java <<EOF import java.net.InetAddress; import java.net.NetworkInterface; public class HelloWorld{ public static void main(String args[]) throws Exception{ InetAddress inetAddress = InetAddress.getLocalHost(); NetworkInterface network = NetworkInterface.getByInetAddress(inetAddress); long id = 0L; if (null == network) { id = 1L; } else { byte[] mac = network.getHardwareAddress(); if (null != mac) { id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6; id = id % (32); } } System.out.println(id); } } EOF java ~/H.java

大佬 可以手动设置数据id吗 类似这样么mybatis-plus.global-config.worker-id: 5?

Comment From: miemieYaho

没有,DefaultIdentifierGenerator默认是读取ip来算出dataCenterId,如果这个值重复那就会生成的雪花id会有重复 你也可以自己注入DefaultIdentifierGenerator到spring里自己保证workerIddataCenterId不重复

Comment From: oday-xiexin

没有,DefaultIdentifierGenerator默认是读取ip来算出dataCenterId,如果这个值重复那就会生成的雪花id会有重复 你也可以自己注入DefaultIdentifierGenerator到spring里自己保证workerIddataCenterId不重复

希望启动debug模式可以打点日志出来 供排查

Comment From: miemieYaho

没有,DefaultIdentifierGenerator默认是读取ip来算出dataCenterId,如果这个值重复那就会生成的雪花id会有重复 你也可以自己注入DefaultIdentifierGenerator到spring里自己保证workerIddataCenterId不重复

希望启动debug模式可以打点日志出来 供排查

tee ~/H.java <<EOF import java.net.InetAddress; import java.net.NetworkInterface; public class HelloWorld{ public static void main(String args[]) throws Exception{ InetAddress inetAddress = InetAddress.getLocalHost(); NetworkInterface network = NetworkInterface.getByInetAddress(inetAddress); long id = 0L; if (null == network) { id = 1L; } else { byte[] mac = network.getHardwareAddress(); if (null != mac) { id = ((0x000000FF & (long) mac[mac.length - 2]) | (0x0000FF00 & (((long) mac[mac.length - 1]) << 8))) >> 6; id = id % (32); } } System.out.println(id); } } EOF java ~/H.java 自己看啊

Comment From: HenryGentry

我也发现了,用k8s部署的服务,同一台机器多个实例的话,在高并发的场景就会出现雪花ID重复的问题。 通过代码验证,发现同一机器的实例获取到的dataCenterId都是一样的

Comment From: qmdx

如下注入自定义唯一参数

@Bean
public DefaultIdentifierGenerator identifierGenerator()  {
   return new DefaultIdentifierGenerator(唯一参数 `workerId` , 唯一参数 `dataCenterId`);
}