记一次OOM问题的解决连载二【Redisson信号量限流】
一. 前言
上周在《记一次OOM问题的解决连载一 流式查询》中写到,我在“中通全球创研中心”的学生为了避免出现OOM问题,把一个站点一个月流水的数据,用Mybatis流式查询的方式,把数据分批次读进内存再写到硬盘上。这样处理之后确实在一定程度上减少了OOM发生的次数,但仍然会在月初各个站点,集中进行上个月份月结报表时出现OOM的现象。
究其原因,月结报表的制作和上传是一个很烧资源的过程,如果全国的中通站点都集中在月初时并发地制作月结报表,服务器根本承受不了这样的压力。
鉴于此,这个学生打算利用Redisson分布式锁结合信号量进行限流。也就是根据服务器的实际承受能力,后台允许同时制作10份月结报表。如果服务器正在同时制作10份月结报表,那么其他制作月结报表的请求只能排队,直到有任务完成让出一个信号量,才能处理一个新的请求。制作完成的月结报表会被上传到文件服务器,后台会通知前端客户自行下载报表。
那么以上这个解决思路,到底该怎么实现呢?
二. 实现过程
2.1 实现原理
其实redisson分布锁信号量的实现原理非常简单,就是在redis中的一个整数,当有制作报表的请求时,我们首先尝试获得一个信号量,如果能够获得(也就是信号量的整数大于0)就执行制作报表的任务,然后让信号量总数减1。制作报表的任务完成之后,再调用release()方法释放一个信号量,信号总量+1。
2.2 核心代码实现
接下来就把核心代码给大家展示一下。我们先在redis中初始化一个信号量,并且设置为10个。
@PostConstruct
public void init() throws Exception {
//初始化1个名为read 的信号量
RSemaphore read = redissonClient.getSemaphore("read");
//设置信号量的初始值为10
read.release(10);
}
当某个站点发出打印报表的请求时,先把任务记录到数据库中,并把任务的状态设置为【等待中】。
@GetMapping("/create")
public R createExcel(){
//TODO 1: 把任务添加到任务列表
//尝试获得一个信号量,如果能获得马上开始读数据库写文件的操作
RSemaphore read = redissonClient.getSemaphore("read");
if(read.tryAcquire()){
//TODO 2: 由于读数据制作文件比较耗时,这里采用线程池调用mybatis流式查询生成报表
}
// 因为生成报表是线程异步执行,这个响应很快会回到前端,提醒前端人员打印任务已经接受
return new R(REnum.SUCCESS,null);
}
当流式查询把所有的数据查出,并生成报表之后,我们应该上传报表到文件服务器,修改任务的状态为【任务完成】,并释放一个信号量出来。
/**
* 这个方法是流式查询查询出最后一批数据时候调用的方法
*/
public void end(){
// TODO 1: 上传已经完成的文件去文件服务器
// TODO 2: 修改任务的状态为【任务完成】,并且表中记录这一条任务对应文件的地址
// 释放一个信号量
RSemaphore read = redissonClient.getSemaphore("read");
read.release();//执行这一句 信号量的值加一
}
三. 后话
为了解决此次OOM的问题,我们使用到了流式查询分页读取数据,又使用到了分布式锁的信号量限流,来限制同时执行任务的个数。但这个学生发现,大数据读取、生成excel、文件上传这些操作,每一个都非常耗时,为了不让这三个操作彼此影响性能,最后还要使用MQ解耦,把这三个操作拆分成3个服务。
相关推荐HOT
更多>>怎么将string字符串转换成byte[]数组?
例如,使用默认字符集转换可以如下所示: 也可以指定字符集: 这将使用UTF-8字符集将字符串转换成字节数组。详情>>
2023-04-25 17:14:58如何禁用浏览器的前进和后退功能
URL) 本质就是在进入页面或者路由跳转的时候在历史记录中保存一条没有意义的记录,这样用户在点击前后后退按钮的时候就没有效果。详情>>
2023-04-19 10:36:58react传值是什么意思?
react是组件化的框架,组件实例间作用域是互相隔离的,所以组件间的通信就变成了开发过程中常常要解决的问题,根据场景可以分为: 父子组...详情>>
2023-04-18 17:23:22使用IE浏览器遇见过哪些兼容问题?
在IE6中,块元素设置float并且有水平方向的margin时,margin显示出来会比设置的值大,会导致最后一块元素被顶到下面去; 解决办法:在CSS文...详情>>
2023-04-12 09:21:12