---------------------------RabbitMQ-----------------------------
一、RabbitMQ介绍
1、什么是MQ?
mq(message queue):消息队列,存储消息的容器
2、什么是AMQP?
AMQP(Advanced Message Queuing Protocol):高级消息队列协议,为消息中间件设计,
规定的接口:
connection:连接
channel:轻量级的connection
exchange:分发消息
queue:存储消息的容器
3、什么是RabbitMQ?
rabbitmq是erlang语言编写的实现AMQP协议的消息中间件
4、为什么要使用rabbitmq?
解耦:a服务本来只调用b、c服务,若添加d服务无需修改a服务的代码
异步:a服务把消息发送到mq,b、c服务接收消息后以异步的方式运行
削峰:按并发量慢慢拉取消息
5、rabbitmq的启动器
spring-boot-starter-amqp
二、RabbitMQ安装
1、安装erlang语言环境
cd /usr/upload
rpm -ivh esl-erlang-17.3-1.x86_64.rpm --force --nodeps
rpm -ivh esl-erlang_17.3-1~centos~6_amd64.rpm --force --nodeps
rpm -ivh esl-erlang-compat-R14B-1.el6.noarch.rpm --force --nodeps
2、安装rabbitmq
rpm -ivh rabbitmq-server-3.4.1-1.noarch.rpm
3、启动和关闭
service rabbitmq-server start
service rabbitmq-server stop
service rabbitmq-server restart
service rabbitmq-server status
chkconfig rabbitmq-server on
4、安装后台管理界面
rabbitmq-plugins enable rabbitmq_management
service rabbitmq-server restart
5、创建账户
rabbitmqctl add_user admin 1111
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
rabbitmqctl list_users
三、五种消息模型
1、simple消息模型
producer-------------------->|queue|---------------->consumer
手动ack:
channel.basicConsume(, false, );//不自动ack
try {
//业务逻辑
channel.basicAck(envelope.getDeliveryTag(), false);//手动ack
}catch (Exception e){
e.printStackTrace();
}
问题:如何保证消费者把消息成功消费?手动ack(理论)
2、work消息模型
producer-------------------->|queue|---------------->多consumer
能者多劳:
channel.basicQos(1);
问题:如何防止消息堆积?能者多劳+多consumer
3、fanout消息模型
bind
producer------------->exchange---------------->|多queue|---------------->多consumer
注意:exchange只负责分发消息,若没有queue绑定到exchange则消息会被丢弃
4、direct消息模型
bind(routingkey)
producer------------->exchange-------------------->|多queue|---------------->多consumer
routingkey:灵活控制消息分发
5、topic消息模型
bind(#.routingkey.*)
producer------------->exchange------------------------>|多queue|---------------->多consumer
通配符:
#:匹配n个单词
*:匹配1个单词
四、持久化
1、exchange:
channel.exchangeDeclare(, , true);
2、queue:
channel.queueDeclare(, true, , , );
3、消息:
channel.basicPublish(, , MessageProperties.PERSISTENT_TEXT_PLAIN, );
问题:如何保证消费者把消息成功消费(理论)?
1、consumer业务会处理失败?
手动ack
2、RabbitMQ会宕机?
持久化
五、springboot整合rabbitmq
1、pom.xml
spring-boot-starter-amqp
2、application.yml
spring:
rabbitmq:
host: 192.168.204.135
port: 5672
username: admin
password: 1111
virtual-host: /
3、Recver
@Component
public class Recver {
/**
* 接收消息的三要素:
* 1、queue
* 2、exchange
* 3、routingkey
*/
@RabbitListener(bindings={@QueueBinding(
value=@Queue(value = "springboot_queue"),
exchange=@Exchange(value = "springboot_exchange", type = ExchangeTypes.TOPIC),
key={"item.*"}
)})
public void listenMsg(String msg){
System.out.println("Recver:" + msg);
}
}
4、Sender
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {SpringbootRabbitMQ.class})
public class Sender {
@Autowired
private AmqpTemplate amqpTemplate;
@Test
public void sendMsg() throws InterruptedException {
String msg = "师姐你好!!!";
amqpTemplate.convertAndSend("springboot_exchange", "item.add", msg);
System.out.println("Sender:" + msg);
Thread.sleep(10000);
}
}
5、手动ack
1)application.yml
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: manual #前两种消息模型不自动ack
direct:
acknowledge-mode: manual #后三种消息模型不自动ack
2)Recver
public void listenMsg(, Channel channel, Message message){
try {
//业务逻辑
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}catch (Exception e){
e.printStackTrace();
}
}