20.1 RabbitMq介绍
20.1.1 是什么
MQ全称为Message Queue,即消息队列. 它也是一个队列,遵循FIFO原则 。RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue protoctl 高级消息队列协议)协议实现的消息队列,它是一种应用程序之间的通信方法,消息队列在分布式系统开 发中应用非常广泛。官方地址:http://www.rabbitmq.com/
20.1.2 使用场景
-
提高系统响应速度
任务异步处理。 将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理。 提高了应用程序的响应时间。
-
提高系统稳定性
系统挂了关系,操作内容放到消息队列.
-
服务调用异步化
服务没有直接的调用关系,而是通过队列进行服务通信
-
服务解耦
应用程序解耦合 MQ相当于一个中介,生产方通过MQ与消费方交互,它将应用程序进行解耦合。
-
排序保证 FIFO
遵循队列先进先出的特点
-
消除峰值
20.1.3 常见mq
ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。
20.1.4 AMQP协议
AMQP是什么 ?
AMQP是一套公开的消息队列协议,最早在2003年被提出,它旨在从协议层定义消息通信数据的标准格式, 为的就是解决MQ市场上协议不统一的问题。RabbitMQ就是遵循AMQP标准协议开发的MQ服务。 官方:http://www.amqp.org
JMS是什么 ?
JMS是Java消息服务,是java提供的一套消息服务API标准,其目的是为所有的java应用程序提供统一的消息通信的标准,类似java的 jdbc,只要遵循jms标准的应用程序之间都可以进行消息通信。它和AMQP有什么 不同,jms是java语言专属的消 息服务标准,它是在api层定义标准,并且只能用于java应用;而AMQP是在协议层定义的标准,是跨语言的 。
20.1.5 为什么需用RabbitMQ
1、使得简单,功能强大。
2、基于AMQP协议。
3、社区活跃,文档完善。
4、高并发性能好,这主要得益于Erlang语言。
5、Spring Boot默认已集成RabbitMQ
20.2 安装RabbitMQ
RabbitMQ由Erlang语言开发,Erlang语言用于并发及分布式系统的开发,在电信领域应用广泛,OTP(Open Telecom Platform)作为Erlang语言的一部分,包含了很多基于Erlang开发的中间件及工具库,安装RabbitMQ需要安装Erlang/OTP,并保持版本匹配,如下图:
本项目使用Erlang/OTP 20.3版本和RabbitMQ3.7.3版本。
20.2.1 安装Erlang
地址:http://erlang.org/download/otp_win64_20.3.exe 或去老师提供的软件包中找到 otp_win64_20.3.exe,以管理员方式运行此文件,安装。
erlang安装完成需要配置erlang环境变量:ERLANG_HOME=D:\Program Files\erl9.3 在path中添 加 D:\Program Files\erl9.3\bin\
20.2.2 安装RabbitMQ
地址:https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.7.3 或去老师提供的软件包中找到 rabbitmq-server-3.7.3.exe,以管理员方式运行此文件,安装。
20.2.3 安装管理插件
安装rabbitMQ的管理插件,方便在浏览器端管理RabbitMQ ,进入到Rabbit的sbin目录,使用cmd执行命令: rabbitmq-plugins.bat enable rabbitmq_management , 安装成功后重新RabbitMQ
20.2.4 启动RabbitMQ
直接在服务中完成启动
20.2.5 登录RabbitMQ
进入浏览器,输入:http://localhost:15672 ,初始账号和密码:guest/guest
20.3 springboot 集成rabbitmq
我们选择基于Spring-Rabbit去操作RabbitMQ
https://github.com/spring-projects/spring-amqp 使用spring-boot-starter-amqp会自动添加spring-rabbit依赖,具体步骤如下:
步骤分析:
1 准备一个springboot项目
2 在springboot中导入rabbitmq的strarter
3 application.yml中进行配置
4 写代码测试
20.3.1 准备一个springboot项目
略过
20.3.2 springboot中导入spring data elasticsearch的strarter
<!--spirngboot集成rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
20.3.3 application.yml中进行配置
spring:
application:
name: test‐rabbitmq‐producer
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
virtualHost: /
20.3.4 写代码测试
配置类
package org.yaosang.config;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitmqConfig {
public static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
public static final String QUEUE_INFORM_SMS = "queue_inform_sms";
public static final String EXCHANGE_TOPICS_INFORM = "exchange_topics_inform";
/**
* 交换机配置
* ExchangeBuilder提供了fanout、direct、topic、header交换机类型的配置
*
* @return the exchange
*/
@Bean(EXCHANGE_TOPICS_INFORM)
public Exchange EXCHANGE_TOPICS_INFORM() {
//durable(true)持久化,消息队列重启后交换机仍然存在
return ExchangeBuilder.topicExchange(EXCHANGE_TOPICS_INFORM).durable(true).build();
}
//声明队列
@Bean(QUEUE_INFORM_SMS)
public Queue QUEUE_INFORM_SMS() {
Queue queue = new Queue(QUEUE_INFORM_SMS,true);
return queue;
}
//声明队列
@Bean(QUEUE_INFORM_EMAIL)
public Queue QUEUE_INFORM_EMAIL() {
Queue queue = new Queue(QUEUE_INFORM_EMAIL,true);
return queue;
}
/**
* channel.queueBind(INFORM_QUEUE_SMS,"inform_exchange_topic","inform.#.sms.#");
* 绑定队列到交换机 .
*
* @param queue the queue
* @param exchange the exchange
* @return the binding
*/
@Bean
public Binding BINDING_QUEUE_INFORM_SMS(@Qualifier(QUEUE_INFORM_SMS) Queue queue,
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("inform.#.sms.#").noargs();
}
@Bean
public Binding BINDING_QUEUE_INFORM_EMAIL(@Qualifier(QUEUE_INFORM_EMAIL) Queue queue,
@Qualifier(EXCHANGE_TOPICS_INFORM) Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("inform.#.email.#").noargs();
}
}
20.3.4.1 生产者实现
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest(classes = App.class)
@RunWith(SpringRunner.class)
public class Producer05_topics_springboot {
@Autowired
RabbitTemplate rabbitTemplate;
@Test
public void testSendByTopics() {
for (int i = 0; i < 5; i++) {
String message = "sms email inform to user" + i;
rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_TOPICS_INFORM, "inform.sms.email", message);
System.out.println("Send Message is:'" + message + "'");
}
}
}
20.3.4.2 消费者实现
@Component
public class ReceiveHandler {
//监听email队列
@RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_EMAIL})
public void receive_email(String msg, Message message, Channel channel) {
System.out.println(msg);
}
//监听sms队列
@RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_SMS})
public void receive_sms(String msg, Message message, Channel channel) {
System.out.println(msg);
}
}
20.3.4.3 测试
- 启动项目-此时消费者就OK
- 通过测试的方式发送消息
- 查看消费者是否接收到消息
20.4 小结
本章节讲解了springboot中怎么使用rabbitmq