最近在做H&M的项目,其中用户信息的增、删、改需要用到rabbitmq,(mmp!搞了两天多,终于弄清楚怎么做的了,被网上的教程坑得想哭)这里总结一下如何把rabbitmq结合到magento2.3中。

首先,你需要自己把magento和rabbitmq以及php的mq扩展装好。我这里的magento是EE(企业)版,社区版的我没用。

确认都装好了 没问题之后,开始步入正题!

这个是官网的配置教程

我们先在 app/etc 的env.php里面加入 queue 的配置(没有env.php 就自己创建一个)

return [
......
'queue' => [
        'amqp' => [
            'host' => 'localhost',
            'port' => '5672',
            'user' => 'guest',
            'password' => 'guest',
            'virtualhost' => '/'
        ]
    ]
......
]

接下来的每一个配置文件,都是在模块下面的etc文件夹里面创建的。

我们先创建 communication.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/queue.xsd">
    <topic name="crm.customer.new" request="string" />
</config>

这个文件就是用来设置rabbitmq的主题的。这个request就是指定主题的数据类型。

由于我这里只需要发布者就行了,所以就没有设置消费者

接下来就是创建 queue_topology.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/queue_topology.xsd">
    <!-- name : 指定的交换机名字  -->
    <!-- type : 写为topic即可 -->
    <!-- connection: 这里我们是链接mq,所以填 amqp,如果是数据库的话,就填 db -->
    <exchange name="hm.ec" type="topic" connection="amqp">
        <!-- id: 交换机和主题、路由绑定的唯一id -->
        <!-- topic: 和communication.xml中的topic值一致 -->
        <!-- destinationType: 这里就填queue即可 -->
        <!-- destination: 标识队列的名称,和topic一致即可 -->
        <binding id="CustomerNew" topic="crm.customer.new" destinationType="queue" destination="crm.customer.new"/>
    </exchange>
</config>

然后,我们就可以创建发布者的配置文件啦 queue_publisher.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework-message-queue:etc/queue_publisher.xsd">
    <!-- topic: 和上面topic一致-->
    <publisher topic="crm.customer.new">
        <!-- name: 对于AMQP连接,连接名必须与queue_topology.xml文件中的连接属性匹配。否则,连接名必须是db -->
        <!-- exchange: 和queue_topology.xml里面的exchange name一致 -->
        <connection name="amqp" exchange="hm.ec" />
    </publisher>
</config>

欧克,到这里,发布者的配置就完成了,我也是跟着网上的教程,配置到这里,然后就一脸懵逼了,因为接下来如何启动发布者,其他地方根本就没说过。我就是被卡在这一步整整两天。废话不多说,继续。

文件配置好后,我们需要执行执行命令upgrade更新模块配置文件,这一步操作,我在项目根目录执行的

php bin/magento setup:upgrade

执行完毕之后,我们可以添加一个命令行去测试一下。

在etc文件夹里面创建di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Console\CommandList">
        <arguments>
            <argument name="commands" xsi:type="array">
                <item name="publish-message" xsi:type="object">software\Customer\Console\MessagePublishCommand</item>
            </argument>
        </arguments>
    </type>
</config>

然后创建一个 Console 文件夹,注意:需要和 etc 文件夹同级。在Console下面创建 MessagePublishCommand.php

<?php
namespace software\Customer\Console;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Magento\Framework\MessageQueue\PublisherInterface;

class MessagePublishCommand extends Command
{
    public $publish;
    public function __construct(PublisherInterface $publish,$name = null)
    {
        $this->publish = $publish;
        parent::__construct($name);
    }

    protected function configure()
    {
        $this->setName('customer:publish');
        $this->setDescription('Demo command line');
        parent::configure();
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $arr = [
            [
                "customer_id_1",
            ],
            [
                "customer_id_2",
            ]
        ];
        $json = json_encode($arr);
        while(true){
            $this->publish->publish('crm.customer.new',$json);
            $output->writeln($json);
            sleep(2);
        }
    }
}

创建完毕之后,执行命令

php bin/magento c:c
php magento setup:upgrade

这里就已经配置加载完毕了,我们可以执行命令看一下

php bin/magento

仔细查看,可以找到


运行发布者:

php bin/magento customer:publish

如何确定是否真的运行成功?可以在rabbitmq的网页管理里面去查看,也可以创建一个消费者读取消息,看看是否成功。

下面这个是我在网上找的一个脚本

<?php 
//配置信息 
$conn_args = array( 
    'host' => 'localhost',  
    'port' => '5672',  
    'login' => 'guest',  
    'password' => 'guest', 
    'vhost'=>'/' 
);   
$e_name = 'hm.ec'; //交换机名 
$q_name = 'crm.customer.new'; //队列名
$k_route = 'crm.customer.new'; //路由key
 
//创建连接和channel 
$conn = new AMQPConnection($conn_args);   
if (!$conn->connect()) {   
    die("Cannot connect to the broker!\n");   
}   
$channel = new AMQPChannel($conn);   
 
//创建交换机    
$ex = new AMQPExchange($channel);   
$ex->setName($e_name); 
$ex->setType(AMQP_EX_TYPE_TOPIC);
$ex->setFlags(AMQP_DURABLE); //持久化


//创建队列    
$q = new AMQPQueue($channel); 
$q->setName($q_name);   
$q->setFlags(AMQP_DURABLE); //持久化  
echo "Message Total:".$q->declare()."\n";   
 
//绑定交换机与队列,并指定路由键 
echo 'Queue Bind: '.$q->bind($e_name, $k_route)."\n"; 
 
//阻塞模式接收消息 
echo "Message:\n";   
while(True){
    sleep(1);
    $q->consume('processMessage');   
   // $q->consume('processMessage', AMQP_AUTOACK); //自动ACK应答  
} 
$conn->disconnect();   
 
/**
 * 消费回调函数
 * 处理消息
 */ 
function processMessage($envelope, $queue) { 
    $msg = $envelope->getBody(); 
    echo $msg."\n"; //处理消息 
    $queue->ack($envelope->getDeliveryTag()); //手动发送ACK应答 
}
?>

可以在服务器上创建一个文件,将上面的代码复制进去保存,然后执行

php 文件名

这时候如何成功了,就能看到消费者里面打印出消息了。

靠。。花了一个午休来写这玩意儿




2 对 “Magento2.3和RabbitMQ结合”的想法;

发表评论

电子邮件地址不会被公开。 必填项已用*标注