入门RabbitMQ

RabbitMQ简介

rabbitmq是基于AMQP(高级消息队列协议)的开源消息中间件,rabbitmq服务端使用Erlang语言开发。消息中间件对于构建复杂应用软件来说作用主要体现在:

 

  • 解耦异构系统数据交互

  • 高并发情况下起到削峰作用

  • 保证数据顺序被处理

  • 保证数据可靠被处理

  • 较好的扩展性

 

rabbitmq目前在互联网应用的使用非常流行,主要原因如下:

 

  • 支持多种协议:AMQP、STOMP、MQTT等

  • 提供多语言客户端:java、python、JavaScript、PHP、c#等

  • 数据可靠性:支持类似ACK确认机制保证数据正确被消费

  • 高可用:可以将队列在集器中不同节点设置镜像的方式保证队列高可用

  • admin管理界面:提供一个用户交互后台管理页面操作查看队列、用户等信息

  • 插件式扩展:通过插件的方式进行功能的扩展

 

RabbitMQ安装

前面我们说过rabbitmq服务端由erlang语言开发,所以想要运行rabbitmq服务端必须先安装erlang语言环境。下面我们通过源码编译的方式在linux上安装erlang,安装之前我们需要知道不同版本的rabbitmq对应的erlang版本是有要求的,下面先了解下rabbitmq和erlang版本的对应关系表:

Rabbitmq版本

Erlang/OTP最低版本

 Erlang/OTP最高版本

3.8.2

3.8.1

3.8.0

21.3

22.x

3.7.24

3.7.23

3.7.22

3.7.21

3.7.20

3.7.19

21.3

22.x

3.7.18

3.7.17

3.7.16

3.7.15

20.3

22.x

3.7.14

3.7.13

3.7.12

3.7.11

20.3

21.3.x

3.7.10

3.7.9

3.7.8

3.7.7

19.3

21.x

3.7.6

3.7.5

3.7.4

3.7.3

3.7.2

3.7.1

3.7.0

19.3

20.3.x

下面我们选择当前较新的配套版本进行安装。

 

Rabbitmq版本

 Erlang/OTP版本

3.8.0

22.0

 

选择好版本之后,作为合格的工程师,接下来我们应该为linux操作系统规划下目录,笔者这里目录规划如下:

 

目录

说明

/opt

自定义软件根目录

/opt/src

放置源码

/opt/tarball

放置tarball文件,例如xxx.tar.gz

/opt/soft

放置安装好的软件

/opt/logs

放置日志文件

/opt/data

放置数据文件

/opt/backup

放置备份文件

 

规划好目录后将全部目录通过mkdir -p 命令创建好,并通过ll命令查看目录权限情况。

入门RabbitMQ_第1张图片

准备就绪后我们开始先安装erlang,具体步骤如下:

 

1、访问erlang官方下载地址:

https://www.erlang.org/downloads

2、进入后选择我们上面规划的22.0版本:

入门RabbitMQ_第2张图片

3、进入后这里我们选择源码文件:

入门RabbitMQ_第3张图片

4、右键复制链接地址,然后ssh登录linux系统进入/opt/tarball目录下,通过wget命令进行下载:

cd /opt/tarball
wget http://erlang.org/download/otp_src_22.0.tar.gz

 

5、从/opt/tarball目录解压erlang到/opt/src目录下:

tar -xvf otp_src_22.0.tar.gz -C /opt/src/

6、安装erlang外部依赖包:

yum install -y gcc
yum install -y perl
yum install -y ncurses-devel
yum install -y openssl openssl-devel
yum -y install unixODBC-devel

7、通过编译源码安装erlang:

cd /opt/src/otp_src_22.0
./configure --prefix=/opt/soft/erlang --without-javac
make
make install

8、配置环境变量(vi /etc/profile):

通过vi /etc/profile编辑profile文件,在文件后面新增下面内容:

export ERLANG_HOME=/opt/soft/erlang
export PATH=$PATH:$ERLANG_HOME/bin

执行source /etc/profile使配置生效。

9、验证安装情况(erl):

出现如上图证明安装成功!安装好erlang语言后接下来继续安装rabbitmq,具体步骤如下:

1、访问rabbtimq github realeas页面:

https://github.com/rabbitmq/rabbitmq-server/releases

2、进入后通过tag切换为3.8.0版本,然后拉到最后选择版本为3.8.0的二进制安装包:

入门RabbitMQ_第4张图片

3、进入/opt/tarball目录通过wget命令进行下载:

cd /opt/tarball
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.0/rabbitmq-server-generic-unix-3.8.0.tar.xz

4、从/opt/tarball目录解压rabbitmq二进制包到/opt/soft目录下:

tar -xvf rabbitmq-server-generic-unix-3.8.0.tar.xz -C /opt/soft/

