这是我参与「第五届青训营」伴学笔记创作活动的第13天。
前言
消息队列是在微服务架构中起到非常重要的作用的一个中间件。我们已经了解了服务与服务之间需要通信,而消息队列就是为了解决服务通信之间的问题而出现的,但它的特性也使得它的应用场景非常广泛,下面就在这篇笔记中简单记录下。
笔记内容
1.定义
首先,消息队列的字面意思就是存放消息的队列。先跳过字面意思,我们首先了解一下同步通讯和异步通讯,举个简单的例子,同步通讯就好比在同一时刻有三个人给你发消息,但你此时只回复一个人并与他聊了起来;而异步通讯则是你同时给三个人发消息,并收到了他们的回复。微服务间基于Feign的调用就属于同步方式,但这显然会造成一些问题,如:级联失败、资源浪费、性能下降等;于是就出现了异步调用,比较常见的实现就是事件驱动模式,类比前面我举的发消息的例子。
在了解了同步通讯与异步通讯后,我们对消息队列也就有了一个基本的认识,他就是事件驱动架构中的消息管理者,这里的事情则就可以理解为具体的请求,根据请求调用相关的服务。
2.消息队列实践
2-1.RabbitMQ
虽然今天青训营的课程讲了三个消息队列,我也都有了解,但笔记还是记录自己用过的,它主要由四部分组成:①producer:生产者,消息的生产者;②exchange: 交换器,关键组件,灵活性所在;③Queue:队列;④Consumer:消费者 ,处理生产者通过queue发来的消息。其实可以看出来,它的设计思想和RPC服务框架类似,这也可以说得通,毕竟都是在分布式系统中使用。
消息发送流程:①建立connection;②创建channel;③利用channel声明队列;④利用channel向队列发送消息。
消息接收流程:①建立connection;②创建channel;③利用channel声明队列;④定义consumer的消费行为handleDelivery();⑤利用channel将消费者与队列绑定。
这里需要注意的是:消息一旦消费就会从队列删除,RabbitMQ没有消息回溯功能
2-2.SpringAMQP
基于AMQP协议的一套API规范,AMQP协议是应用间消息通信的一种协议,与语言和平台无关。
消息发送流程:①引入amqp的starter依赖;②配置RabbitMQ地址;③利用RabbitTemplate的convertAndSend方法。
消息接收流程:①引入amqp的starter依赖;②配置RabbitMQ地址;③定义类,添加@Component注解;④类中声明方法,添加@RabbitListener注解,方法参数就时消息。
3.简单的消息队列入门案例
1.引入依赖:
<!--AMQP依赖,包含RabbitMQ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>`
2.在生产者服务中编写配置文件,添加MQ的连接信息:
spring:
rabbitmq:
host: 192.168.132.100 #主机名
port: 5672 #端口
virtual-host: / #虚拟主机
username: pitayafruit #用户名
password: 123456 #密码
3.在生产者服务中新建一个测试类,编写测试方法:
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSimpleQueue() {
String queueName = "simple.queue";
String message = "hello, spring amqp!";
rabbitTemplate.convertAndSend(queueName, message);
}
}
4.在消费者服务中编写配置文件,添加MQ连接信息:
spring:
rabbitmq:
host: 192.168.132.100 #主机名
port: 5672 #端口
virtual-host: / #虚拟主机
username: pitayafruit #用户名
password: 123456 #密码
5.在消费者服务中新建一个类,编写消费逻辑:
@Component
public class SpringRabbitListener {
@RabbitListener(queues = "simple.queue")
public void listenSimpleQueueMessage(String msg) throws InterruptedException {
System.out.println("spring 消费者接收到消息:" + msg);
}
}
小结
消息队列在实际使用时功能更加丰富,比如使用work模型让多消费者绑定时的指定发送、消费者接收消息数量等、发布订阅模式的使用实现推送,这些都需要我们根据具体的业务需求再做细化,这篇笔记仅仅只是对消息队列的入门。