PHP中RabbitMQ之phpAmqplib实现(五
环境:CoentOS,PHP 7
简单介绍一下php-amqplib
php-amqplib是Advanced Message Queuing Protocol (AMQP)的一个PHP开源实现。高级消息队列协议(AMQP)是一个异步消息传递所使用的应用层协议规范。作为线路层协议,而不是API(例如JMS),AMQP 客户端能够无视消息的来源任意发送和接受信息
1、RabbitMQ的安装
需要下载的两个包
erlang-21.0.7-1.el7.centos.x86_64.rpm
rabbitmq-server-3.7.7-1.el7.noarch.rpm
这两个包我已经放在了百度云盘的分享上
链接:https://pan.baidu.com/s/1rMv_yFpLnH-D1S5wrOZrbA#list/path=%2FRabbitMQ
提取码:ipyu
然后参照 weixin_41368339的博客linux rabbitmq3.7.7安装与使用一文中的步骤安装步,基本上没有什么问题
2、composer的安装(已安装的请忽略此步)
为什么要装这个?我们可以通过composer来下载安装php-amqplib
如何安装composer,可以百度一下composer的全局安装或者直接去composer中文网
3、php-amqplib的下载及安装
新建一个composer.json的文件,内容如下所示
- {
 - "require": {
 - "php-amqplib/php-amqplib": ">=2.6.1"
 - }
 - }
 
然后执行
composer install
会生成一个composer.lock文件及vendor文件夹,vendor文件夹里有php-amqplib库,且有一个autoload.php文件可以使用自动加载
4、Demo示例
本Demo示例只创建了一个直连交换机,共有四个文件Consumer.php (消费者),Publisher.php (生产者) ,Parenter.php (自己封装的RabbitMQ的方法) ,以及test.php (测试数据),目录如图所示

Parenter.php 代码如下图所示
- <?php
 - require_once __DIR__ . '/vendor/autoload.php';
 - use PhpAmqpLib\Connection\AMQPStreamConnection;
 - use PhpAmqpLib\Message\AMQPMessage;
 - abstract class Parenter
 - {
 - //MQ的默认连接配置
 - public $config = array(
 - 'host' => '127.0.0.1', //ip
 - 'port' => '5672', //端口号
 - 'user' => 'guest', //用户
 - 'password' => 'guest', //密码
 - 'vhost' => '/' //虚拟host
 - );
 - public $connection; //链接
 - public $channel; //信道
 - public $exchangeName = ''; //交换机名
 - public $queueName = ''; //队列名
 - public $routeKey = ''; //路由键
 - public $exchangeType = 'direct'; //交换机类型
 - public $autoAck = true; //是否自动ack应答
 - public function __construct($exchangeName, $queueName, $routeKey, $exchangeType = 'direct', $config=array())
 - {
 - $this->exchangeName = empty($exchangeName) ? '' : $exchangeName;
 - $this->queueName = empty($queueName) ? '' : $queueName;
 - $this->routeKey = empty($routeKey) ? '' : $routeKey;
 - $this->exchangeType = empty($exchangeType) ? '' : 'direct';
 - if(!empty($config))
 - {
 - $this->setConfig($config);
 - }
 - $this->createConnect();
 - }
 - //创建连接与信道
 - private function createConnect()
 - {
 - $host = $this->config['host'];
 - $port = $this->config['port'];
 - $user = $this->config['user'];
 - $password = $this->config['password'];
 - $vhost = $this->config['vhost'];
 - if(empty($host) || empty($port) || empty($user) || empty($password))
 - {
 - throw new Exception('RabbitMQ的连接配置不正确');
 - }
 - //创建链接
 - $this->connection = new AMQPStreamConnection($host, $port, $user, $password, $vhost);
 - //创建信道
 - $this->channel = $this->connection->channel();
 - $this->createExchange();
 - }
 - //创建交换机
 - private function createExchange()
 - {
 - //创建交换机$channel->exchange_declare($exhcange_name,$type,$passive,$durable,$auto_delete);
 - //passive: 消极处理, 判断是否存在队列,存在则返回,不存在直接抛出 PhpAmqpLib\Exception\AMQPProtocolChannelException 异常
 - //durable:true、false true:服务器重启会保留下来Exchange。警告:仅设置此选项,不代表消息持久化。即不保证重启后消息还在
 - //autoDelete:true、false.true:当已经没有消费者时,服务器是否可以删除该Exchange
 - $this->channel->exchange_declare($this->exchangeName, $this->exchangeType, false, true, false);
 - //passive: 消极处理, 判断是否存在队列,存在则返回,不存在直接抛出 PhpAmqpLib\Exception\AMQPProtocolChannelException 异常
 - //durable:true、false true:在服务器重启时,能够存活
 - //exclusive :是否为当前连接的专用队列,在连接断开后,会自动删除该队列
 - //autodelete:当没有任何消费者使用时,自动删除该队列
 - //arguments: 自定义规则
 - $this->channel->queue_declare($this->queueName, false, true, false, false);
 - }
 - //发送消息
 - public function sendMessage($data)
 - {
 - //创建消息$msg = new AMQPMessage($data,$properties)
 - //#$data string类型 要发送的消息
 - //#roperties array类型 设置的属性,比如设置该消息持久化[‘delivery_mode’=>2]
 - $msg = new AMQPMessage($data, array('delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT));
 - $this->channel->basic_publish($msg,$this->exchangeName, $this->routeKey);
 - }
 - //处理消息
 - public function dealMq($flag)
 - {
 - $this->autoAck = $flag;
 - $this->channel->queue_bind($this->queueName,$this->exchangeName, $this->routeKey);
 - //prefetchSize:0
 - //prefetchCount:会告诉RabbitMQ不要同时给一个消费者推送多于N个消息,即一旦有N个消息还没有ack,则该consumer将block掉,直到有消息ack
 - //global:true\false 是否将上面设置应用于channel,简单点说,就是上面限制是channel级别的还是consumer级别
 - //$this->channel->basic_qos(0, 1, false);
 - //1:queue 要取得消息的队列名
 - //2:consumer_tag 消费者标签
 - //3:no_local false这个功能属于AMQP的标准,但是rabbitMQ并没有做实现.参考
 - //4:no_ack false收到消息后,是否不需要回复确认即被认为被消费
 - //5:exclusive false排他消费者,即这个队列只能由一个消费者消费.适用于任务不允许进行并发处理的情况下.比如系统对接
 - //6:nowait false不返回执行结果,但是如果排他开启的话,则必须需要等待结果的,如果两个一起开就会报错
 - //7:callback null回调函数
 - //8:ticket null
 - //9:arguments null
 - $this->channel->basic_consume($this->queueName, '', false, $this->autoAck, false, false, function($msg){$this->get($msg);});
 - //监听消息
 - while(count($this->channel->callbacks)){
 - $this->channel->wait();
 - }
 - }
 - public function get($msg)
 - {
 - $param = $msg->body;
 - $this->doProcess($param);
 - if(!$this->autoAck)
 - {
 - //手动ack应答
 - $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
 - }
 - }
 - abstract public function doProcess($param);
 - public function closeConnetct()
 - {
 - $this->channel->close();
 - $this->connection->close();
 - }
 - //重新设置MQ的链接配置
 - public function setConfig($config)
 - {
 - if (!is_array($config))
 - {
 - throw new Exception('config不是一个数组');
 - }
 - foreach($config as $key => $value)
 - {
 - $this->config[$key] = $value;
 - }
 - }
 - }
 
Consumer.php (消费者)
- <?php
 - include_once('Parenter.php');
 - class Consumer extends Parenter
 - {
 - public function __construct()
 - {
 - parent::__construct('exchange', 'queue', 'routeKey');
 - }
 - public function doProcess($msg)
 - {
 - echo $msg."\n";
 - }
 - }
 - $consumer = new Consumer();
 - //$consumer->dealMq(false);
 - $consumer->dealMq(true);
 
Publisher.php (生产者)
- <?php
 - include_once('Parenter.php');
 - class Publisher extends Parenter
 - {
 - public function __construct()
 - {
 - parent::__construct('exchange', '', 'routeKey');
 - }
 - public function doProcess($msg)
 - {
 - }
 - }
 
test.php(测试数据)
- <?php
 - include_once('Publisher.php');
 - $publisher = new Publisher();
 - $publisher->sendMessage('Hello,World!');
 - $publisher->closeConnetct();
 
5、添加交换机与队列
打开http://ip(你的RabbitMQ安装的主机):15672/,会进入到RabbitMQ的可视化管理后台登录页面,登录你的账号密码(如果你是按照第一步提到的博客里的教程来装的,那你的账号密码就是guest),然后新加交换机和队列,
以下是新加交换机的操作,注意vhost与以及交换机的名称要与代码里的消费者与生产者传入的参数值保持一致,如果你不想使用"/"这个默认的vhost,也可以新建一个vhost(什么?你问我如何新建,那么请百度一下),但是要记住在代码里创建消费者与生产者时把你新加的这个vhost传进去,覆盖RabbitMqParernt.php里的vhost

以下是新加队列,这里的vhost要与上一步的vhost保持一致,保证交换机与队列在同一个vhost下,不然交换机会找不到队列的,队列名与消费者代码里传入进去的队列名保持一致

6、运行代码
先打开一个窗口启动消费者

运行测试脚本

如果打印出来字符串就成功了

注意:消费者与生产者传入的交换机名称,路由键必须相同
交换机类型请务必选择直连,各种交换机的路由键形式不大相同,有兴趣的同学可以去试试其它类型的交换机实现哦
当修改了vhost或者交换机名称,队列名称等时,需要修改对应代码
至于注释里的ack应答,我会在之后的博客里详细介绍,包括RabbitMQ的持久化,这里使用默认的ack应答即可
代码里很多注释都是我后来学习php-amqplib库中类的方法时加的,表示的是参数的意义,大家也可以去研究一下,这里提供个网址:Rabbitmq各方法的作用详解
关于管理后台及RabbitMQ的命令,我这里就不多介绍了,有兴趣的同学去网上搜索一下就能搜到好多
下一篇:RabbitMQ的持久化(六)
PHP中RabbitMQ之phpAmqplib实现(五的更多相关文章
- 如何从40亿整数中找到不存在的一个  webservice  Asp.Net Core 轻松学-10分钟使用EFCore连接MSSQL数据库  WPF实战案例-打印  RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange
		
如何从40亿整数中找到不存在的一个 前言 给定一个最多包含40亿个随机排列的32位的顺序整数的顺序文件,找出一个不在文件中的32位整数.(在文件中至少确实一个这样的数-为什么?).在具有足够内存的情况 ...
 - RabbitMQ学习总结 第五篇:路由Routing
		
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
 - RabbitMQ入门教程(十五):普通集群和镜像集群
		
原文:RabbitMQ入门教程(十五):普通集群和镜像集群 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.c ...
 - .NET中RabbitMQ的使用
		
概述 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.他遵循Mozilla Public ...
 - {Django基础八之cookie和session}一 会话跟踪    二 cookie         三 django中操作cookie        四 session        五 django中操作session
		
Django基础八之cookie和session 本节目录 一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session 六 xxx 七 ...
 - NETCore中RabbitMQ的使用
		
NET中RabbitMQ的使用 https://www.cnblogs.com/xibei666/p/5931267.html 概述 MQ全称为Message Queue, 消息队列(MQ)是一种应用 ...
 - Word中划线的方法(五种)
		
Word中划线的方法(五种): 1. 按CTRL+F9,在出现的黑底花括号内,如图输入内容, 最后按SHIFT+F9(或者右键菜单点切换域代码),以后可以反复按ALT+F9在代码与结果之间切换. 注: ...
 - linux中RabbitMQ安装教程
		
linux中RabbitMQ安装教程 在做一个微服务项目时候用到消息队列,于是深入了解了消息队列知识,并在linux上安装了Rabbitmq,本博客介绍Rabbitmq的安装教程,想要深入了解消息队列 ...
 - OpenStack 中 RabbitMQ 的使用
		
OpenStack 中 RabbitMQ 的使用 本文是 OpenStack 中的 RabbitMQ 使用研究 两部分中的第一部分,将介绍 RabbitMQ 的基本概念,即 RabbitMQ 是什么. ...
 
随机推荐
- MATLAB常用快捷键总结
			
MATLAB 命令栏显示处理的常用命令 清屏:clc 紧凑显示格式:format compact 宽松显示格式:format loose 数据高精度显示:format longG 数据低精度显示:fo ...
 - IE浏览器URL中的查询条件中包含中文时报404的解决办法
			
情况是比如我输入如下URL到IE浏览器: http://localhost:8090/RPT_TYSH_JL_ZD_DETAIL.html?pageIndex=1&year=2018& ...
 - EasyUI中对datagrid的扩展方法
			
以下是给datagrid扩展一个方法的demo 1.给datagrid添加一个属性 $.extend($.fn.datagrid.defaults, { demo: "demo1" ...
 - 初始Hibernate框架
			
首先我们需要先创建一个案例 构建一个Student 的实体类 private String name; private Integer age; private Integer id; 在SRC根目录 ...
 - EasyNetQ使用(二)【连接RabbitMQ,SSL连接,Logging】
			
如果你连接过关系数据库,例如SQL Server.你会发现EasyNetQ处理connections有点奇怪.和关系数据库通讯一直都是通过client开始的.Client 打开一个连接, 发出一个SQ ...
 - Tracking of Features and Edges
			
目录 Joint Tracking of Features and Edges Joint Tracking of Features and Edges 1. LK光流 基本LK光流运动假设: \[ ...
 - Vue中ESlint配置文件.eslintrc文件
			
很久没有分享和更新过了 今天就给大家分享一篇 Vue中ESlint配置文件.eslintrc文件详解吧 ------------------------------------------------ ...
 - POJ1149 PIGS 【最大流 + 构图】
			
题目链接:http://poj.org/problem?id=1149 PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions ...
 - 你除了在客户端上会使用Cookie,还能使用哪些可以作为数据缓存呢?
			
问题如标题,直奔主题.介绍下另两种缓存. 1.sessionStorage.localStorage localStorage: 是一种你不主动清除它,它会一直将存储数据存储在客户端的存储方式,即使你 ...
 - SpringBoot 对IBM MQ进行数据监听接收以及数据发送
			
一.需求介绍 后端使用Spring Boot2.0框架,要实现IBM MQ的实时数据JMS监听接收处理,并形成回执通过MQ队列发送. 二.引入依赖jar包 <dependency> < ...