本文已参与「新人创作礼」活动,一起开启掘金创作之路
引言
在开发过程中常常使用到消息中间件。消息中间件主要有三个优点:1、解耦 2、异步操作 3、流量削峰。简单的来描述下他们的信息。
第一点解耦,我们在写代码中经常提到的就是解耦,这个举个例子,A系统和B系统直接有数据交互,需要通过接口进行调用。后续有加入了其它系统,如果只是通过代码直接编写调用,那系统之间的逻辑就之间相互关联,加入的系统越多,关系网就越复杂,一旦需求发生变动,代码处理上就要考虑很多。如果我们通过消息队列来进行数据交互,那么两个系统之间没有了直接的逻辑关系,能避免需求变动时带来的麻烦。
第二点异步操作。比较常见的例子就是,如我们的注册中间需要提供邮箱和短信的消息提醒,由于注册时本身还有进行注册相关的业务处理,当完成数据库写入用户注册信息后,再发送邮件,发送短信,最终返回用户注册成功的提示信息,整个的链路会很长,耗时情况也不理想。所以针对这种可以通过消息队列将不是主要的业务流用消息分发出去做处理。这样在用户信息写入数据库后就可以直接返回信息给用户了,邮件和短信可以通过消息队列做处理。或许会有疑问,这种能否直接用异步方法做替代,比如spring中使用@Async去标记一个异步方法,但是消息队列带有手动确认和重试机制,相比于一个简单的异步方法提供了更加稳健的解决方案。
第三点流量削峰,秒杀抢购活动中会出现瞬时的高流量,一万人抢购一百件商品,绝大部分是抢购失败的。大流量如果直接进入数据库,会对数据库造成不小的压力。基于消息队列本身采用了队列这种先进先出的数据结构,可以很好契合秒杀下单这种操作,同时提供了一个缓冲的环境,将请求有序的缓存起来,很好的保护了系统。
如果是Java开发的话,一般可选的消息队列有kafka mq、rabbit mq、rocket mq,我用过后面两个,单纯从使用上说的话,我个人觉得rabbit mq还是比较不错的,rocket mq虽然在代码使用上也比较方便,但是在可视化控制台上不够直观,相对于rabbit mq的可视化控制台,rocket mq的我是觉得比较难用的。
rabbit mq的官网文档是比较详细的,安装第一次可能会比较繁琐,需要先装erlang环境,后面只要照着文档基本也没有什么难点。我觉得第一次不管是windows还是linux都可以先用安装包的方式安装一遍,后续如果是自己个人开发学习我觉得用docker来安装部署是个很好的选择。
整合入门
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
首先整合需要加入这个依赖,然后在spring的yml配置文件的spring目录下加入下面的配置文件
rabbitmq:
host: 127.0.0.1
username: dev
password: dev
virtual-host: /dev
port: 5672
listener:
simple:
retry:
enabled: true
#最大重试次数
max-attempts: 3
#乘子
multiplier: 2
#初始化重试间隔
initial-interval: 3000
#最大重试间隔
max-interval: 30000
这里主要配置了rabbit mq运行的主机地址,登录的用户名密码,virtual-host是虚拟主机的路径默认为/,可以认为是个工作空间,有点类似于我们spring 配置的context path。然后是端口默认是5672.后面是一个重试机制,设置最大重试3次,第一次的重试间隔为3s第二次为6s,最大不超过30s的间隔。
创建一个配置类
@Data
@Component
@ConfigurationProperties(prefix = "spring.rabbitmq")
public class RabbitMqConfiguration {
private String host;
private Integer port;
private String username;
private String password;
private String virtualHost;
@Bean
public CachingConnectionFactory connectionFactory(){
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
cachingConnectionFactory.setHost(host);
cachingConnectionFactory.setPort(port);
cachingConnectionFactory.setUsername(username);
cachingConnectionFactory.setPassword(password);
cachingConnectionFactory.setVirtualHost(virtualHost);
return cachingConnectionFactory;
}
@Bean
public RabbitTemplate rabbitTemplate(){
RabbitTemplate rabbitTemplate = new RabbitTemplate();
rabbitTemplate.setConnectionFactory(connectionFactory());
return rabbitTemplate;
}
}
这里主要是读取了我们配置文件中的配置,将它注入到rabbitTemplate中,并把这个对象作为一个spring容器。然后启动spring boot
可以看到控制台的日志输出,连接了本地的5672端口,在/dev虚拟主机上建立了连接,这样说明我们spring boot整合rabbit mq成功了
并且我们在浏览器中,打开127.0.0.1:15672(前提是rabbit mq安装激活了控制台插件)
控制台打开输入之前的用户名密码就可以登录,在右上角有用户和虚拟主机信息,可以看到我们的spring boot服务和消息队列主机已经连接上了,这样整个框架的整合就成功了