新手学习RabbitMQ
安装RabbitMQ
-
因为rabbitmq是erlang语言开发的,所以想使用rabbitmq先要安装erlang环境
#下载 wget https://packages.erlang-solutions.com/erlang-solutions-2.0-1.noarch.rpm #解压 rpm -Uvh erlang-solutions-2.0-1.noarch.rpm #安装插件 yum install -y socat
-
在官网根据自己的运行环境下载rabbitmq的安装包https://www.rabbitmq.com/download.html
-
安装rabbitmq
rpm -Uvh rabbitmq-server-3.9.11-1.el7.noarch.rpm #设置开机自启 systemctl enable rabbitmq-server #启动 systemctl start rabbitmq-server #查看启动是否成功 systemctl status rabbitmq-server
-
安装管理界面
#安装 rabbitmq-plugins enable rabbitmq_management #重启服务 systemctl restart rabbitmq-server
安装完毕后通过ip:15672即可跳转带管理界面,该界面有一个默认账号密码为:
guest
,这个账号密码只能在本机上访问,如果服务在远程服务器上,则必须创建一个新的账号#创建用户名密码 rabbitmqctl add_user admin admin #设置用户的权限 rabbitmqctl set_user_tags admin administrator #赋予其"/"根目录下所有文件的访问权限 rabbitmqctl set_permissions -p / admin '.*' '.*' '.*' #修改密码 rabbitmq change_password admin admin123 #查看用户清单 rabbitmq list_users
用户的权限有四种(向下权限依次减小)
administrator :可以登录控制台,查看所有信息,可以对rabbitmq进行管理
monitoring:监控者,可以登录控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)。
policymaker:策略制定者,可以登录控制台,同时可以对policy进行管理。但只能查看自己相关节点的相关信息。
management:普通管理员,可以登录控制台,无法看到节点信息,也无法对策略进行管理。
-
登录界面及登录后界面
简单测试
-
新建一个maven项目,添加rabbitmq依赖
<dependencies> <dependency> <groupId>com.rabbitmq</groupId> <artifactId>amqp-client</artifactId> <version>5.10.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> <scope>compile</scope> </dependency> </dependencies>
-
生产者测试
package com.zhb.rabbitmq.simple; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import java.io.IOException; import java.util.concurrent.TimeoutException; /** * @author ZHB * @Description 简单模式-生产者 * 一个生产者,一个消费者 * @create 2021-12-19 */ public class Producer { public static void main(String[] args) { //所有的中间件技术都是基于TCP/IP协议基础之上进行开发的,rabbitmq采用amqp协议 //1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.236.128");//服务所在的ip地址 factory.setPort(5672); factory.setUsername("admin"); factory.setPassword("admin"); factory.setVirtualHost("/");//虚拟访问节点,前面配置账户权限的时候已经添加了根目录下的所有访问权限 Connection connection=null; Channel channel=null; try { //2. 创建连接Connection connection = factory.newConnection("生产者"); //3. 通过连接获取通道 channel=connection.createChannel(); //4. 通过创建交换机,声明队列,绑定关系,路由Key,发送消息和接受消息 String queueName="queue1"; /** * @params1 队列的名称 * @params2 是否要持久化 * @params3 排他性(是否是独占队列) * @params4 是否自动删除(随着最后一个消费者消费完毕是否把队列自动删除) * @params5 携带附属的消息 */ channel.queueDeclare(queueName,false,false,false,null); //5. 准备消息内容 String message="hello,RabbiyMQ!"; //6. 发送消息给队列queue channel.basicPublish("",queueName,null,message.getBytes()); } catch (Exception e) { e.printStackTrace(); } finally { //7. 关闭通道 if(channel!=null && channel.isOpen()){ try { channel.close(); }catch (Exception e){ e.printStackTrace(); } } //8. 关闭连接 if(connection!=null && connection.isOpen()){ try { connection.close(); }catch (Exception e){ e.printStackTrace(); } } } } }
运行程序结果后,管理界面如图所示,已经有一条消息准备就绪,还处于未被消费的情况,由于我们把通道和连接都在程序
finally
中关闭掉了,所以界面里查看不到。你们可以不关闭,在里面查看即可。 当你执行多次生产者,你可以看到这里面的Ready和Total不断的累加,执行几次就有几条信息在等待被消费
-
消费者测试
package com.zhb.rabbitmq.simple; import com.rabbitmq.client.*; import java.io.IOException; /** * @author ZHB * @Description 简单模式-消费者 * @create 2021-12-19 */ public class Consumer { public static void main(String[] args) { //所有的中间件技术都是基于TCP/IP协议基础之上进行开发的,rabbitmq采用amqp协议 //1.创建连接工程 ConnectionFactory factory = new ConnectionFactory(); factory.setHost("192.168.236.128"); factory.setPort(5672); factory.setUsername("admin"); factory.setPassword("admin"); factory.setVirtualHost("/");//虚拟访问节点 Connection connection=null; Channel channel=null; try { //2. 创建连接Connection connection = factory.newConnection("消费者"); //3. 通过连接获取通道 channel=connection.createChannel(); //4. 通过创建交换机,声明队列,绑定关系,路由Key,发送消息和接受消息 String queueName="queue1"; channel.queueDeclare(queueName,false,false,false,null); //5. 从队列queue1里面接收消息 channel.basicConsume(queueName, true, new DeliverCallback() { @Override public void handle(String s, Delivery delivery) throws IOException { System.out.println("消息是:"+new String(delivery.getBody(),"UTF-8")); } }, new CancelCallback() { @Override public void handle(String s) throws IOException { System.out.println("接收失败"); } }); System.in.read();//通过这个阻断一下程序,可以去观察一下连接和通道都是什么样的情形 } catch (Exception e) { e.printStackTrace(); } finally { //6. 关闭通道 if(channel!=null && channel.isOpen()){ try { channel.close(); }catch (Exception e){ e.printStackTrace(); } } //7. 关闭连接 if(connection!=null && connection.isOpen()){ try { connection.close(); }catch (Exception e){ e.printStackTrace(); } } } } }
通过程序我们可以看到 信息可以通过
new String(delivery.getBody(),"UTF-8")
取出信息,注意,当生产者生产多个消息时候,消费者消费一次会将所有Ready中的信息都会消费掉,使数量变成0
持久化与非持久化
当这个队列处于持久化的时候,我们的服务器宕机了,这个队列就会被保存下来,当队列消失则代表是非持久化的。
非持久化的消息会存盘吗?
我们都应该清楚,只要是持久化的东西,那就代表会存盘,那rabbitmq非持久化的队列信息会存盘吗?其实rabbitmq的非持久化队列的信息也会存盘,但是当服务重启,该消息依旧会丢失。
-