微信模板消息多线程发送场景设计

最近由于公司微信公众号的业务需求,需要一个模板消息的推送业务,但公司的公众号的粉丝数也是千万级别的,有时需要批量发送一批数量较大的模板消息,为了应对这种业务也是资讯了一些老鸟的思路,最后采取一个相对适合自己的一种方法。

基本思路:首先我们需要一个线程专门创建【微信模板消息发送任务】,接着我们还需要若干个线程执行这些发送任务。

当然为了可以执行的更快,我们的设想不能局限于一台服务器的场景设计,我们需要能在不同的服务器中也能执行这些若干个发送任务,保证能够更快的执行完模板消息的发送任务。为此我们要设计好相关的表结构来支持我们的设想。

我们先来考虑下,任务表需要哪些字段?

1、当然我们需要一个任务ID并作为主键,这个ID是每个任务的唯一标识。

2、接着是任务名,设置这个主要是因为微信模板消息有许多不同的模板,同时对应着不同的业务处理,所以希望通过这个字段来区分不同的业务处理。

3、能标识每一批发送任务的任务主ID,因为业务上发送是分批次的,例如今天有一批模板消息通知10万条优惠券A的到期提醒,正好还有另一批优惠券B的到期提醒也要通知,这就需要这两批拥有能够识别各自批次的ID。

4、每个任务的具体执行的数据段,比如优惠券A中有1至1000人的需要发送到期通知(这里的每条记录肯定需要记录每个人的openid,这样后面才能最终发到这个人的微信客户端中),这1至1000就是我们要存储的数据段,

我这里分两个字段一个开始,一个结束。

5、 任务状态,这也是一个非常关键的一个字段,因为在多线程的情况就会出现任务争抢的情况,为了保证每一个任务是被唯一的一个线程任务执行,我们需要控制好这个任务状态。

6、任务完成时间,这个字段记录任务的完成时间

7、任务创建时间

8、任务截至时间,这个字段是为了告诉发送任务的线程过了这个时间点就不需要在发送了。

9、任务超期时间,这个字段是为了限制任务执行的时间,因为任务执行的过程中,很多情况是不可控的,中间可能因为异常出现任务处理停止,所以在某个任务抢占下来的时候需要设置一个超期时间,主要为程序后面是否能够对超期任务,进行补单操作。

10、任务类型,这个字段根据自己实际的业务情况设置。

由于本人是JAVA程序员,以下是java写的任务对象

public class WechatTemplateMsgTask {

    private long id;//任务ID
	private String task_name;//任务名
	private String task_main_id;//任务主ID
	private long task_snum;//数据段开始序号
	private long task_enum;//数据段结束序号
	private String task_status;//任务状态
	private String task_finishtime;//任务完成时间
	private String add_time;//任务创建时间
	private String deadline;//任务截至时间
	private String overtime;//任务超期时间
	private String task_type;//任务类型
	
		public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getTask_name() {
		return task_name;
	}
	public void setTask_name(String task_name) {
		this.task_name = task_name;
	}	
	public String getTask_main_id() {
		return task_main_id;
	}
	public void setTask_main_id(String task_main_id) {
		this.task_main_id = task_main_id;
	}
	public long getTask_snum() {
		return task_snum;
	}
	public void setTask_snum(long task_snum) {
		this.task_snum = task_snum;
	}
	public long getTask_enum() {
		return task_enum;
	}
	public void setTask_enum(long task_enum) {
		this.task_enum = task_enum;
	}
	public String getTask_status() {
		return task_status;
	}
	public void setTask_status(String task_status) {
		this.task_status = task_status;
	}
	public String getTask_finishtime() {
		return task_finishtime;
	}
	public void setTask_finishtime(String task_finishtime) {
		this.task_finishtime = task_finishtime;
	}
	public String getAdd_time() {
		return add_time;
	}
	public void setAdd_time(String add_time) {
		this.add_time = add_time;
	}
	public String getDeadline() {
		return deadline;
	}
	public void setDeadline(String deadline) {
		this.deadline = deadline;
	}
	public String getOvertime() {
		return overtime;
	}
	public void setOvertime(String overtime) {
		this.overtime = overtime;
	}
	public String getTask_type() {
		return task_type;
	}
	public void setTask_type(String task_type) {
		this.task_type = task_type;
	}
}
接下来要讨论几个关键点:
1、如何在多个并行的线程中如何保证其中的一个线程安全的抢到一个属于自己的发送任务?
在这个问题上,我们需要利用数据库的UPDATE语句去更新需要抢占的任务的信息,这信息指的就是任务状态,我们可以设定未抢占的任务状态为0,任务已抢占的状态为1,多个线程并行都想把一个相同任务抢下来时候,都对这个任务进行更新操作,当其中的某一个线程中update的影响行数=1,那么就可以代表这个线程将这个任务操作许可权抢占下来了(这个过程我们还需要设置任务超期时间),其他的线程自然也抢占不到这条记录的操作权。
2、如何在任务超期时或者是任务部分执行时进行补单操作?
由于在我的设计中创建任务的线程也包含了补单操作,而每小时都会执行一次创建任务的线程,其中都会执行是否需要补单操作的判断,我们需要查找一些任务是否执行完成,当任务状态为1时,我们要判断它这个任务是否超期,如果超期,需要将这个任务状态设置为4(表示该任务废除),之后在新建补单的发送任务。当这个任务状态为3(3表示任务部分执行,有些已知的原因导致任务执行不全且并没有异常,这时我们可以将这个任务状态设置为3),我们需要 将这个任务状态设置为4,之后一样新建补单的发送任务。








评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值