原文地址:https://ntopic.cn/p/2023062101/
- Gitee源代碼倉庫:https://gitee.com/obullxl/sequence-jdbc
- GitHub源代碼倉庫:https://github.com/obullxl/sequence-jdbc
分布式id序列說明
業務資料的存盤,少不了資料記錄的id序列,
id序列(或稱序列)的生成方式有很多種,比如當前時間戳、資料庫的序列值(Oracle的序列,MySQL的自增ID等)、UUID等方式,
這些生成方式都有一定的局限性,如時間戳在業務量較大時容易重復、Oracle序列和MySQL的自增ID限定了資料庫型別(且MySQL的自增ID只能保證單庫唯一,在分庫分表的場景下也不適用)、UUID容易重復且無法保證遞增等,
同時,一般業務資料的id序列通常會帶上一些業務資訊,比如增加業務標識前綴、增加年月日等資訊,業務id序列的處理變得多樣,則進一步要求業務id序列的生成通用且高效,
通用分布式id序列組件
為了屏蔽業務獲取id序列因資料庫型別、分庫分表等帶來的研發和維護成本,我們把分布式id序列的獲取抽取為一個通用組件,對業務統一介面和規范,
通用分布式id序列實作方式有很多,本文主要介紹一種基于資料表的實作方式,通過一張表記錄所有的業務序列名和值,業務根據序列名獲取下一個序列值(和Oracle序列型別,但是無需為每個序列創建序列,因此更簡單):

本方案的設計主要考量點:
通用性:僅依賴一張序列資料表,JDBC支持的資料庫均可使用,包括SQLite、MySQL、Oracle、OceanBase等,高性能:本地快取一個序列區間,快取使用完之前無DB互動;快取的區間可設定,區間越大,DB訪問越少,性能越高,分布式:受益于集中式的序列資料表,保證了序列全域唯一,
分布式id序列組件設計
組件介面設計
組件介面只有1個,就是獲取序列:
/**
* Author: [email protected]
* Copyright (c) 2020-2023 All Rights Reserved.
*/
package cn.ntopic.sequence;
/**
* 分布式序列服務
*
* @author obullxl 2023年06月21日: 新增
*/
public interface NTSequence {
/**
* 默認序列名稱
*/
String DEFAULT_SEQUENCE_NAME = "DEFAULT";
/**
* 序列名稱最大長度
*/
int MAX_SEQUENCE_NAME_LENGTH = 64;
/**
* 獲取下一個序列值
*
* @return 獲取默認序列的新的唯一的序列值 {@link #DEFAULT_SEQUENCE_NAME}
* @throws IllegalArgumentException 引數非法
*/
default long next() {
return this.next(DEFAULT_SEQUENCE_NAME);
}
/**
* 獲取下一個序列值
*
* @param sequenceName 序列名稱,非空,1~64字符,業務可隨意指定(如:用戶模塊為`USER`,訂單模塊為`ORDER`等)
* @return 新的唯一的序列值
* @throws IllegalArgumentException 引數非法
*/
long next(String sequenceName);
}
組件可控引數
在追求通用性和性能的同時,以引數的方式供個性化調控:
id序列資料表名:默認值為nt_sequence;但對于不同的業務,對資料表名有要求規范(如:表名前置等),因此序列資料表名可設定id序列起始值:默認值為1,即序列值從1開始遞增;但對于存量業務,id值起始值需要比存量最大值要大,否則容易重復id序列最大值:默認值為99999999,序列值遞增到最大值,則回圈從起始值開始序列更新重試次數:默認值為10,當快取序列用盡,需要查詢和更新序列資料表,比較存在網路通訊和DB操作,不可避免存在例外失敗,失敗后會進行重試序列快取大小:默認值為1000,值越大,訪問DB越少,性能越高,序列的連續性越差(如:快取大小為1000,當序列用到400時,服務器重啟了,那么401~1000直接的序列就丟失了);相反,值越小,訪問DB越多,性能越低,序列的連續性越好,
/**
* 屬性-資料源
*/
private final DataSource ntDataSource;
/**
* 屬性-重試次數
*/
private int retryTimes = 10;
/**
* 屬性-資料表名
*/
private String tableName = "nt_sequence";
/**
* 屬性-序列獲取步長(即序列快取大小)
*/
private long step = 1000L;
/**
* 屬性-序列最小值
*/
private long minValue = https://www.cnblogs.com/obullxl/archive/2023/06/30/1L;
/**
* 屬性-序列最大值
*/
private long maxValue = 99999999L;
序列組件使用
- Gitee源代碼倉庫:https://gitee.com/obullxl/sequence-jdbc
- GitHub源代碼倉庫:https://github.com/obullxl/sequence-jdbc
目前JAR包已經發布,通過Gitee進行倉庫托管,也可直接使用,2步即可:
- 第一步:在專案源代碼的根
pom.xml中,設定倉庫地址:
<repositories>
<repository>
<id>Gitee-obullxl</id>
<url>https://gitee.com/obullxl/maven-repository/master/repository</url>
</repository>
</repositories>
- 第二步:參考JAR包,僅需要依賴本JAR包,無其他JAR包依賴:
<dependency>
<groupId>cn.ntopic</groupId>
<artifactId>sequence-jdbc</artifactId>
<version>1.0.1</version>
</dependency>
在業務代碼中呼叫序列組件樣例:
// 1. 構建資料源
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:sqlite:/Users/obullxl/CodeSpace/sequence-jdbc/SequenceJDBC.sqlite");
dataSource.setDriverClassName("org.sqlite.JDBC");
dataSource.setPoolPreparedStatements(false);
dataSource.setMaxPoolPreparedStatementPerConnectionSize(-1);
dataSource.setTestOnBorrow(true);
dataSource.setTestOnReturn(false);
dataSource.setTestWhileIdle(true);
dataSource.setValidationQuery("SELECT '1' FROM sqlite_master LIMIT 1");
// 2. 初始化序列組件
NTSequenceImpl ntSequence = new NTSequenceImpl(dataSource);
ntSequence.setTableName(tableName);
ntSequence.createTable();
ntSequence.init();
// 3. 獲取序列值
@Autowire
@Qualifier("ntSequence")
private NTSequence ntSequence;
// 獲取`DEFAULT`默認序列ID
long newId1 = ntSequence.next();
long newId2 = ntSequence.next();
long newId3 = ntSequence.next();
// 獲取`USER`用戶ID:
long newUserId1 = ntSequence.next("USER");
long newUserId2 = ntSequence.next("USER");
long newUserId3 = ntSequence.next("USER");
// 獲取`ORDER`訂單ID:
long newOrderId1 = ntSequence.next("ORDER");
long newOrderId2 = ntSequence.next("ORDER");
long newOrderId3 = ntSequence.next("ORDER");
完整的使用方法,可引數源代碼倉庫說明檔案(README.md):
- Gitee源代碼倉庫:https://gitee.com/obullxl/sequence-jdbc
- GitHub源代碼倉庫:https://github.com/obullxl/sequence-jdbc
分布式id序列測驗用例
因為代碼較大,請直接查看源代碼:
- Gitee測驗源代碼:https://gitee.com/obullxl/sequence-jdbc/blob/master/src/test/java/cn/ntopic/sequence/NTSequenceTest.java
- GitHub測驗源代碼:https://github.com/obullxl/sequence-jdbc/blob/master/src/test/java/cn/ntopic/sequence/NTSequenceTest.java
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556401.html
標籤:其他
上一篇:Java-語法基礎
下一篇:返回列表
