欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mybatis-plus內(nèi)置雪花算法主鍵重復(fù)問題解決

 更新時間:2023年09月26日 14:38:42   作者:簡單簡單小白  
本文主要介紹了mybatis-plus內(nèi)置雪花算法主鍵重復(fù)問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

問題描述

目前項目使用的id是mybatis-plus 內(nèi)置的主鍵生成策略 ID_WORKER ,最近測試在做性能壓測,部署架構(gòu)是單服務(wù)集群的部署方式,然后就發(fā)現(xiàn)了id重復(fù)的異常,異常如下

問題分析

首先分析的是id生成是不是就是重復(fù)了,先關(guān)掉其中一臺機器,單機跑,這個時候發(fā)現(xiàn)壓到1000的并發(fā)都沒有出現(xiàn)過id重復(fù),這個說明單機情況下不存在id重復(fù)問題,說明只有集群的情況下才會出現(xiàn)。

再分析一下id生成的幾個要素,雪花算法的核心能影響到id生成的幾個因素:1.服務(wù)器時間2.workId(機器 ID 部分)3.datacenterId(數(shù)據(jù)標(biāo)識 ID 部分)。先檢查了一下服務(wù)器時間,都是一樣的,然后再看一下workId的生成,我們先看一下源碼。

public Sequence() {
    this.datacenterId = getDatacenterId(maxDatacenterId);
    this.workerId = getMaxWorkerId(datacenterId, maxWorkerId);
}
//獲取workerId
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) {
        StringBuilder mpid = new StringBuilder();
        mpid.append(datacenterId);
        //代表正在運行的Java虛擬機的名稱。
        String name = ManagementFactory.getRuntimeMXBean().getName();
        if (StringUtils.isNotEmpty(name)) {
            /*
             * GET jvmPid
             */
            mpid.append(name.split(StringPool.AT)[0]);
        }
        /*
         * MAC + PID 的 hashcode 獲取16個低位
         */
        return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1);
    }

這里生成的workerId主要核心影響就是獲取運行的虛擬機名稱,現(xiàn)在猜測就是有可能是由于兩臺機的虛擬機名稱可能一樣,導(dǎo)致拿到的workerId一樣。這個沒有具體去驗證,猜測是這樣的。那我們嘗試修改一下這個workerId的值。

問題解決

1.先設(shè)置workerId為隨機數(shù),這樣保證每個機器部署的時候拿到的都是隨機數(shù)

# 設(shè)置隨機
mybatis-plus.global-config.worker-id: ${random.int}

這里你啟動項目的時候回發(fā)現(xiàn)一個異常

異常很明顯,這里的worer id 必選小于31,那我們就需要修改一下隨機數(shù)

# 設(shè)置隨機
mybatis-plus.global-config.worker-id: ${random.int(1,31)}

這個時候我們先看一下我們設(shè)置參數(shù)有沒有生效,為了比較明顯看到效果,我們直接設(shè)置worker-id為一個固定值20,再斷點看一下,我們找到 com.baomidou.mybatisplus.core.toolkit.IdWorker 這個核心類,獲取id的核心方法是 com.baomidou.mybatisplus.core.toolkit.IdWorker#getId ,那我們就在這里加一個斷點看下

public class IdWorker {
    /**
     * 主機和進(jìn)程的機器碼
     */
    private static Sequence WORKER = new Sequence();
	//獲取id
    public static long getId() {
        return WORKER.nextId();
    }
    public static String getIdStr() {
        return String.valueOf(WORKER.nextId());
    }
    /**
     * <p>
     * 有參構(gòu)造器
     * </p>
     *
     * @param workerId     工作機器 ID
     * @param datacenterId 序列號
     */
    public static void initSequence(long workerId, long datacenterId) {
        WORKER = new Sequence(workerId, datacenterId);
    }
    /**
     * <p>
     * 使用ThreadLocalRandom獲取UUID獲取更優(yōu)的效果 去掉"-"
     * </p>
     */
    public static String get32UUID() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        return new UUID(random.nextLong(), random.nextLong()).toString().replace(StringPool.DASH, StringPool.EMPTY);
    }
}

斷點后的結(jié)果是:

這個時候看到workerId沒有生效,我們繼續(xù)分析下源碼。

項目啟動的時候,mybatis-plus 會調(diào)用一個 com.baomidou.mybatisplus.core.MybatisConfiguration#init 方法來初始化配置信息,我們看下代碼

public void init(GlobalConfig globalConfig) {
        // 初始化 Sequence
    //這里需要同時設(shè)置workerId和datacenterId
        if (null != globalConfig.getWorkerId()
            && null != globalConfig.getDatacenterId()) {
            IdWorker.initSequence(globalConfig.getWorkerId(), globalConfig.getDatacenterId());
        }
        // 打印 Banner
        if (globalConfig.isBanner()) {
            System.out.println(" _ _   |_  _ _|_. ___ _ |    _ ");
            System.out.println("| | |\\/|_)(_| | |_\\  |_)||_|_\\ ");
            System.out.println("     /               |         ");
            System.out.println("                        "+MybatisPlusVersion.getVersion()+" ");
        }
    }

