【本人原创】,欢迎交流和分享技术,转载请附上如下内容:
如果你觉得这篇文章对你有帮助,请记得帮我点赞, 谢谢!作者:kevin【转自】http://www.cnblogs.com/itshare/
很多时候,我们常常会需要给系统构造不同的流水号,并且不希望它出现重复数据,有很多方法能够实现这个需求。
但是,我们希望方法是能够动态支持不同业务场景、跨语言和操作平台,支持服务水平扩展。
下面,我将带领你一步步理解和实现它。
一、需求描述:
1. 每天的不同业务的流水号 (每天从1开始)
2. 永久的不同业务的唯一标识 (历史从1开始)
3. 不依赖数据库的Sequence和支持跨平台。
二、技术实现
1. 采用redis的内部函数hincrBy(string main_key, string item_key, long addValue)方法,对不同场景的ID进行自动+1或+n进行构造和返回。
2. 采用java的restful进行数据请求和返回结果。
三、代码分析
1. 后台代码
因为Redis本省是线程安全,所以我们不用自己加些写入数据的锁,只需要直接调用incre方法,存入增量1或n,redis就能自动返回我们需要的下一个sequence的数值。
这个类似数据库oracle的sequence.nextval
2.前台代码
主要是restful接受参数:main_key和item_key,你也可以增加一个自定义参数addValue,
这样也就可以做批量构造流水号或sequence (见 数值区间 =【maxCurReturn - addValue + 1, maxCurReturn】).
四、压力测试
因为这里只是一台Redis测试机器,所以多线程去请求获得的单步构造流水号的TPS是675。
但是这个已经足够我们使用它做流水号的构造了。如果超过这个范围,就要考虑部署服务和Redis集群,并且代码采用批量获取(addValue不要传入1,要传入批量的构造个数n)。
测试1:手动执行一次soapUI的单个请求,后台查看Id变为1
测试2:执行三次压力测试(每次1000个线程并发请求),平均tps为678,后台查看ID变为69765