微服务时代,我们需要生产一个连续的序列号,变得比较麻烦。这里使用了Mysql简单的实现了一个简单的分布式序列号生成组件。后续还可以支持Redis等其他高效中间件。
原理很简单,在mysql数据专门创建一张表,例如:
CREATE TABLE IF NOT EXISTS `sequence`( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键id', `value` bigint(20) NOT NULL COMMENT 'sequence当前值', `name` varchar(32) NOT NULL COMMENT 'sequence对应的名称,通常是表名', `gmt_create` DATETIME NOT NULL COMMENT '创建时间', `gmt_modified` DATETIME NOT NULL COMMENT '修改时间', PRIMARY KEY (`ID`) ,UNIQUE uk_name (`name`) );
每钟业务类型创建一条记录,value表示当时取的区间值,例如当前value值是100。 当我们设置step长为100时,来取一次,就会update到value。然后程序节点就可以把这个100分配出去。
1.API方式使用
public class SequenceTest_Api { private Sequence userSeq; @Before public void setup() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://121.196.218.206:3306/admin?characterEncoding=UTF-8"); dataSource.setUsername("admin"); dataSource.setPassword("admin123"); dataSource.setMaxActive(300); dataSource.setMinIdle(50); dataSource.setInitialSize(2); dataSource.setMaxWait(500); DbSeqRangeConfig seqRangeConfig = new DbSeqRangeConfig(); seqRangeConfig.setDataSource(dataSource); seqRangeConfig.setTableName("sequence"); seqRangeConfig.setRetryTimes(100); seqRangeConfig.setStep(1000); seqRangeConfig.setStepStart(0); DbSeqRangeMgr seqRangeMgr = new DbSeqRangeMgr(); seqRangeMgr.setSeqRangeConfig(seqRangeConfig); seqRangeMgr.init(); userSeq = new DefaultSequence(); userSeq.setName("user"); userSeq.setSeqRangeMgr(seqRangeMgr); } @Test public void test() { long start = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) { System.out.println("++++++++++id:" + userSeq.nextValue()); } System.out.println("interval time:" + (System.currentTimeMillis() - start)); } }
2.Spring使用方式
(1)XML文件配置
<!-- 数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="jdbc:mysql://121.196.218.206:3306/admin?characterEncoding=UTF-8"/> <property name="username" value="admin"/> <property name="password" value="admin123"/> <property name="maxActive" value="300"/> <property name="minIdle" value="50"/> <property name="initialSize" value="2"/> <property name="maxWait" value="500"/> </bean> <!-- 序列号步长管理器配置 --> <bean id="seqRangeConfig" class="com.xuan.xseq.range.impl.db.DbSeqRangeConfig"> <!-- 数据源[必选] --> <property name="dataSource" ref="dataSource"/> <!-- 表名[可选] 默认:sequence--> <property name="tableName" value="sequence"/> <!-- 更新失败重试次数[可选] 默认:100--> <property name="retryTimes" value="100"/> <!-- 每次取数步长[可选] 默认:1000--> <property name="step" value="1000"/> <!-- 起始数,注意真实开始可用数是stepStart+1,例如stepStart=0表示从1开始[可选] 默认:0--> <property name="stepStart" value="0"/> </bean> <!-- 序列号步长管理器 --> <bean id="seqRangeMgr" class="com.xuan.xseq.range.impl.db.DbSeqRangeMgr" init-method="init"> <property name="seqRangeConfig" ref="seqRangeConfig"/> </bean> <!-- 具体使用demo --> <bean id="userSeq" class="com.xuan.xseq.seq.impl.DefaultSequence"> <property name="seqRangeMgr" ref="seqRangeMgr"/> <property name="name" value="user"/> </bean>
(2)API代码使用
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:sequence-test.xml" }) public class SequenceTest_Spring { @Autowired private Sequence userSeq; @Test public void test() { for (int i = 0; i < 100; i++) { System.out.println("++++++++++id:" + userSeq.nextValue()); } } }
maven依赖 <dependency> <groupId>com.xuanner</groupId> <artifactId>xsequence-core</artifactId> <version>1.6</version> </dependency> SpringBoot配置注入 import co
1、历史版本 v1.0 支持DB方式生成序列号 文档:https://my.oschina.net/u/1271235/blog/1808103 v1.1 支持Redis方式生成序列号 文档:https://my.oschina.net/u/1271235/blog/1809437 2、新版本特性说明 v1.2 支持雪花算法生成序列号 3、使用教程 (1)API使用方式 public
主要内容:1.UUID,2.数据库自增Id,3.基于数据库集群模式,4.基于数据库的号段模式,5.Redis,6.Snowflake,7.百度(uid-generator),8.Leaf,9.TinyId生成方式: 1.UUID 2.数据库自增ID 3.数据库多主模式 4.号段模式 5.Redis 6.雪花算法(SnowFlake) 7.滴滴出品(TinyID) 8.百度 (Uidgenerator) 9.美团(Leaf) 1.UUID UUID的生成简单到只有一行代码,输出结果 c2b8c2b
有时我们需要能够生成类似MySQL自增ID这样不断增大,同时又不会重复的id。以支持业务中的高并发场景。比较典型的,电商促销时,短时间内会有大量的订单涌入到系统,比如每秒10w+。明星出轨时,会有大量热情的粉丝发微博以表心意,同样会在短时间内产生大量的消息。 在插入数据库之前,我们需要给这些消息、订单先打上一个ID,然后再插入到我们的数据库。对这个id的要求是希望其中能带有一些时间信息,这样即使我
雪花算法 类型:SNOWFLAKE 可配置属性: 属性名称 数据类型 说明 默认值 worker-id (?) long 工作机器唯一标识 0 max-vibration-offset (?) int 最大抖动上限值,范围[0, 4096)。注:若使用此算法生成值作分片值,建议配置此属性。此算法在不同毫秒内所生成的 key 取模 2^n (2^n一般为分库或分表数) 之后结果总为 0 或 1。为防
如何自定义生成固定长度的字符串ID,8-12个字符 格式:业务标记_xxxxxxxxxx 如:user_Nuxq23s24dxa1ScSx 要求:1ms生成100W个 或有什么现成的库可以使用,麻烦老大们贴下代码
1、创建 list 的方式 之前经过我们的学习,都知道如何创建一个 list ,可是有些情况,用赋值的形式创建一个 list 太麻烦了,特别是有规律的 list ,一个一个的写,一个一个赋值,太麻烦了。比如要生成一个有 30 个元素的 list ,里面的元素为 1 - 30 。我们可以这样写: # -*- coding: UTF-8 -*- list1=list ( range (1,31) )
问题内容: 我有一张桌子:student_marks 预期产量: 使用mysql用户定义的变量,可以使用查询来完成: 在不使用用户定义变量的情况下,有什么方法可以在msyql中实现? 问题答案: 基于您不想使用用户定义变量的原因,因为要避免有两个查询,一个用于初始化,一个用于使用它,您可以使用以下方法: