spring boot:redis+lua实现顺序自增的唯一id发号器(spring boot 2.3.1)
一,为什么需要生成唯一id(发号器)?
1,在分布式和微服务系统中,
生成唯一id相对困难,
常用的方式:
uuid不具备可读性,作为主键存储时性能也不够好,
mysql的主键,在分库时使用不够方便,高并发时性能没有保障
所以在这里我们演示使用redis+lua生成唯一id
2,使用redis性能虽好,但仍然要考虑单点故障问题,
这里建议在生产环境中使用主从+哨兵或集群方式
说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,本演示项目的相关信息
1,项目地址:
https://github.com/liuhongdi/redisuniqueid
2,项目原理:
利用redis中lua脚本的原子性,避免产生重复id的问题
3,项目结构:

三,lua代码说明
id.lua
local id_key = 'id_key_'..KEYS[1]
local current = redis.call('get',id_key)
if current == false then
redis.call('set',id_key,1)
return '1'
end
--redis.log(redis.LOG_NOTICE,' current:'..current..':')
local result = tonumber(current)+1
--redis.log(redis.LOG_NOTICE,' result:'..result..':')
redis.call('set',id_key,result)
return tostring(result)
说明:
id_key变量作为存储的kv对的key
如果变量不存在,设置id_key值为1并返回
如果变量存在,值加1后返回
注意转为字符串形式后返回,方便java代码接收
四,java代码说明
RedisLuaUtil.java
@Service
public class RedisLuaUtil {
@Resource
private StringRedisTemplate stringRedisTemplate; private static final Logger logger = LogManager.getLogger("bussniesslog");
/*
run a lua script
luaFileName: lua file name,no path
keyList: list for redis key
return:lua return value,type is string
*/
public String runLuaScript(String luaFileName,List<String> keyList) {
DefaultRedisScript<String> redisScript = new DefaultRedisScript<>();
redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/"+luaFileName)));
redisScript.setResultType(String.class); String argsone = "none";
//String result = stringRedisTemplate.execute(redisScript, keyList,argsone);
String result = "";
try {
result = stringRedisTemplate.execute(redisScript, keyList,argsone);
} catch (Exception e) {
logger.error("发生异常",e);
throw new ServiceException(ResponseCode.LUA_ERROR.getMsg());
} return result;
}
}
说明:功能用来运行resource目录下的lua脚本
IdServiceImpl.java
@Service
public class IdServiceImpl implements IdService { @Resource
private RedisLuaUtil redisLuaUtil; /*
* 调用lua得到唯一id
* 返回:唯一的自增id,字符串形式
* */
@Override
public String getId(String idType) {
List<String> keyList = new ArrayList();
keyList.add(idType);
String res = redisLuaUtil.runLuaScript("id.lua",keyList);
System.out.println("-----res:"+res);
return res;
}
}
说明:得到自增id的service
五,测试发号器效果
1,从redis删除已创建的key
127.0.0.1:6379> del id_key_formtoken
(integer) 1
127.0.0.1:6379> get id_key_formtoken
(nil)
2,用ab发起测试
#-c:20个并发
#-n:共20个请求
[liuhongdi@localhost ~]$ ab -c 20 -n 20 http://127.0.0.1:8080/order/getid
3,查看输出效果
-----res:1
-----res:2
-----res:3
-----res:4
-----res:5
-----res:6
-----res:8
-----res:7
-----res:9
-----res:10
-----res:11
-----res:12
-----res:13
-----res:14
-----res:15
-----res:16
-----res:17
-----res:20
-----res:19
-----res:18
并发情况下,仍然正确的按自增的顺序生成id
六,查看spring boot的版本
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
spring boot:redis+lua实现顺序自增的唯一id发号器(spring boot 2.3.1)的更多相关文章
- spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)
一,秒杀需要具备的功能: 秒杀通常是电商中用到的吸引流量的促销活动方式 搭建秒杀系统,需要具备以下几点: 1,限制每个用户购买的商品数量,(秒杀价格为吸引流量一般会订的很低,不能让一个用户全部抢购到手 ...
- spring boot redis缓存JedisPool使用
spring boot redis缓存JedisPool使用 添加依赖pom.xml中添加如下依赖 <!-- Spring Boot Redis --> <dependency> ...
- spring mvc Spring Data Redis RedisTemplate [转]
http://maven.springframework.org/release/org/springframework/data/spring-data-redis/(spring-data包下载) ...
- Spring Data Redis简介以及项目Demo,RedisTemplate和 Serializer详解
一.概念简介: Redis: Redis是一款开源的Key-Value数据库,运行在内存中,由ANSI C编写,详细的信息在Redis官网上面有,因为我自己通过google等各种渠道去学习Redis, ...
- SpringMVC + Spring + Mybatis+ Redis +shiro以及MyBatis学习
SpringMVC + Spring + Mybatis+ Redis +shiro http://www.sojson.com/shiro MyBatis简介与配置MyBatis+Spring+My ...
- 【原】Spring整合Redis(第三篇)—盘点SDR搭建中易出现的错误
易错点01:Spring版本过低导致的错误[环境参数]Redis版本:redis-2.4.5-win32-win64Spring原来的版本:4.1.7.RELEASESpring修改后的版本:4.2. ...
- spring 集成 redis -- pub/sub
redis除了常用的当做缓存外,还可以当做简单的消息中间件,实现消息发布订阅 spring集成redis,可以使用spring-data-redis 首先引入相关maven依赖(此处我spring相关 ...
- Spring Boot Redis 分布式缓存的使用
一.pom 依赖 <!-- 分布式缓存 --> <dependency> <groupId>org.springframework.boot</groupId ...
- Spring Boot Redis 实现分布式锁,真香!!
之前看很多人手写分布式锁,其实 Spring Boot 现在已经做的足够好了,开箱即用,支持主流的 Redis.Zookeeper 中间件,另外还支持 JDBC. 本篇栈长以 Redis 为例(这也是 ...
随机推荐
- java中双亲委派机制(+总结)
类加载器 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段"加载"过程中,需要通过一个类的全限定名来获 ...
- 学习使用PSTools工具中的psping
目录 初识PsTools psping 1.使用ICMP ping 2.使用TCP ping 3.延迟测试 4.带宽测试 5.同功能的tcping工具 总结 初识PsTools 在工作中我们都 ...
- hystrix元素详解
转自https://www.cnblogs.com/wanggangblog/p/8550218.html package com.example.demo.service; import org.s ...
- maven问题汇总
Failed to read artifact descriptor for xxx:jar 在MyEclipse中执行Maven的install命令时,报“Failed to read artifa ...
- HTML+CSS使用swiper快速生成最简单、最快捷、最易看懂的轮播图
1. 在网页顶部输入swiper.com.con,进入swiper官网 2. 点击" API文档",获取轮播图代码的地方 3. 点击左侧"swiper初始化&q ...
- 《Netty权威指南》笔记
第1章 Java的I/O演进之路 1.1 Linux网络I/O模型 fd:file descriptor,文件描述符.linux内核将所有外部设备都看作一个文件来操作,对文件的读写会调用内核提供的命令 ...
- 关于Linux软连接和硬链接
(注:此文章仅为个人学习,研究,原创作者:iTech,原创文章网址:https://www.cnblogs.com/itech/archive/2009/04/10/1433052.html) 1.L ...
- IIS目录浏览模式打开文件还是无法下载
写在前面的话 IIS已经设置目录浏览启用,且可以正常访问到文件,说明这些设置没问题,但是点击文件进行下载时,却提示无法下载,文件不存在等等,有的又可以,一顿操作后发现,原来是文件类型没有包含在MIME ...
- (转载)什么是B+树?
本文转载自网络. 如有侵权,请联系处理!
- 使用Commons FileUpload 1.3.3和Servlet 3.0上传文件
简介 Commons FileUpload可以轻松地为web应用程序添加强大,高性能的文件上传功能.Servlet3.0之前的web应用程序需要使用Commons FileUpload组件上传文件,但 ...