我正在构建一个需要在固定时间向用户发送通知的应用程序。用户可以选择他们希望收到通知的时间,以及他们希望收到通知的日期。例如,用户可能希望每天早上6点或仅在工作日的上午7点收到通知。
在后端,我不确定如何构建发送这些通知的服务。解决方案需要处理:
答案 0 :(得分:2)
使用RabbitMQ等消息代理和Celery等任务调度程序可能符合您的要求。
异步或非阻塞处理是一种将某些任务的执行与程序主流分离的方法。这为您提供了几个优点,包括允许您的面向用户的代码不间断地运行。
消息传递是程序组件可用于通信和交换信息的方法。它可以同步或异步实现,并且可以允许离散进程无问题地进行通信。消息传递通常作为此类用法的传统数据库的替代实现,因为消息队列通常实现其他功能,提供更高的性能,并且可以完全驻留在内存中。
Celery是一个基于异步消息传递系统构建的任务队列。它可以用作可以转储编程任务的存储桶。传递任务的程序可以继续执行并响应地运行,然后,它可以轮询芹菜以查看计算是否完成并检索数据。
虽然芹菜是用Python编写的,但它的协议可以用任何语言实现。 worker是Python中Celery的一个实现。如果该语言具有AMQP客户端,则使用您的语言创建工作人员的工作量不会太大。 Celery工作者只是连接到代理来处理消息的程序。
此外,还有另一种与语言无关的方法,那就是使用REST任务,而不是将任务作为功能,它们就是URL。有了这些信息,您甚至可以创建简单的Web服务器,以支持预加载代码。只需公开执行操作的端点,然后创建一个只对该端点执行HTTP请求的任务。
这是来自官方documentation的蟒蛇示例:
from celery import Celery
from celery.schedules import crontab
app = Celery()
@app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
# Calls test('hello') every 10 seconds.
sender.add_periodic_task(10.0, test.s('hello'), name='add every 10')
# Calls test('world') every 30 seconds
sender.add_periodic_task(30.0, test.s('world'), expires=10)
# Executes every Monday morning at 7:30 a.m.
sender.add_periodic_task(
crontab(hour=7, minute=30, day_of_week=1),
test.s('Happy Mondays!'),
)
@app.task
def test(arg):
print(arg)
答案 1 :(得分:0)
我可以看到你需要有3种类型的实体:用户(存储电子邮件或其他一些方式来访问用户),通知(存储你想发送给用户的内容 - 文本等)和时间表(到当用户想要收到通知时存储)。您需要将这些类型的实体存储在某种数据库中。 时间表应与用户连接,通知应与用户和时间表相关联。
假设您拥有每分钟启动一些脚本的cron作业。此脚本将尝试将所有通知与当前时间(作业开始时间)的计划相关联。不要忘记实施某种类型的重叠预防。
此脚本将在队列中放置任务(包含所有需要的数据:通知类型,要通知的用户等)(beanstalkd或其他)。您可以创建任意数量的工作人员(即使在不同的物理实例上),因为您希望为此队列提供服务(而不考虑重复) - 这将为您提供出色的可扩展性。
如果用户更改了他的日程安排,它将同时影响他的所有通知。没有待处理的通知,因为它们只有在真正发送时才会提供。
这是一个非常高级的描述。许多事情取决于语言,数据库,队列服务器,工作器实现。