临时性后台任务

针对一些复杂耗时的用户操作场景,一个常见的优化性能手段就是

  • 先检查必要的提交数据是否完整有效(同步执行)
  • 将复杂耗时部分改为异步执行(提前结束)

那么这里的【异步执行】就有多种实现方式了,例如:

  • 使用 Task.Run(...)
  • 使用 Hangfire 之类的组件
  • 将所有数据参数打包成一个消息结构,发送到MQ,再订阅处理

前2种方式都是 不建议 的做法,因为:

  • Task.Run,它其实是将操作任务提交到线程池,这里就有4个延伸问题:
    • 与HTTP请求争用线程,影响进程的吞吐量,甚至能出现HTTP503
    • 程序可能随时重启或者崩溃,没办法保证异步任务能执行结束
    • 没有日志
    • 缺乏监控
  • Hangfire,在这种场景下(临时任务)它其实是在解决Task.Run的问题,但是它有2大缺点
    • 增加数据库压力,尤其是非SQLSERVER数据库
    • 日志太弱,参考价值较小。




推荐做法

推荐做法:2个步骤

  1. 将所有数据参数打包成一个消息结构,发送到MQ
  2. 订阅MQ,根据消息内容执行具体任务

为什么是这样:

  • 消息一旦进入MQ,就不会丢失,程序重启或者崩溃都不受影响
  • 不依赖于数据库或者Redis,它们容易出现性能瓶颈问题
  • 充分利用ClownFish消息管道特性:
    • 重试
    • 多订阅者(数量可调,压力恒定)
    • 日志记录
    • 性能监控