5、配置环境变量:

通过vi /etc/profile编辑profile文件,将上面新增的内容重新修改为:

export ERLANG_HOME=/opt/soft/erlang
export RABBITMQ_HOME=/opt/soft/rabbitmq_server-3.8.0
export PATH=$PATH:$ERLANG_HOME/bin:$RABBITMQ_HOME/sbin

执行source /etc/profile使配置生效。

 

6、启动RabbitMQ服务:

rabbitmq-server
或者后台方式启动:
rabbitmq-server -detached

出现如下图证明成功安装并启动rabbtimq服务:

入门RabbitMQ_第5张图片

7、查看rabbitmq服务运行状态:

rabbitmqctl status

8、停止服务:

rabbitmqctl stop

rabbitmqctl命令是rabbitmq当前节点服务端的命令行客户端,通过该命令可以获取服务端的信息以及和服务端进行交互。

 

RabbitMQ 初体验

上面我们安装好了rabbitmq服务,那么接下来我们就通过helloworld的方式来体验一把,这里我们使用java语言进行开发,通过maven构建工具管理项目依赖,通过IDEA编辑器进行代码编写,具体步骤如下:

 

1、通过IDEA创建一个普通maven项目,名称笔者这里为:lazy-course-rabbitmq:

 

2、访问github,找到rabbitmq-java-client项目的pom依赖坐标并添加到项目pom.xml:

JDK8以上的可以使用下面版本坐标(笔者使用这个):
 

    com.rabbitmq
    amqp-client
    5.8.0

 
JDK8以下的可以使用下面版本坐标:
 

    com.rabbitmq
    amqp-client
    4.11.3

3、分别创建发送者和接收者类,关键代码如下:

发送者Send.java :

public class Send {


    public static void main(String[] args) throws Exception {


        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.137.101");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        
        //public final static String HELLO_QUEUE_NAME = "hello";
        channel.queueDeclare(Const.HELLO_QUEUE_NAME, false, false, false, null);
        String message = "Hello World!";
        channel.basicPublish("", Const.HELLO_QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent '" + message + "'");


    }
}

接收者Recv.java :

public class Recv {


    public static void main(String[] argv) throws Exception {


        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.137.101");
        factory.setPort(5672);


        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();


        //public final static String HELLO_QUEUE_NAME = "hello";
        //queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map arguments
        channel.queueDeclare(Const.HELLO_QUEUE_NAME, false, false, false, null);


        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");


        DeliverCallback deliverCallback = new DeliverCallback() {
            public void handle(String s, Delivery delivery) throws IOException {
                String message = new String(delivery.getBody(), "UTF-8");
                System.out.println(" [x] Received '" + message + "'");
            }
        };


        //basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, ConsumerShutdownSignalCallback shutdownSignalCallback)
        channel.basicConsume(Const.HELLO_QUEUE_NAME, true, deliverCallback, new CancelCallback() {
            public void handle(String s) throws IOException {
            }
        });
    }
}

4、分别运行发送者和接收者main方法,可以看到控制台输出如下:

发送者控制台输出 :

入门RabbitMQ_第6张图片

报错了,提示没有权限!

原因是rabbitmq服务默认启动后用户名和密码均为:guest,guest这个用户默认只能通过localhost的方式访问,不支持在别的服务器通过ip的方式远程去访问,当然可以通过配置允许guest远程访问,但是强烈不建议这么做!最佳的方式删除guset用户,然后创建一个新的账号,并赋予足够的服务器权限,创建方式如下:

- 列出当前用户列表:

rabbitmqctl list_users

- 删除guest用户:

rabbitmqctl delete_user guest

- 创建新用户(标签为空非管理员):

rabbitmqctl add_user lazy 111111

- 为lazy用户设置管理员标签:

rabbitmqctl set_user_tags lazy administrator

入门RabbitMQ_第7张图片

- 查看并创建虚拟主机(rabbitmq支持多租户模式,任何队列都必须附属在某个虚拟主机上,类似nginx的虚拟主机server{}的概念,安装后默认虚拟主机名称/,guest用户拥有/虚拟主机的权限):

rabbitmqctl list_vhosts 
rabbitmqctl add_vhost vhost_hello

入门RabbitMQ_第8张图片

- 设置虚拟机最大连接数和队列数限制参数:

rabbitmqctl set_vhost_limits -p vhost_hello '{"max-connections": 200, "max-queues": 1024}'

- 查看lazy用户拥有的虚拟机权限

rabbitmqctl list_user_permissions lazy

- 给lazy用户添加使用vhost_hello虚拟机资源的权限:

rabbitmqctl set_permissions -p vhost_hello lazy "^hello.*" ".*" ".*"

入门RabbitMQ_第9张图片

前面3个正则代表如下:

