因为公司业务需要,负责搭建rabbitMQ集群,以及代码集成。今天分享一下RabbitMQ
Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。
Queue:消息队列载体,每个消息都会被投入到一个或多个队列。
Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。
Routing Key:路由关键字,exchange根据这个关键字进行消息投递。
vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。
producer:消息生产者,就是投递消息的程序。
consumer:消息消费者,就是接受消息的程序。
channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。
(2)客户端声明一个exchange,并设置相关属性。
(3)客户端声明一个queue,并设置相关属性。
(4)客户端使用routing key,在exchange和queue之间建立好绑定关系。
(5)客户端投递消息到exchange。
(1)exchange持久化,在声明时指定durable => 1
(2)queue持久化,在声明时指定durable => 1
(3)消息持久化,在投递时指定delivery_mode => 2(1是非持久化)
基于centos7Linux系统下安装。
Erlang1.8.1版本
RabbitMQ3.6.3版本
2、搭建单机环境
1、 安装erlang语言环境
Rpm Uvhhttp://www.rabbitmq.com/releases/erlang/erlang-18.1-1.el7.centos.x86_64.rp
Wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.3/rabbitmq-server-generic- unix-3.6.3.tar.xz
Xz –d rabbitmq-server-generic-unix-3.6.3.tar.xz
Tar –xvf rabbitmq-server-generic-unix-3.6.3.tar
cd ./rabbitmq_server-3.6.3
3、搭建集群环境(考虑到服务器限制,集群拟定三个节点)
3、设置三台服务器并修改名称
XXX.XX.X.XXX node1
XXX.XX.X.XXX node2
XXX.XX.X.XXX node3
2、<!--[endif]-->加入集群三个节点的对应关系:
172.16.7.117 node1
172.16.7.132 node2
3、<!--[endif]-->安装erlang语言环境
Rpm Uvhhttp://www.rabbitmq.com/releases/erlang/erlang-18.1-1.el7.centos.x86_64.rpm
RabbitMQ节点之间和命令行工具(e.g.rabbitmqctl)是使用Cookie互通的,Cookie是一组随机的数字+字母的字符串。当rabbitmq服务器启动的时候,erlangVM会自动创建一个随机内容的Cookie文件。如果是通过源安装rabbitmq的话,erlang cookie文件在/var/lib/rabbitmq/.erlang.cookie。如果是通过源码安装的rabbitmq的话,erlang cookie文件在$HOME/.erlang.cookie
由于这个文件权限是400,所以需要修改node2、node3中该文件权限为777:
Chmod 777 .erlang.cookie
然后将文件复制到node2、node3上面
Node2:
Chmod 777 .erlang.cookie
Scp –r node1:/.erlang.cookie ~/
Node3:
Chmod 777 .erlang.cookie
Scp –r node1:/.erlang.cookie ~/
分别在node1、node2、node3将权限恢复过来:
Chmod 400 .erlang.cookie
5、下载rabbitMQ3.6.3
Wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.6.3/rabbitmq-server-generic-unix-3.6.3.tar.xz
Xz –d rabbitmq-server-generic-unix-3.6.3.tar.xz
Tar –xvf rabbitmq-server-generic-unix-3.6.3.tar
cd ./rabbitmq_server-3.6.3
cd sbin/
启用web管理界面
./rabbitmq-plugins enable rabbitmq_management
使用detached参数,在后台启动rabbit node
要先停止现有的rabbitmq-server 在重新再后台运行
./rabbitmqctl stop
./rabbitmq-server –detached
通过rabbitmqctl cluster_status命令,可以查看节点的状态
将node1、node2、node3组成集群
因为rabbitmq-server启动时,会一起启动节点和应用,它预先设置rabbitmq应用为standalone模式。要将一个节点加入到现有的集群中,需要停止这个应用并将节点设置为原始状态,然后就为加入集群准备好了。如果使用./rabbitmqctl stop,应用和节点都将被关闭。所以使用rabbitmqctl stop_app仅仅关闭应用。
Rabbitmqctl stop_app
Rabbitmqctl join_cluster rabbit@node1
Rabbitmqctl start_app
使用内存节点
Rabbitmqctl join_cluster --ram rabbit@node1
RabbitMQ镜像功能
在任意一个节点之下下面命令
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
将所有队列设置为镜像队列,即队列会被复制到各个节点,各个节点状态保持一致。<!--EndFragment-->
cd sbin/
启用web管理界面
./rabbitmq-plugins enable rabbitmq_management
启动
./rabbitmq-server start
因为rabbitmq默认账户guest不等在远程登录所以需要创建用户。
./rabbitmqctl add_user admin admin 前一个admin为账户,后一个admin为密码
设置权限
./rabbitmqctl set_user_tags admin administrator
访问ip:15672
Spring集成rabbitMQ
Maven依赖
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<import resource="classpath*:rabbitMq.xml" />
<!-- 扫描指定package下所有带有如@controller,@services,@resource,@ods并把所注释的注册为Spring Beans -->
<context:component-scan base-package="com.xin.consumer,com.xin.producer" />
<!-- 激活annotation功能 -->
<context:annotation-config />
<!-- 激活annotation功能 -->
<context:spring-configured />
</beans>
1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
4. xsi:schemaLocation="http://www.springframework.org/schema/beans
5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
6. http://www.springframework.org/schema/beans
7. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
8. http://www.springframework.org/schema/rabbit
9. http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd">
10. <!--配置connection-factory,指定连接rabbit server参数 -->
11. <rabbit:connection-factory id="connectionFactory"
12. username="guest" password="guest" host="localhost" port="5672" />
13.
14.
15. <!--direct 一对一传输-->
16. <!--定义rabbit template用于数据的接收和发送 -->
17. <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"
18. exchange="exchangeTest" />
19.
20. <!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
21. <rabbit:admin connection-factory="connectionFactory" />
22.
23. <!--定义queue -->
24. <rabbit:queue name="queueTest" durable="true" auto-delete="false" exclusive="false" />
25.
26. <!-- 定义direct exchange,绑定queueTest -->
27. <rabbit:direct-exchange name="exchangeTest" durable="true" auto-delete="false">
28. <rabbit:bindings>
29. <rabbit:binding queue="queueTest" key="queueTestKey"></rabbit:binding>
30. </rabbit:bindings>
31. </rabbit:direct-exchange>
32.
33.
34. <!-- 消息接收者 -->
35. <bean id="messageReceiver" class="com.xin.consumer.MessageConsumer"></bean>
36.
37. <!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象-->
38. <rabbit:listener-container connection-factory="connectionFactory">
39. <rabbit:listener queues="queueTest" ref="messageReceiver"/>
40. </rabbit:listener-container>
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52. <!--topic 匹配传输-->
53. <rabbit:template id="topicTemplate" connection-factory="connectionFactory"
54. exchange="topicExchange"/>
55.
56. <!--定义queue -->
57. <rabbit:queue name="topicQueue" durable="true" auto-delete="false" exclusive="false" />
58.
59. <!--topic交换器 pattern与topicTemplate.convertAndSend("foo.bar",message);第一个参数匹配-->
60. <rabbit:topic-exchange name="topicExchange">
61. <rabbit:bindings>
62. <rabbit:binding queue="topicQueue" pattern="info.*" />
63. </rabbit:bindings>
64. </rabbit:topic-exchange>
65.
66. <rabbit:listener-container connection-factory="connectionFactory">
67. <rabbit:listener ref="topic1" queues="topicQueue"/>
68. </rabbit:listener-container>
69.
70. <bean id="topic1" class="com.xin.consumer.TopicConsumer"/>
71.
72.
73.
74.
75.
76.
77.
78.
79. <!--fanout 把一条消息通过多条队列传输出去-->
80.
81. <rabbit:template id="fanoutTemplate" connection-factory="connectionFactory"
82. exchange="fanoutExchange"/>
83.
84. <!--定义queue -->
85. <rabbit:queue name="fanoutQueue" durable="true" auto-delete="false" exclusive="false" />
86. <rabbit:queue name="fanoutQueue2" durable="true" auto-delete="false" exclusive="false" />
87.
88. <!--topic交换器-->
89. <rabbit:fanout-exchange name="fanoutExchange">
90. <rabbit:bindings>
91. <rabbit:binding queue="fanoutQueue"></rabbit:binding>
92. <rabbit:binding queue="fanoutQueue2"></rabbit:binding>
93. </rabbit:bindings>
94. </rabbit:fanout-exchange>
95.
96. <rabbit:listener-container connection-factory="connectionFactory">
97. <rabbit:listener ref="fanoutConsumer" queues="fanoutQueue"/>
98. <rabbit:listener ref="fanoutConsumer2" method="foo" queues="fanoutQueue2"/>
99. </rabbit:listener-container>
<bean id="fanoutConsumer" class="com.xin.consumer.FanoutConsumer"/>
<bean id="fanoutConsumer2" class="com.xin.consumer.FanoutConsumer2"/>
</beans>
1. package com.xin.producer;
2.
3. import org.slf4j.Logger;
4. import org.slf4j.LoggerFactory;
5. import org.springframework.amqp.core.AmqpTemplate;
6. import org.springframework.stereotype.Service;
7.
8. import javax.annotation.Resource;
9.
10. /**
11. * Created by wuye on wuye on 2016/10/5 19:57
12. *
13. * @Description
14. */
15. @Service
16. public class MessageProducer {
17.
18. private Logger logger = LoggerFactory.getLogger(MessageProducer.class);
19.
20. @Resource
21. private AmqpTemplate amqpTemplate;
22.
23. public void sendMessage(Object message){
24. logger.info("to send message:{}",message);
25. amqpTemplate.convertAndSend("queueTestKey",message);
26. }
27. }
消费端:MessageConsumer
1. package com.xin.consumer;
2.
3. import com.xin.producer.MessageProducer;
4. import org.slf4j.Logger;
5. import org.slf4j.LoggerFactory;
6. import org.springframework.amqp.core.Message;
7. import org.springframework.amqp.core.MessageListener;
8. import org.springframework.context.support.AbstractApplicationContext;
9. import org.springframework.context.support.ClassPathXmlApplicationContext;
10.
11. /**
12. * Created by wuye on wuye on 2016/10/5 19:57
13. *
14. * @Description 消费接收
15. */
16. public class MessageConsumer implements MessageListener {
17.
18. private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);
19.
20. @Override
21. public void onMessage(Message message) {
22. logger.info("receive message:{}",message);
23. System.out.println(new String(message.getBody()));
24. }
25.
26. public static void main(final String... args) throws Exception {
27. AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
28. MessageProducer messageProducer = (MessageProducer) ctx.getBean("messageProducer");
29. messageProducer.sendMessage("-------------hello,3453465465467456456456^^^^^^66666!");
30. Thread.sleep(1000);
31. ctx.destroy();
32. }
33.
}
1. package com.xin.consumer;
2.
3. import com.xin.producer.MessageProducer;
4. import org.slf4j.Logger;
5. import org.slf4j.LoggerFactory;
6. import org.springframework.amqp.core.Message;
7. import org.springframework.amqp.core.MessageListener;
8. import org.springframework.context.support.AbstractApplicationContext;
9. import org.springframework.context.support.ClassPathXmlApplicationContext;
10.
11. /**
12. * Created by wuye on 2016/10/5 19:57
13. *
14. * @Description 消费接收
15. */
16. public class MessageConsumer implements MessageListener {
17.
18. private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);
19.
20. @Override
21. public void onMessage(Message message) {
22. logger.info("receive message:{}",message);
23. System.out.println(new String(message.getBody()));
24. }
25.
26. public static void main(final String... args) throws Exception {
27. AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
28. MessageProducer messageProducer = (MessageProducer) ctx.getBean("messageProducer");
29. messageProducer.sendMessage("-------------hello,xin3453465465467456456456^^^^^^66666!");
30. Thread.sleep(1000);
31. ctx.destroy();
32. }
33.
}