2020-08-06:现有一批邮件需要发送给订阅顾客,且有一个集群(集群的节点数不定,会动态扩容缩容)来 负责具体的邮件发送任务,如何让系统尽快地完成发送? 请详述技术方案!
福哥答案2020-08-06:

参考答案:
A.借助消息中间件,通过发布者订阅者模式来进行任务分配
B.master-slave 部署,由master 来分配任务
C.不借助任何中间件,且所有节点均等。通过数据库的 update returning,从而实现节点之间任务的互斥

知乎答案:
这个问题解决方案很多,主要要考虑:
1.动态任务分配:例如如果是先分配好,后执行的话,那么在执行发邮件的时候,加入节点,没法分摊压力
2.任务补偿:如果某个节点挂了,分配给这个节点的任务,需要其他节点执行。

如果可以使用中间件的话,那么各种MQ的集群消费模式,是比较好的方案。这个集群中节点可以动态添加,删除,每个消息只在某个节点消费一次。只有发邮件成功,消费才算完成,这样补偿也有了。
不能使用中间件,可以采用分配者,执行者模式,或者master-slave模式,动态根据当前集群节点数分配任务执行。如何分配,可以:
1.任务id哈希对于节点个数取模
2.一致性哈希分配

如何执行:
1.同步调用,调用slave或者执行者接口,发送成功返回。吞吐量比较差,任务堆积在分配者或者master这里,耗费资源多。
2.异步调用,调用slave分配任务立刻返回,slave真正发送前,加分布式锁,查询数据库这个任务是否发送完成,如果没发送则发送后更新数据库。假设发邮件接口最大响应时间是10s,那么master可以考虑一个任务经过30s(大于十秒,不要过于接近)以上时间,就可以补偿这个任务重新分配。