临时性后台任务
针对一些复杂耗时的用户操作场景,一个常见的优化性能手段就是
- 先检查必要的提交数据是否完整有效(同步执行)
- 将复杂耗时部分改为异步执行(提前结束)
那么这里的【异步执行】就有多种实现方式了,例如:
- 使用 Task.Run(...)
- 使用 Hangfire 之类的组件
- 将所有数据参数打包成一个消息结构,发送到MQ,再订阅处理
前2种方式都是 不建议 的做法,因为:
- Task.Run,它其实是将操作任务提交到线程池,这里就有4个延伸问题:
- 与HTTP请求争用线程,影响进程的吞吐量,甚至能出现HTTP503
- 程序可能随时重启或者崩溃,没办法保证异步任务能执行结束
- 没有日志
- 缺乏监控
- Hangfire,在这种场景下(临时任务)它其实是在解决Task.Run的问题,但是它有2大缺点
- 增加数据库压力,尤其是非SQLSERVER数据库
- 日志太弱,参考价值较小。
推荐做法
推荐做法:2个步骤
- 将所有数据参数打包成一个消息结构,发送到MQ
- 订阅MQ,根据消息内容执行具体任务
为什么是这样:
- 消息一旦进入MQ,就不会丢失,程序重启或者崩溃都不受影响
- 不依赖于数据库或者Redis,它们容易出现性能瓶颈问题
- 充分利用ClownFish消息管道特性:
- 重试
- 多订阅者(数量可调,压力恒定)
- 日志记录
- 性能监控