分布式环境下数字序列号生成服务
背景
日常应用中,常常会碰到获取唯一序列号的需求。比如,唯一的订单编号,唯一的流水编号等等。
很多语言已经有了获取GUID或UUID的实现,直接使用工具就可以获取。但是GUID,UUID里面是数字和字母的字符串组合,虽然能保证唯一,但是长度很长,而且不好记忆。在很多场景下,作为唯一编号向外暴露对人类来说并不友好。
使用有规律的字母+数字适合向外暴露,那么如何保证生成对数字不重复,而且是在分布式环境下?
解决方案
使用数据库自增长特性
-
使用方法
利用数据库特性,设置id为自增型,数据写入后自动填入。 -
优点
实现简单,结果可靠 -
缺点
使用起来不灵活,为了保证安全,唯一序列号需要在数据插入后才能得到。很多情况下,我们希望这个序列号在数据写入数据库前就能够使用
使用分布式缓存
-
使用方法
在redis内对特定key使用incr
命令,原子获取唯一序列号 -
优点
实现简单,使用灵活 -
缺点
依赖缓存,如果缓存数据丢失可能会有重复id
利用数据库乐观锁+应用分段
-
使用方法
在数据库中维护一个key + 开始数字 + 步长数这样一个数据结构,应用通过调用数据库乐观锁方式获取并占用一段数字,应用内通过维护这一段数字实现唯一序号
-
优点
使用灵活,可靠性高 -
缺点
不能保证序列号顺序输出 -
实现
定义Sequence类
public class Sequence {