Celery用于监控微信报警

应用场景

广告系统会根据业务需求(比如预算到期,创意被拒,账户被封等)给用户发送微信提醒。

之前的实现方法是,由业务模块负责把数据推送到由redis简单构成的消息队列中,然后有一个集中处理模块定期去采集消息队列中的信息,发送给对应用户。

这样实现虽然简单,但是有一些问题的: 1. 定期集中处理相当于是采用轮询的方式查看队列,首先在没有数据时,轮询操作本身是一种浪费资源(尽管在这个场景下浪费不大),其次轮询意味着固定的时间周期,如果时间周期过短肯定是资源消耗增加,如果时间周期过长一方面是报警不及时(你预算都停了半天才告诉我,还不如我自己去看对吧),同时也会让很多报警一次性的发送给用户(微信突然响个不停) 2. redis的队列本身没有重试,也不会保存信息,换句话说,如果采集模块出bug了,这些数据就是丢了,前期报警数据本身没有那么重要(因为不是直接涉及钱的数据),但丢数据从技术角度还是应该解决的问题。 3. 代码复杂度,用redis的话,每个业务服务都得redis客户端对吧,那就要负责开关。每个业务服务通常习惯使用不同的名称(与业务本身相关),这点得和采集模块保持一致,但如果模块多了呢,或者说这种信息定义在业务代理里,本身查看和更新也非常不方便。

Celery可以解决的问题 1.不是同步非阻塞了,是异步查询。执行效率变高了,用户不用等了,如果业务量级大,还是会有延迟,但你可以定义不同优先级的队列处理,用户基本是及时收到报警信息。 2.任务本身可以重试,相关消息也可以根据需要保存。 3.采集模块简化为一个函数,业务调用模块调用函数(实际是发送消息到队列),两侧均不再需要直接接触redis。

另外也研究了Celery用于定时任务管理的功能,考虑对其它语言的接受程度和系统稳定性,还是决定使用公司内部开发的调度系统。关于定时任务的应用,以后有机会再做介绍。