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

Python 为什么我需要使用异步工具来发送Django电子邮件,python,django,multithreading,python-multiprocessing,python-multithreading,Python,Django,Multithreading,Python Multiprocessing,Python Multithreading,在使用Django时,我注意到当我发送​电子邮件有一个延迟,为了克服这个问题,我不得不使用芹菜工具。所以我想知道引擎盖下到底发生了什么。为什么Django/Python需要一个异步工具来完成这项任务。我已经学习了Python中的多线程、多处理,但是如果有人能告诉我Django在不使用芹菜的情况下发送电子邮件时到底发生了什么事情。想象一下发送电子邮件就像发送请求一样,在同步上下文中,过程如下: 发送请求 等待答复 接收响应 在您等待线程不能做任何其他事情的响应的整个过程中,这是在浪费CPU周期,而

在使用Django时,我注意到当我发送​电子邮件有一个延迟,为了克服这个问题,我不得不使用芹菜工具。所以我想知道引擎盖下到底发生了什么。为什么Django/Python需要一个异步工具来完成这项任务。我已经学习了Python中的多线程、多处理,但是如果有人能告诉我Django在不使用芹菜的情况下发送电子邮件时到底发生了什么事情。

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

  • 发送请求
  • 等待答复
  • 接收响应
  • 在您等待线程不能做任何其他事情的响应的整个过程中,这是在浪费CPU周期,而这些CPU周期可能会被其他东西使用(例如为其他用户请求提供服务)

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

    另一方面,芹菜是一个异步任务队列,其中生产者(您的web应用程序)发送消息,代理(数据存储)存储和分发消息,消费者(工作者)从代理中提取消息并进行处理。使用者是与web应用程序完全独立的进程(通常是完全独立的服务器),它使web应用程序能够专注于尽快将响应返回给客户端。通过芹菜发送电子邮件的过程如下所示:

  • Web应用程序向代理发送消息并将响应返回给用户。这里有一条json伪消息。(代理实际上将消息存储为pickle对象或JSON)
  • 芹菜工人经常与代理检查是否有新消息要处理,如果它当前没有处理。有时芹菜工人会拉入成批的消息,这样就减少了开销,这是可配置的
  • 芹菜工人使用参数和关键字参数执行函数(由消息中的“任务”定义)
  • 这是一个非常简单的例子,说明了为什么你可能想用芹菜来发送电子邮件,这样你就可以尽快将回复返回给用户!它还非常适合于长时间运行的任务,例如处理图像缩略图:

  • 用户上传一个图像,你把它存储在某处(例如AmazonS3)
  • 您向代理发送一条消息,说“使用文件S3URL作为参数执行我的
    process\u image\u thumbails
    任务”
  • 将响应返回给用户。从用户的角度来看,它又好又快
  • 一名工作人员拾取消息,从S3下载文件,并将其处理为不同大小的缩略图

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

    谢谢你提供的信息。消除了很多疑问。另外,关于您提到的等待时间,是因为线程正在等待来自STMP服务器的响应,因此由于来自STMP服务器的响应延迟(网络瓶颈),线程无法执行下一个操作吗?而且,由于Python是单线程的,所以它不能生成另一个线程来处理线程1(正在等待SMTP的响应)的加载?抱歉这么晚才问这个问题。没错,它正在等待响应,而等待会消耗CPU周期。从技术上讲,您可以在python中使用多线程,并将发送电子邮件的工作推送到另一个线程。这将加快响应速度,但是,就服务器负载而言,这可能不是最有效的选择。该线程仍在同步上下文中执行请求,因此它将在等待时消耗CPU周期。如果发出100个请求,那么100个线程将空闲地等待SMTP响应。因此,使用芹菜的一个原因是从web服务器上移除负载。
    {
        "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
    }