全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货

Redis分布式锁+信号量进行限流的原理与代码实现

发布时间:2022-10-09 09:29:03
发布人:syq

  一. 前言

  上周小千在《记一次OOM问题的解决连载一 流式查询》中写到,我在“中通全球创研中心”的学生为了避免出现OOM问题,把一个站点一个月流水的数据,用Mybatis流式查询的方式,把数据分批次读进内存再写到硬盘上。这样处理之后确实在一定程度上减少了OOM发生的次数,但仍然会在月初各个站点,集中进行上个月份月结报表时出现OOM的现象。

Redis分布式锁

  究其原因,月结报表的制作和上传是一个很烧资源的过程,如果全国的中通站点都集中在月初时并发地制作月结报表,服务器根本承受不了这样的压力。

  鉴于此,小千的这个学生打算利用Redisson分布式锁结合信号量进行限流。也就是根据服务器的实际承受能力,后台允许同时制作10份月结报表。如果服务器正在同时制作10份月结报表,那么其他制作月结报表的请求只能排队,直到有任务完成让出一个信号量,才能处理一个新的请求。制作完成的月结报表会被上传到文件服务器,后台会通知前端客户自行下载报表。

  那么以上这个解决思路,到底该怎么实现呢?

  二. 实现过程

  2.1 实现原理

  其实redisson分布锁信号量的实现原理非常简单,就是在redis中的一个整数,当有制作报表的请求时,我们首先尝试获得一个信号量,如果能够获得(也就是信号量的整数大于0)就执行制作报表的任务,然后让信号量总数减1。制作报表的任务完成之后,再调用release()方法释放一个信号量,信号总量+1。

  2.2 核心代码实现

  接下来小千就把核心代码给大家展示一下。我们先在redis中初始化一个信号量,并且设置为10个。

1

  当某个站点发出打印报表的请求时,先把任务记录到数据库中,并把任务的状态设置为【等待中】。

2

  当流式查询把所有的数据查出,并生成报表之后,我们应该上传报表到文件服务器,修改任务的状态为【任务完成】,并释放一个信号量出来。

3

  三. 后话

  为了解决此次OOM的问题,我们使用到了流式查询分页读取数据,又使用到了分布式锁的信号量限流,来限制同时执行任务的个数。但小千的这个学生发现,大数据读取、生成excel、文件上传这些操作,每一个都非常耗时,为了不让这三个操作彼此影响性能,最后还要使用MQ解耦,把这三个操作拆分成3个服务。至于结合MQ进行具体解决的方案,小千会在以后的文章中继续连载,请各位同学继续关注哦。

相关文章

flutter和uni-app在应用层面有什么区别?

flutter和uni-app在应用层面有什么区别?

2023-10-14
Flutter和 qt的区别都有什么?

Flutter和 qt的区别都有什么?

2023-10-14
rnn和lstm中batchsize和timestep的区别是什么?

rnn和lstm中batchsize和timestep的区别是什么?

2023-10-14
什么是OA服务器?

什么是OA服务器?

2023-10-14

最新文章

常见网络安全面试题:Windows常用的命令有哪些?

常见网络安全面试题:Windows常用的命令有哪些?

2023-10-09
常见网络安全面试题:根据设备告警如何展开排查?

常见网络安全面试题:根据设备告警如何展开排查?

2023-10-09
常见网络安全面试题:mysql加固呢?(数据库加固)

常见网络安全面试题:mysql加固呢?(数据库加固)

2023-10-09
常见网络安全面试题:windows和linux加固?(操作系统加固)

常见网络安全面试题:windows和linux加固?(操作系统加固)

2023-10-09
在线咨询 免费试学 教程领取