上篇文章我意气风发封装了无限Channel,马上被新的需求打脸😭
新需求如下
- 根据回传的数据进行反序列化,dump出图片并且生成视频转码之后上传到云端
- 痛点:之前全量的数据很多,需要尽快生成完
- 增量请求非常集中
- 痛点:之前全量的数据很多,需要尽快生成完
第一次尝试
- 请求来了之后将数据写入Redis,利用List数据类型实现一个消息队列,我们的处理Channel从Redis中读数据(Channel数量根据业务情况自行定义)
- 在一个Channel里面完成下载,dump出图片并且生成视频转码之后上传到云端
结果执行任务发现速度达不到我们的预期
- 分析发现:因为使用下载使用内网,速度很快,视频生成、转码等比较慢
- 如果我们开了十个Channel,可能十个Channel都在下载,利用的是IO资源,十个Channel都在转码等操作,利用的是CPU资源,如果都在IO资源,那CPU资源没有Channel在利用,如果都在CPU资源,那么IO资源没有利用
优化方法
- 改成专门负责下载的Channel、专门负责视频生成的Channel,这样可以将CPU资源和IO资源都充分利用
第二次:优化 (踩坑
- 让下载Channel、视频生成Channel并行执行,使资源全部被利用
- 因为我使用是上个文章封装的无限Channel,并不会阻塞,但是下载的速度大于视频生成的速度,只有在视频生成之后才会将本地的下载的文件删除
- 下载Channel完成下载任务的时候就发消息给视频生成Channel,视频生成Channel完成之后将本地文件删除,并不会有阻塞
这就导致了下载不会阻塞,但是处理比较慢,一段时间之后磁盘就会满了
第三次:完善
- 无限Channel并不适合这个场景,因为下载的文件比较大,处理比较慢,会造成磁盘爆满的情况
- 所以最后改成了阻塞式,具体的数量需要根据具体业务来定
- 改成阻塞式的话不会出现磁盘爆满的问题,同时根据具体任务和CPU资源以及IO资源来决定数量,尽量利用好资源
总结
- 并不是所有业务场景都可以使用无限Channel,这次算是狠狠踩坑了,并且在业务中,学会怎么尽量利用好资源,IO资源和CPU资源尽量得到充分利用
- 阻塞Channel和非阻塞Channel的业务场景不一样,用好是利剑,没用好自损八百😭