介绍RabbitMQ是一个消息代理:接受和转发消息。把它想象成一个邮局:当您将邮件放入邮箱时,您可以确定邮递员先生最终会将邮件投递给您的收件人。在这个比喻中,RabbitMQ就是这里的邮箱、邮局和邮递员。RabbitMQ和邮局的主要区别在于它不处理纸张,而是接受、存储和转发二进制数据——消息。RabbitMQ和一般的消息传递使用行话。生产者的工作是发送消息。发送消息的程序是生产者:队列类似于一个邮箱,它存在于RabbitMQ中,但是信息流经RabbitMQ和你的应用程序,它们只能存储在一个队列中。队列仅受主机内存和磁盘限制的限制,它本质上是一个大的消息缓冲区。将有许多可以将消息发送到队列的生产者,以及可以尝试从队列接收数据的许多消费者。这就是我们表示队列的方式:消费者和生产者具有相似的含义。消费者只不过是等待消息然后处理它们的程序:注意生产者、消费者和代理不必在同一台主机上;在大多数应用程序中,他们没有。“HelloWorld”(使用PHPamqplib客户端)在教程的这一部分,我们将用PHP编写两个程序;生产者发送消息,消费者接收消息并打印出来。我们将忽略PHPamqplibAPI的一些细节,并专注于刚刚开始的这个非常简单的事情。这是一条“HelloWorld”消息。在下图中,“p”是我们的生产者,“C”是我们的消费者。中间的框是RabbitMQ代表消费者保留的消息缓冲区队列。PHPamqplib客户端库RabbitMQ有很多协议。本教程介绍AMQP0-9-1,这是一种开放的通用消息传递协议。有许多不同语言的RabbitMQ客户端。我们将在本教程中使用PHPamqplib、composer来解决依赖管理。添加composer.json:{"require":{"php-amqplib/php-amqplib":">=2.6.1"}}composerinstall#或者直接运行包导入composerrequirephp-amqplib/php-amqplib现在我们可以为了启动我们的helloworld生产者(消息发送者),我们命令我们的消息发布者(发送者)send.php和消息接收者receive.php。发送方将连接到RabbitMQ,发送消息,然后退出。require_once__DIR__。'/vendor/autoload.php';使用PhpAmqpLib\Connection\AMQPStreamConnection;使用PhpAmqpLib\Message\AMQPMessage;现在我们可以创建一个到服务器的连接:$connection=newAMQPStreamConnection('localhost',5672,'guest','guest');$channel=$connection->channel();这个连接抽象了套接字(socket)连接,负责为我们进行协议版本协商和认证。在这里,我们连接到本地计算机上的rabbitmq代理-使用localhost。如果我们想连接到不同机器上的代理,我们只需在此处指定它的名称或IP地址。接下来,我们创建一个通道,这是大多数API处理事情的地方。在发送消息之前,我们必须声明一个队列来为我们的发送做准备;然后我们可以向队列发布消息:$channel->queue_declare('hello',false,false,false,false);$msg=newAMQPMessage('HelloWorld!');$channel->basic_publish($msg,'','hello');echo"[x]Sent'HelloWorld!'\n";Declaringthatqueueisidempotent(原句:Declaringaqueueisidempotent,这里的幂等不知道什么意思)——只有队列不存在才会创建。消息内容是一个字节数组,所以你可以在那里随意编码。最后,我们关闭通道和连接;$channel->close();$connection->close();上面我们已经完成了send.php。接下来我们完成consumer的代码consumer(receiver,taskprocessor)Consumers接收到RabbitMQ的推送消息,我们会一直运行监听消息并打印出来。导入librequire_once__DIR__。'/vendor/autoload.php';使用PhpAmqpLib\Connection\AMQPStreamConnection;设置与发布者相同;我们打开一个连接和一个通道,并声明要使用的队列。请注意,这与发送发布的队列相匹配。$connection=newAMQPStreamConnection('localhost',5672,'guest','guest');$channel=$connection->channel();$channel->queue_declare('hello',false,false,false,false);echo'[*]等待消息。要退出,请按CTRL+C',"\n";请注意,我们还在这里声明了队列。由于我们可能会在发布之前启动消费者,因此我们希望在尝试使用队列中的消息之前确定队列的存在。我们将告诉服务器从队列中发送消息。我们将定义一个PHP可调用对象,它将接收服务器发送的消息。请记住,消息是从服务器异步发送到客户端的。$callback=function($msg){echo"[x]Received",$msg->body,"\n";};$channel->basic_consume('你好','',false,true,false,false,$callback);while(count($channel->callbacks)){$channel->wait();}当调用basic_consume时,我们的代码会阻塞。当我们收到消息时,我们的回调函数将传递接收到的返回消息。以上就是我们receive.phpruntestrunconsumerphpreceive.phprunmessagesenderphpsend.phplistqueuerabbitmqctllist_queues完整源码的代码(已调整)config.php['路径'=>目录名(目录名(__DIR__))。'/vendor'],'rabbitmq'=>['host'=>'127.0.0.1','port'=>'5672','login'=>'qkl','password'=>'123456','vhost'=>'/']];?>receive.phpchannel();$channel->queue_declare('你好',false,false,false,false);echo'[*]等待消息。要退出,请按CTRL+C',"\n";$callback=function($msg){echo"[x]Received",$msg->body,"\n";};$channel->basic_consume('hello','',false,true,false,false,$callback);}while(count($channel->callbacks)){$channel->wait();}$channel->close();$connection->close();?>send.phpchannel();//发送端不需要设置队列,但是为了持久化,建议执行这一行$channel->queue_declare($msg=newAMQPMessage('HelloWorld!');$channel->basic_publish($msg,'','hello');echo"[x]Sent'HelloWorld!'\n";$channel->close();$connection->close();?>要学习如何构建一个简单的工作队列,你可以阅读下一章:RabbitMQ+PHPTutorial2(WorkQueues)翻译自RabbitMQ-RabbitMQtutorial-《HelloWorld!》
