为什么我需要使用异步工具来发送Django电子邮件

时间:2019-07-18 01:25:12

标签: python django multithreading python-multiprocessing python-multithreading

在使用Django时,我已经注意到当我发送电子邮件时存在延迟,为了克服这一点,我不得不使用Celery工具。所以我想知道引擎盖下到底发生了什么。 Django / Python为什么需要异步工具来完成此任务。我已经了解了Python中的MultiThreading,MultiProcessing,但是如果有人可以简要介绍一下Django在不使用Celery的情况下发送电子邮件时到底发生了什么。

1 个答案:

答案 0 :(得分:1)

像发送请求一样发送电子邮件,在同步上下文中,过程将如下:

  1. 发送请求
  2. 等待回应..........
  3. 接收响应

一直在等待线程无法执行任何其他操作的响应,这浪费了CPU周期,而这些周期可能被其他事物使用(例如,为其他用户的请求服务)。

我想在这里区分异步和celery的用法。  Python的实际异步实现使用“事件循环”来调度和接收消息。 “等待”是在单独的线程/进程中完成的,该线程/进程专门用于接收消息,并将这些消息分派给接收者,这样,发送请求的线程就不再浪费CPU周期,它将由事件循环准备就绪。这是python异步工作方式的非常模糊描述。除非发送大量电子邮件,否则不一定会使用户整个过程更快。

另一方面,Celery是一个异步任务队列,在该队列中,您具有让生产者(您的Web应用程序)发送消息,一个代理(数据存储)来存储和分发消息,以及使消费者(工人)从代理中提取消息并处理它们。使用者是与Web应用程序完全独立的过程(通常是完全独立的服务器),它释放了Web应用程序的精力,专注于尽快将响应返回给客户端。通过芹菜发送电子邮件的过程如下:

  1. Web应用程序向代理发送消息,并将响应返回给用户。这是一个json伪消息。 (代理实际上将消息存储为腌制对象或JSON)
{
    "task": "my_app.send_email",
    "args": ["Subject Line", "Hello, World! This is your email contents", "to_email@example.com", "from_email@example.com"],  # 
    "kwargs": {}  # No keyword arguments
}
  1. 芹菜工作人员一直在与经纪人联系,以检查是否正在处理新消息。有时,芹菜工作者会提取成批的消息,以便减少开销,这是可配置的。
  2. 芹菜工作者使用参数和关键字参数来执行功能(由消息中的“任务”定义)。

这是一个非常简单的示例,说明了您为什么要使用芹菜发送电子邮件,以便您可以尽快将响应返回给用户!它也非常适合长时间运行的任务,例如处理图像缩略图:

  1. 用户上传图片,并将其存储在某处(例如Amazon S3)
  2. 您向代理发送一条消息,说“以文件S3 URL作为参数执行我的process_image_thumbails任务”
  3. 您将响应返回给用户。从用户的角度来看,这很好,而且很快。
  4. 一个工人拿起消息,从S3下载文件,并将其处理为大小不同的缩略图。

当您将芹菜用于更多新的用例时,会遇到新的问题。例如,如果有人在处理缩略图时请求缩略图,我们该怎么办?我会让你想像一下。