  • conf( "^hello.*"):与资源名称(用户被授予配置权限)相匹配的正则表达式,^hello.*表示配置以hello开头的所有资源。

  • 写( ".*"):与资源名称相匹配的正则表达式,用户被授予写权限,.*表示配置为所有资源。

  • 读( ".*"):与资源名称匹配的正则表达式,已授予用户读取权限.*表示配置为所有资源。

 

5、修改前面的发送和接受的代码后如下:

发送者代码:

public class Send {




    public static void main(String[] args) throws Exception {


        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.137.101");
        factory.setPort(5672);
        factory.setVirtualHost("vhost_hello");
        factory.setUsername("lazy");
        factory.setPassword("111111");


        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();


        //public final static String HELLO_QUEUE_NAME = "hello";
        channel.queueDeclare(Const.HELLO_QUEUE_NAME, false, false, false, null);
        String message = "Hello World!";
        channel.basicPublish("", Const.HELLO_QUEUE_NAME, null, message.getBytes());
        System.out.println(" [x] Sent '" + message + "'");


    }
}

接收者代码:

public class Recv {


    public static void main(String[] argv) throws Exception {


        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.137.101");
        factory.setPort(5672);
        factory.setVirtualHost("vhost_hello");
        factory.setUsername("lazy");
        factory.setPassword("111111");


        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();


        //public final static String HELLO_QUEUE_NAME = "hello";
        //queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map arguments
        channel.queueDeclare(Const.HELLO_QUEUE_NAME, false, false, false, null);


        System.out.println(" [*] Waiting for messages. To exit press CTRL+C");


        DeliverCallback deliverCallback = new DeliverCallback() {
            public void handle(String s, Delivery delivery) throws IOException {
                String message = new String(delivery.getBody(), "UTF-8");
                System.out.println(" [x] Received '" + message + "'");
            }
        };


        //basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, ConsumerShutdownSignalCallback shutdownSignalCallback)
        channel.basicConsume(Const.HELLO_QUEUE_NAME, true, deliverCallback, new CancelCallback() {
            public void handle(String s) throws IOException {
        
            }
        });
    }
}

6、运行发送者控制台输出:

入门RabbitMQ_第10张图片

7、运行接收者控制台输出:

入门RabbitMQ_第11张图片

8、查看rabbitmq服务vhost_hello虚拟机上队列创建情况:

rabbitmqctl list_queues -p vhost_hello

至此,我们用java实现了一个基于RabbitMQ简单的发送者和接收者程序!

 

RabbitMQ管理界面

前面我们说过,rabbitmq这么主流的原因之一就是它支持插件式扩展能力,比如前面通过rabbitmqctl命令管理的方式如果能有个界面化操作的话会更加友好,rabbtimq通过插件的方式提供了一款界面后台管理,默认端口为:15672:

入门RabbitMQ_第12张图片

我们直接通过浏览器访问是无法访问到的,我们需要通过插件管理命令rabbitmq-plugins激活插件,激活命令如下:

rabbitmq-plugins enable rabbitmq_management

入门RabbitMQ_第13张图片

激活后无需重启服务就可以使用了,访问后界面如下:

入门RabbitMQ_第14张图片

这里需要带有如下标签账号才能登录:

标签

能力

(None)

无法访问管理插件

管理(management)

用户可以通过消息传递协议执行的任何操作以及:

列出可以通过AMQP登录的虚拟主机

查看“其”虚拟主机中的所有队列,交换和绑定

查看并关闭自己的渠道和联系

查看涵盖其所有虚拟主机的“全局”统计信息,包括其中其他用户的活动

政策制定者(policymaker)

包含management所有权限外加:

查看,创建和删除可通过AMQP登录到的虚拟主机的策略和参数

监控(monitoring)

列出所有虚拟主机,包括它们无法使用消息传递协议访问的虚拟主机

查看其他用户的联系和渠道

查看节点级别的数据,例如内存使用情况和集群

查看所有虚拟主机的真实全局统计信息

管理员(administrator)

包含policymaker和monitoring所有权限外加:

创建和删除虚拟主机

查看,创建和删除用户

查看,创建和删除权限

关闭其他用户的连接

标签类似角色,不同标签拥有不同的权限,我们前面创建的lazy账号设置的标签为administrator,类似超级管理员权限,所以lazy当然是可以直接登录的且拥有超管的权限,登录后界面如下:

入门RabbitMQ_第15张图片

我们可以通过后台管理界面进行管理用户、虚拟机、交换机、队列、发送消息、连接数等擦操作,功能非常丰富。

关注本人微信公众号,后续将持续rabbitmq集群搭建、组件讲解、配置讲解等更新更多干货!

---------------------- 正文结束 ------------------------

长按扫码关注微信公众号

Java软件编程之家

你可能感兴趣的:(入门RabbitMQ)