我們發(fā)現(xiàn)workerId和datacenterId必須同時設(shè)置才會獲取我們設(shè)置的值。

那我們就修改配置一下

# 設(shè)置隨機
mybatis-plus.global-config.worker-id: ${random.int(1,31)}
mybatis-plus.global-config.datacenter-id: ${random.int(1,31)}

ties

設(shè)置隨機

mybatis-plus.global-config.worker-id: ${random.int(1,31)}
mybatis-plus.global-config.datacenter-id: ${random.int(1,31)}

這樣設(shè)置以后發(fā)現(xiàn)終于生效了,然后部署一下,問題終于解決了。這里問題雖然解決了,但是workerId重復(fù)其實沒有實際驗證過,如果有驗證過的同學(xué)歡迎留言。

到此這篇關(guān)于mybatis-plus內(nèi)置雪花算法主鍵重復(fù)問題小結(jié)的文章就介紹到這了,更多相關(guān)mybatis-plus內(nèi)置雪花算法主鍵重復(fù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring IOC裝配Bean過程解析

    Spring IOC裝配Bean過程解析

    這篇文章主要介紹了Spring IOC裝配Bean過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • java開發(fā)分布式服務(wù)框架Dubbo原理機制詳解

    java開發(fā)分布式服務(wù)框架Dubbo原理機制詳解

    這篇文章主要為大家介紹了java開發(fā)分布式服務(wù)框架Dubbo的原理機制詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Java使用Lua實現(xiàn)動態(tài)擴展和腳本自動升級

    Java使用Lua實現(xiàn)動態(tài)擴展和腳本自動升級

    Lua是一種輕量級的腳本語言,常用于游戲開發(fā)和嵌入式系統(tǒng)中,這篇文章主要介紹了Java如何調(diào)用Lua實現(xiàn)動態(tài)擴展和腳本自動升級,感興趣的可以學(xué)習(xí)下
    2023-08-08
  • mybatis關(guān)系映射之一對多和多對一

    mybatis關(guān)系映射之一對多和多對一

    今天小編就為大家分享一篇關(guān)于mybatis關(guān)系映射之一對多和多對一,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • springboot多模塊項目mvn打包遇到存在依賴但卻無法發(fā)現(xiàn)符號問題

    springboot多模塊項目mvn打包遇到存在依賴但卻無法發(fā)現(xiàn)符號問題

    在SpringBoot多模塊項目中,如果遇到依賴存在但無法發(fā)現(xiàn)符號的問題,常見原因可能是pom.xml配置問題,例如,如果某個模塊僅作為依賴而不是啟動工程,不應(yīng)在其pom中配置spring-boot-maven-plugin插件,因為這將影響jar包的生成方式
    2024-09-09
  • Java實現(xiàn)瀏覽器大文件上傳的示例詳解

    Java實現(xiàn)瀏覽器大文件上傳的示例詳解

    文件上傳是許多項目都有的功能,用戶上傳小文件速度一般都很快,但如果是大文件幾個g,幾十個g的時候,上傳了半天,馬上就要完成的時候,網(wǎng)絡(luò)波動一下,文件又要重新上傳,所以本文給大家介紹了Java實現(xiàn)瀏覽器大文件上傳的示例,需要的朋友可以參考下
    2024-07-07
  • Hibernate框架數(shù)據(jù)分頁技術(shù)實例分析

    Hibernate框架數(shù)據(jù)分頁技術(shù)實例分析

    這篇文章主要介紹了Hibernate框架數(shù)據(jù)分頁技術(shù),結(jié)合實例形式分析了Hibernate框架實現(xiàn)數(shù)據(jù)分頁的原理,步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2016-03-03
  • Java 操作Properties配置文件詳解

    Java 操作Properties配置文件詳解

    這篇文章主要介紹了Java 操作Properties配置文件詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot+Redis執(zhí)行l(wèi)ua腳本的5種方式總結(jié)

    SpringBoot+Redis執(zhí)行l(wèi)ua腳本的5種方式總結(jié)

    Lua是一種快速、輕量級的腳本語言,廣泛應(yīng)用于各種領(lǐng)域,包括數(shù)據(jù)庫,Redis作為一個內(nèi)嵌Lua解釋器的NoSQL數(shù)據(jù)庫,允許通過Lua腳本在服務(wù)器端執(zhí)行一些復(fù)雜的操作,本文給大家介紹了使用SpringBoot Redis執(zhí)行l(wèi)ua腳本的五種方式,需要的朋友可以參考下
    2023-11-11
  • 淺談Java double 相乘的結(jié)果偏差小問題

    淺談Java double 相乘的結(jié)果偏差小問題

    下面小編就為大家?guī)硪黄獪\談Java double 相乘的結(jié)果偏差小問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01

最新評論