构建可配置的用户通知服务

时间:2017-03-25 16:05:15

标签: service notifications cron alert jobs

我正在构建一个需要在固定时间向用户发送通知的应用程序。用户可以选择他们希望收到通知的时间,以及他们希望收到通知的日期。例如,用户可能希望每天早上6点或仅在工作日的上午7点收到通知。

在后端,我不确定如何构建发送这些通知的服务。解决方案需要处理:

  • 并发,所以我可以扩展我的服务器(通知不应该重复)
  • 系统重启
  • 如果用户更改其偏好设置,则应重新安排待处理通知

2 个答案:

答案 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或其他)。您可以创建任意数量的工作人员(即使在不同的物理实例上),因为您希望为此队列提供服务(而不考虑重复) - 这将为您提供出色的可扩展性

如果用户更改了他的日程安排,它将同时影响他的所有通知。没有待处理的通知,因为它们只有在真正发送时才会提供。

这是一个非常高级的描述。许多事情取决于语言,数据库,队列服务器,工作器实现。