Redisson是一个在Redis的基础上实现的Java驻内存数据网络(In-Memory Data Grid),它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。
分布式锁(Lock)和同步锁(Synchronizer),其中就有:
可重入锁(Reentrant Lock)、公平锁(Fair Lock)、联锁(MultiLock)、红锁(RedLock)、读写锁(ReadWriteLock)、信号量(Semaphore)、可过期性信号量(PermitExpirableSemaphore)、闭锁(CountDownLatch)。
以上详细信息均可在官网查询,这里就不多赘述(水)了,下面直接进入正题。
1、Redisson入门:
首先需要引用依赖:
1 | <!-- https://mvnrepository.com/artifact/org.redisson/redisson --> |
然后配置客户端:
1 | @Configuration |
这里需要注意的点是,记得给客户端加上@Bean注释,否则不会生效;其次,如果单台Redis服务器,就使用useSingleServer()
方法,也可以用这个方法配置多台,只不过要多注册几个Bean,此外还可以根据需求使用useClusterServers()
和useSentinelServers()
来配置Redis集群。
创建Redisson的分布式锁,测试是否创建成功:
1 | @Autowired |
注意,上面导的包是Redisson的。
2、实现优化:
如果以上步骤都没问题,那么就可以完成下面的优化了。
先来整理一下思路:
(1)、新增秒杀活动的同时,将秒杀商品信息预先保存到Redis中
(2)、基于Lua脚本,判断秒杀酷讯、一人一单,决定用户是否秒杀成功
(3)、如果抢购成功,将商品id和用户id封装存入到阻塞队列
(4)、开启线程任务,不断从阻塞队列中获取信息,实现异步下单功能
下面就是实现的代码:
1 | @Autowired |
使用JVM的阻塞队列的弊端:内存限制问题,如果jvm内存不够,就不能继续存储了,而且当存储的订单量大于设定的容量上限,也不能继续存储了。数据安全问题,如果服务器宕机了,那jvm里面的数据就会被清空,就会出现数据不一致问题;如果数据从队列中拿出来了,但是这时服务器出现了问题,导致业务没有执行下去,当它恢复时,阻塞队列里面就会没有这条数据,导致数据不一致问题。
想要解决这个问题,也可以使用Redis5.0以后的消息队列实现秒杀,或者更专业的消息队组件,比如RabbitMQ、Kafka、RocketMQ等。
本文链接: https://longzas.github.io/2023/09/02/%E5%9F%BA%E4%BA%8ERedisson%E4%BC%98%E5%8C%96%E7%A7%92%E6%9D%80%E4%B8%9A%E5%8A%A1/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!