Magento 2 消息队列使用

1,274 阅读5分钟

相关配置文件

配置消息队列涉及在<module>/etc目录中创建和修改以下配置文件:

用例

根据您的需要,您可能只需要创建和配置communication.xml这些文件中的一个或两个。

  • 如果您只想发布到由第三方系统创建的现有队列,则只需要该queue_publisher.xml文件。
  • 如果只想从现有队列中使用,则只需要queue_consumer.xml配置文件。
  • 如果要配置本地队列并发布给本地队列以供第三方系统使用,则需要queue_publisher.xmlqueue_topology.xml文件。
  • 当您要配置本地队列并使用由第三方系统发布的消息时,将需要queue_topology.xmlqueue_consumer.xml文件。

communication.xml

<module>/etc/communication.xml 文件定义了所有通信类型共有的消息队列系统的各个方面。此版本支持AMQP和数据库连接。

示例

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Communication/etc/communication.xsd">
  <topic name="synchronous.rpc.test" request="string" response="string">
    <handler name="processRpcRequest" type="Magento\TestModuleSynchronousAmqp\Model\RpcRequestHandler" method="process"/>
  </topic>
  <topic name="magento.testModuleSynchronousAmqp.api.serviceInterface.execute" schema="Magento\TestModuleSynchronousAmqp\Api\ServiceInterface::execute">
    <handler name="processRemoteRequest" type="Magento\TestModuleSynchronousAmqp\Model\RpcRequestHandler" method="process"/>
  </topic>
</config>

topic 配置项

topic 的配置可以在 env.php 文件中被覆盖。

ParameterDescription
nametopic名称,用.分割,例如: cat.white.feeddog.retriever.walk.
request配置consumer入参数据格式。
response指定response数据格式。如果是同步队列,这个参数是必需的。如果是异步队列,这个参数可忽略。
schemaThe interface that describes the structure of the message. The format must be <module>\Api\<ServiceName>::<methodName>.

handler 配置项

handler 配置定义了哪个类用来消费 message

ParameterDescription
name名称
type类名或接口名
method方法
disabled是否禁用这个handler , 默认值: false.

queue_consumer.xml

示例

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/consumer.xsd">
    <consumer name="basic.consumer" queue="basic.consumer.queue" handler="LoggerClass::log"/>
    <consumer name="synchronous.rpc.test" queue="synchronous.rpc.test.queue" handler="LoggerClass::log"/>
    <consumer name="rpc.test" queue="queue.for.rpc.test.unused.queue" consumerInstance="Magento\Framework\MessageQueue\BatchConsumer" connection="amqp"/>
    <consumer name="test.product.delete" queue="queue.for.test.product.delete" connection="amqp" handler="Magento\Queue\Model\ProductDeleteConsumer::processMessage" maxMessages="200" maxIdleTime="180" sleep="60" onlySpawnWhenMessageAvailable="0"/>
</config>

consumer 配置项

AttributeDescription
name (必填)consumer 名称
queue (必填)queue 名称
handler指定处理这条消息的类和方法。格式为: <Vendor>\Module\<ServiceName>::<methodName>.
consumerInstanceThe Magento class name that consumes the message
connection针对 AMQP 连接, connection 的值必须和queue_topology.xml 文件中 connection 属性值相同;其余连接类型,connection 的值必须是 db.
maxMessages指定 consumer 最大处理消息数量。
maxIdleTime (v2.4.1版本支持)定义了等待新消息的最大等待时间(单位:秒);如果在这个时间内没有收到新的消息,customer 进程将终止,默认值: null
sleep (v2.4.1版本支持)指定检查队列中是否有新消息之前的休眠时间(以秒为单位)。默认值null等于1秒。
onlySpawnWhenMessageAvailable (v2.4.1版本支持)布尔值(10仅布尔值),用于标识是否仅在相关队列中有可用消息时才产生使用者。默认值:null

只有设置了maxMessages值时, maxIdleTimesleep 这两个属性的值才会被使用。

Consumer handlers 配置项

handler 可以在communication.xmlqueue_consumer.xml 两个文件中定义;如果在queue_consumer.xml 文件中定义了 handler,communication.xml 文件中的将被忽略。

queue_topology.xml

queue_topology.xml 文件定义了路由规则。 包含:

  • exchange
  • exchange/binding (可选)
  • exchange/arguments (可选)
  • exchange/binding/arguments (可选)

示例

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/topology.xsd">
  <exchange name="magento-topic-based-exchange1" type="topic" connection="db">
    <binding id="topicBasedRouting2" topic="anotherTopic" destinationType="queue" destination="topic-queue1">
        <arguments>
            <!--Not part of our use case, but will be processed if someone specifies them-->
            <argument name="argument1" xsi:type="string">value</argument>
        </arguments>
    </binding>
    <arguments>
        <argument name="alternate-exchange" xsi:type="string">magento-log-exchange</argument>
    </arguments>
  </exchange>
  <exchange name="magento-topic-based-exchange2" type="topic" connection="db">
    <binding id="topicBasedRouting1" topic="#" destinationType="queue" destination="topic-queue2"/>
    <arguments>
      <argument name="alternate-exchange" xsi:type="string">magento-log-exchange</argument>
    </arguments>
  </exchange>
