文字教学: https://bit.ly/3jFMwvS
教学影片: https://bit.ly/3WI0Wdx
范例程式: https://bit.ly/3Z0U6Bt
系统架构图: https://i.imgur.com/VZyfv0M.png
本篇来聊聊‘如何取消正在执行的工作任务’,当系统内有需要处理比较久或较多资源的
任务,肯定会将这些任务丢到其他机器再执行,执行过程如果需要取消,会经过如上图几
个步骤。先假设中间的过程不透过 Message Queue 机制,而是两个服务进行沟通透过
RESTful 或 gRPC 方式。
## 使用情境
可以看到步骤一是 worker 会先发请求到后端服务,询问目前正在执行的任务是否取消,
这边可以用一个长连接持续 30 秒或 1 分钟才断线。步骤二是 User 从 Web UI 端按下
取消的按钮。步骤三是后端服务接受到取消任务的请求,就回复 Worker 到请求执行取消
任务。
大家可以想看看此情境该如何设计流程,先不考虑多台后端服务的情境,也不考虑使用
Message Queue 的方式来实作。也许大家有想到一种方式,就是当使用者按下取消时 (到
步骤三),后端服务将此任务的状态改成取消。而 Worker 每次来询问状态 (步骤一),后
端就再查询一次就可以了 (步骤四),这方式也没有不对,只是即时性效果比较差,如果
是每 30 秒轮询一次,就有可能 30 秒后才能取消任务,轮询时间设定很短,又会造成过
多不必要的连线请求。除了这种方式外,还有没有其他方式可以不需要查询数据库就可以
即时让 Worker 知道目前任务状态。
目前先讲单机版解法,非常适用于要将服务部署在不同团队内。
## 心得
本篇最主要是要用 Go 语言的 Channel 特性来处理两个服务之间的沟通机制,大家可能
想到的解法就是用 Message Queue 来处理,但是有时候把架构想的更简单一点,用 Go
语言的特性来处理,那就减少一个服务的维运,未来要将此架构转换到其他平台就会更简
单,其他部门有需求会是将整套服务架设在不同团队内,这时候架构越简单,除错时间会
越短。