首先需要声明的是,这个标题是有问题的。因为用 MySQL 实现队列并不是一个好的选择。
之所以使用 MySQL 是因为想尝试一下。
在 Google 之前,先实践一下自己的思路
MySQL table 结构
task_queue
- id
- msg_id
- created_at
- finished_at
有三个 worker 负责发送消息, 每隔 5 秒钟来取一次 task。 需要防止的事情是, 两个以上 woker 取到同一个 task。
worker 流程
- 读取最旧的一条记录, 同时给该条数据打上标志,防止其他 worker 也能读到。所以,需要增加一个标志字段,status。
- 处理该条数据
- 更新该条数据的状态。status,finished_at 都需要更新,finished_at 用来后期查看任务耗时。
更新一下表结构
task_queue
- id
- msg_id
- status
- created_at
- finished_at
如果 worker 因异常崩溃,或者因程序更新重启,怎么保证 status 为正在处理的任务能够被再次处理?如何知道这项任务是未处理完,还是已经中断处理?最简单的方法是,每个 worker 在拉取任务之前,先判断是否有自己未处理完的任务。所以,再补充一个字段 worker, 用来标识处理该项任务的 worker。
更新一下表结构
task_queue
- id
- msg_id
- status
- worker
- created_at
- finished_at
同时更新一下 worker 执行流程:
- 拉取是否有之前中断的任务,如果有,继续处理
- update 最旧的一项任务,如果有影响到的数据行,再取出来,进行处理
参考
微信关注我哦 👍
我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式