</config>

exchange 配置项

AttributeDescription
name (必填)名称,确保值唯一
type (必填)固定值:topic.
connection (必填)针对 AMQP 连接, connection 的值必须唯一;MySQL连接类型,connection 的值必须是 db.
durable指定 exchange 是否持久的。重新启动服务器后,会清除非持久性exchange。默认值为true
autoDelete指示在所有队列使用完毕后是否删除该exchange。默认值为false
internal如果设置为true,则发行人不得直接使用该交换,而只能与其他交换绑定时使用。默认值为false

binding 配置项

AttributeDescription
id (必填)唯一ID
topic (必填)topic名称。可以指定通配符 *
destinationType (必填)固定值: queue.
destination (必填)指定 queue 名称.
disabled是否禁用,默认值: false.

arguments 配置项

可选,定义参数传递给broker 调用。

AttributeDescription
name参数名称
type参数类型

示例:

<arguments>
    <argument name="warehouseId" xsi:type="int">1</argument>
    <argument name="carrierName" xsi:type="string">USPS</argument>
</arguments>

queue_publisher.xml

queue_publisher.xml 定义了 connection and exchange 的信息

示例:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/publisher.xsd">
    <publisher topic="magento.testModuleSynchronousAmqp.api.serviceInterface.execute" disabled="true" />
    <publisher topic="asynchronous.test">
        <connection name="amqp" exchange="magento" disabled="false"/>
        <connection name="db" exchange="exch1" disabled="true"/>
    </publisher>
</config>

publisher 配置项

AttributeDescription
topic (必填)topic名称。
disabled是否禁用队列。默认值:false

connection 配置项

connection元素是publisher元素的子节点。一次定义的与发布者的已启用活动连接不得超过一个。如果没有定义connection元素,则将使用amqp和的默认连接magento

AttributeDescription
name (必填)对于AMQP连接,连接名称必须与文件中的connection属性匹配queue_topology.xml。否则,连接名称必须为db
exchange要发布到的 exchange 的名称。默认的系统交换名称是magento
disabled确定是否禁用此队列。默认值:false

每个 topic只有一个publisher.

queue.xml

这个文件文档中写的是已废弃,但如果你的连接是db 那这个文件是必须要的;

管理消息队列

Magento 默认提供了 crontab的方式管理消费者进程,也可以使用如Supervisor 这类工具进行进程管理

以下是 consumers_runner 配置

/app/code/Magento/MessageQueue/etc/crontab.xml

...
<job name="consumers_runner" instance="Magento\MessageQueue\Model\Cron\ConsumersRunner" method="run">
    <schedule>* * * * *</schedule>
</job>
...

ENV配置

cron_consumers_runner配置

默认行为
  • Cron consumers_runner 任务默认是激活的
  • Cron consumers_runner 任务默认执行所有已定义的消费者
  • 每个消费者执行 10000 消息后终止
具体配置

编辑 /app/etc/env.php 文件

...
    'cron_consumers_runner' => [
        'cron_run' => false,
        'max_messages' => 20000,
        'consumers' => [
            'consumer1',
            'consumer2',
        ]
    ],
...
  • cron_run - 是否使用 crontab 管理消息队列 (默认值 : true).
  • max_messages - 指定消费者进程停止前需要处理的 (默认值: 10000).
  • consumers - 列出所有需求启动消费者,如果是空数组将运行所有消费者。

consumers_wait_for_messages 配置

该配置在v2.3.4 版本中添加

'queue' => [
    'consumers_wait_for_messages' => 1
]

可配置的值:

  • 1—默认值,如果队列没有需要执行的任务时,consumer(消费者) 将继续监听队列直到执行任务数达到 max_messages 配置值后关闭进程。
  • 0—如果队列没有需要执行的任务时,consumer(消费者)将终止当前进程。

相关命令

查看所有消费者

bin/magento queue:consumers:list

启动队列监听

bin/magento queue:consumers:start [--max-messages=<value>] [--batch-size=<value>] [--single-thread] [--area-code=<value>] <consumer_name>

常见错误

  1. 错误描述:
Type Error occurred when creating object: Magento\Framework\MessageQueue\Consumer\Config\Data, Argument 2 passed to Magento\Framework\Reflection\TypeProcessor::resolveFullyQualifiedClassName() must be of the type string, null given, called in /var/www/magentobe/vendor/magento/framework/Reflection/TypeProcessor.php on line 535

解决方法:

方法需要添加注解

    /**
     * @param  $message
     *
     * @return void
     */
    public function process($message)