CentOS7 + RabbitMQ3.7.5 + PHP

CentOS7 + RabbitMQ3.7.5 + PHP

MQ 全称为 Message Queue。消息队列(MQ)是一种应用程序对应用程序的通信方法。目前业界有很多 MQ 产品。它们是 RabbitMQ、Redis、ZeroMQ、KafkaMQ、ActiveMQ 等。本文今天讲的是 RabbitMQ。它是使用 Erlang 编写的一种开源的消息队列,本身支持很多的协议:AMQP、XMPP、SMTP、STOMP。也正是如此,使得它变得非常重量级,更适合企业级开发。同时实现了一个经纪人(Broker)构架,这意味着消息在发送给客户端时先在中心队列排队。对路由(Routing),负载均衡(Load balance)或者数据持久化都有很好的支持。

一、Erlang 安装

1)RabbitMQ 是用 Erlang 语言编写。

所以,我们在安装 RabbitMQ 之前必须安装 Erlang。

$ yum -y install make ncurses-devel gcc gcc-c++ unixODBC unixODBC-devel openssl openssl-devel
$ wget http://erlang.org/download/otp_src_20.3.tar.gz
$ tar zxvf otp_src_20.3.tar.gz
$ cd otp_src_20.3
$ ./configure                       \
  --prefix=/usr/local/erlang      \
  --enable-smp-support            \
  --enable-threads                \
  --enable-sctp                   \
  --enable-kernel-poll            \
  --enable-hipe                   \
  --with-ssl
$ make && make install

2)设置环境变量

$ vi /etc/profile

将 Erlang 的 bin 目录添加进去。

ERL_HOME=/usr/local/erlang
PATH=$ERL_HOME/bin:$PATH
export ERL_HOME PATH

让环境变量立即生效:

$ source /etc/profile

二、安装 RabbitMQ

Erlang 安装好之后。我去 RabbitMQ 找到了最新的 RPM 包。我们就不通过源码安装了。

$ wget https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.5/rabbitmq-server-3.7.5-1.el7.noarch.rpm
$ rpm -i --nodeps rabbitmq-server-3.7.5-1.el7.noarch.rpm

三、RabbitMQ 管理

1)启动 RabbitMQ

$ rabbitmq-server start

启动成功会输出如下信息:


  ##  ##
  ##  ##      RabbitMQ 3.7.5. Copyright (C) 2007-2018 Pivotal Software, Inc.
  ##########  Licensed under the MPL.  See http://www.rabbitmq.com/
  ######  ##
  ##########  Logs: /var/log/rabbitmq/rabbit@localhost.log
                    /var/log/rabbitmq/rabbit@localhost_upgrade.log

              Starting broker...
 completed with 0 plugins.

2)停止 RabbitMQ

$ rabbitmqctl stop

四、用户管理

1)添加用户

为当前程序新建用户 admin 密码为 admin:

$ rabbitmqctl add_user admin admim

2)删除用户

$ rabbitmqctl delete_user admin

注意:当删除用户时,任何引用该用户访问权限条目都会从 RabbitMQ 权限数据库中自动删除。RabbitMQ 并不会提醒你与用户相关的控制条目都被删除了。所以,删除用户时需要非常谨慎。

3)查看当前用户

$ rabbitmqctl list_users

4)修改密码

$ rabbitmqctrl change_password admin admin123

我们把用户 admin 的用户密码修改成了 admin123

五、权限管理

1)分配权限

我们现在给添加的 admin 账号赋予读写以及配置的权限。

$ rabbitmqctl set_permissions -p  / admin  ".*"  ".*" ".*"

查看权限设置结果:

$ rabbitmqctl list_permissions -p /

会输出如下结果:

Listing permissions for vhost "/" ...
admin   .*      .*      .*
guest   .*      .*      .*

参数说明:

-p /:代表 set_permissions 控制条目应该用到哪个 vhosts 上;
admin:代表被授权的用户名字;
".*" ".*"  ".*":分别代表配置、读和写权限,而其中的 ".*" 为正则表达式,代表匹配所有权限;

开发中我们为了方便,通常都会给用户最大权限。正式上线之后,会根据实际用途细化设置。

2)删除权限

$ rabbitmqctl clear_permissions -p / admin

此时,我们再查看一下权限情况:

$ rabbitmqctl list_permissions -p /

会输出如下结果:

Listing permissions for vhost "/" ...
guest   .*      .*      .*

我们发现,admin 用户的权限已经被删除了。如果要查看用户所有的 RabbitMQ 服务器上的 vhosts 上的权限,请使用 list_user_permissions 命令。开发中,我们一般更关注解决实际的业务场景问题。所以,当需要深入去操作这块的时候可以去查看相关的手册。

六、角色管理

