我试图在这里了解芹菜和AMQP的工作原理。
我的方案
我在机器中安装了芹菜
点安装芹菜
我使用
from celery import Celery
app = Celery('tasks', backend='amqp', broker='amqp://')
@app.task
def print_hello():
print 'hello there'
据我了解,芹菜将此任务转换为消息并通过 AMQP 协议发送给代理(redis 或 rabbitmq)。然后,这些消息将排队并传递到工作节点以处理消息。
我的问题是,
- 假设我在 Java 环境中创建了任务,如果将消息发送到外部工作节点,这是否意味着工作节点服务器必须安装 Java 才能执行任务?
- 如果消息是由外部工作节点拾取的,工作节点和代理如何找到对方?在上面的代码中,我只有用于存储任务的代理地址。
还有 为什么我们将任务存储在代理中?为什么我们不能在芹菜中实现交换算法并将消息直接发送给工人?
SOAP和AMQP有什么区别?
工作人员不仅需要Python,还需要你想要在他们上运行的任务的所有代码。
但是您没有专门针对节点,这正是存在代理的原因。你把你的任务放在队列上,工人拿起它们。
我不知道你为什么在这种情况下提到SOAP。它与任何事情无关。
您的问题的具体答案是:
-
"如果消息发送到外部工作节点"略有误导。消息本身不会发送到工作节点。它被发送到代理(由 URL 标识),特别是该代理上的交易所,带有路由密钥,可以看到它登陆队列。所有工作线程都配置了相同的代理 URL 并读取此队列,这在很大程度上是 [第一个穿着最好的][1],第一个使用消息的工作线程(要读取 AMQP 中的消息,它会在一个原子操作中从队列中删除)。[消息][2] 与语言无关。然而,Workers是用Python编写的,任务定义必须用Python编写,尽管Python任务定义当然可以通过任何方式调用任何其他库来执行任务。但从某种意义上说,是的,无论您的任务需要什么运行时库才能运行,它都需要与 Worker 在同一台机器上,并且它们周围必须有一个 Python 包装器,以便 Worker 可以加载它们。
-
"如果消息是由外部工作节点选择的,工作节点和代理如何找到彼此?"- 这个问题具有误导性。他们找不到彼此。工作线程配置了与客户端完全相同的代理 URL。它知道网址。Celery 通常在 Python 中解决这个问题的方式是,你共享的代码片段由客户端和 Worker 加载。这实际上是芹菜的美妙之处之一。你用Python编写任务,并在Worker 中加载定义不变。因此,它们使用相同的代理,并定义了相同的任务。@app.task实际上创建了一个任务类实例,该实例有两个非常重要的方法:apply_async(),它创建并发送请求任务的消息,以及run()运行修饰的函数。前者在客户端中调用。后者由工作线程(实际运行任务)。
"为什么我们将任务存储在代理中 ?"-任务不存储在代理中。该任务在 python 文件中定义,就像您的代码片段一样。如 2.客户端和辅助角色读取相同的定义。从客户端发送到工作线程的消息,要求它运行任务。
"为什么我们不能在芹菜中实现交换算法并将消息直接发送给工人?"- 我必须在这里猜测,但我会问,为什么要重新发明轮子?有一个定义的标准,AMQP(高级消息队列协议),并且该标准有许多实现。为什么要再写一个?芹菜是FOSS,就像许多FOSS一样,我想开始编写它的人希望专注于任务管理而不是消息管理,并选择依靠AMQP进行消息管理。一个公平的选择。但值得一提的是,Celery 确实在 Kombu 中实现了很多,为 AMQP 提供 Python API。
SOAP(简单对象访问协议的缩写)是一种消息传递协议规范,用于在计算机网络中实现 Web 服务时交换结构化信息。
AMQP(高级消息队列协议的缩写)是面向消息的中间件的开放标准应用层协议。AMQP 的定义功能是消息面向、排队、路由(包括点对点和发布和订阅)、可靠性和安全性。
SOAP 通常是协议栈中更高级别的。描述如下:
https://www.amqp.org/product/different