为用户添加权限,已经基本可以满足我们的需求了,但有时,我们可以使用系统预置的角色,为用户赋予角色,那么该用户也就拥有了该角色所赋予的所有权限了,在 RabbitMQ 中,角色大致分为超级管理员、监控者、策略制定者、普通管理者以及其他,它们的区别是什么?

(1) 超级管理员(administrator)

可登陆管理控制台(启用managementplugin的情况下),可查看所有的信息,并且可以对用户,策略(policy)进行操作。

(2) 监控者(monitoring)

可登陆管理控制台(启用managementplugin的情况下),同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)

(3) 策略制定者(policymaker)

可登陆管理控制台(启用managementplugin的情况下),同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。

(4) 普通管理者(management)

仅可登陆管理控制台(启用managementplugin的情况下),无法看到节点信息,也无法对策略进行管理。

(5) 其他

无法登陆管理控制台,通常就是普通的生产者和消费者。

用户角色分配

$ rabbitmqctl set_user_tags admin administrator

我们再来查看一下用户的情况:

$ rabbitmqctl list_users

输出如下结果:

Listing users ...
admin   [administrator]
guest   [administrator]

我们可以看到,刚添加一个用户的时候,[] 里面的内容为空。现在变成了 [administrator]

如果想分配其他角色直接通过此命令操作即可。

七、服务使用统计

在上面,我们使用了-p选项,旨在指定虚拟主机或路径信息,如果不添加该选项,那么rabbitmqctl会将”/”作为默认的路径访问。

1)查看队列

查看默认虚拟机上所有的队列列表(list_queues):

$ rabbitmqctl list_queues

因为,当前我刚刚安装并未进行任何的队列操作。于是,会输出如下结果:

Timeout: 60.0 seconds ...
Listing queues for vhost / ...

2)查看队列名字、消息数目、消费者数目及内存使用情况:

$ rabbitmqctl list_queues name messages consumers memory

跟上面一样,当前没有任何队列数据。所以,会输出如下结果:

Timeout: 60.0 seconds ...
Listing queues for vhost / ...

八、PHP 与 RabbitMQ 基础操作

1)安装 PHP php-amqplib

在项目根目录创建 composer.json 文件。内容如下:

{
    "require": {
        "php-amqplib/php-amqplib": ">=2.6.1"
    }
}

然后进入到该项目下执行如下命令:

$ composer install

2)发送消息到 RabbitMQ 队列当中

send.php

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

// [1] 创建 RabbitMQ 连接
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// [2] 打开一个通道。
$channel    = $connection->channel();
// [3] 定义一个队列。
$channel->queue_declare('hello', false, false, false, false);
// [4] 创建一条字符串消息对象。
$msg = new AMQPMessage('Hello World!');
// [5] 向队列当中推送一条消息。
$channel->basic_publish($msg, '', 'hello');

echo " [x] Sent 'Hello World!'\n";
// [6] 关闭通道。
$channel->close();
// [7] 关闭连接。
$connection->close();

3)接收队列消息并消费

receive.php

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;

// [1] 创建 RabbitMQ 连接。
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
// [2] 打开一个通道。
$channel = $connection->channel();
// [3] 定义一个队列。
$channel->queue_declare('hello', false, false, false, false);

echo ' [*] Waiting for messages. To exit press CTRL+C', "\n";

// [4] 定义一个匿名方法处理接收到的消息。
$callback = function($msg) {
    echo " [x] Received ", $msg->body, "\n";
};
// [5] 设置接收到的消息由谁来消息。
$channel->basic_consume('hello', '', false, true, false, false, $callback);
// [6] 循环等待接收队列的消息。
while(count($channel->callbacks)) {
    $channel->wait();
}

4)启动脚本

分别运行这两个脚本。

php receive.php

接收消息的脚本会一直等待有消息为止才会输出内容。

php send.php

通过多次执行 send.php 脚本,可以向 RabiitMQ 队列当中发送消息。

九、RabbitMQ 与 Redis 对比

通过不同的资料进行综合对比得知。Redis 在单个数据不超过 10k 的情况下,性能普遍高于 RabbitMQ。当数据超过 10k 的时候,数据入队时性能会下降很多。而 RabbitMQ 数据大小对入队出队都非常稳定。

RabbitMQ 虽然总体性能可能较低。但是,当数据大且并发量上来之后,我们可以很好的通过扩展服务器解决问题。也就是说,RabbitMQ 更适合企业级的应用。小型应用 Redis 会更适合。毕竟,企业级的应用对稳定性要求是最高的。

Reids 支持的数据类型比 RabbitMQ 要多。

Redis:轻量级、高并发、延迟敏感、限时数据分析、秒杀计数器、缓存等。

RabbitMQ:重量级、高并发、异步、指数据异步处理、并行任务串行化、高负载任务的负载均衡等。

博主 2011 年创建了一个《PHP 初学者官方群》,目前群成员 500 人左右。群号:168159147。为了防止广告,设置为付费入群。欢迎大家加入讨论技术!

标签: 无

发表评论: