概述
上一篇中我们已经成功将spring boot和rabbit mq整合成功了,现在我们来进行一些入门案例。rabbit mq的文档在一众技术文档中是属于比较清晰的,算是手摸手教学了,下面是第一个例子
开始实战
首先我们简单理清楚三个概念,1、生产者 2、消息队列 3、消费者
生产者指的就是发送消息的一方,在代码中就是使用rabbitTemplate调用方法的一方。
消息队列,我们可以认为是一块消息的缓冲区,拥有先进先出的特点,一个队列可以连接多个生产者和多个消费者。
消费者,接收消息队列中的消息。
了解了这三个就可以编写代码了。代码和我们的业务息息相关,我们举个例子,路人甲需要寄一个东西给路人乙,但是甲很忙不能亲自送,所以找了配送员做配送。
首先我们创建一个接口ProducerService便于后面做单元测试,创建一个方法,它接收字符串消息。
void sendSimpleMessage(String message);
然后我们创建这个接口的实现类,这个就是生产者也就是我们的路人甲。
@Autowired
private RabbitTemplate rabbitTemplate;
@Override
public void sendSimpleMessage(String message) {
LocalDateTime now = LocalDateTime.now();
log.info("producer simple msg:[{}]",now.toString());
rabbitTemplate.convertAndSend(SimpleQueueConfig.QUEUE_NAME,message);
log.info("send simple msg:[{}]",message);
}
我们在里面打印发送的时间,convertAndSend这里这个方法接收了两个参数一个是路由键也是我们队列的名字,可以说是我们这个配送员的编号。
@Slf4j
@RabbitListener(queues = "simple")
public class SimpleListener {
@RabbitHandler
public void receive(String msg){
log.info("simple receive msg:[{}]",msg);
}
}
然后我们创建一个消费者(监听者),这里在注解上添加队列名称,标识监听这个队列。就如同我们的路人甲告诉路人乙,东西交给了编号123的配送员,那路人乙就会等这个编号123的人来送东西。完成生产者和消费者的创建之后还需要创建队列。我们创建一个配置类,因为它在服务启动时就需要把队列给创建好。
@Configuration
public class SimpleQueueConfig {
public static final String QUEUE_NAME = "simple";
@Bean
public Queue simple(){
return new Queue(QUEUE_NAME);
}
@Bean
public SimpleListener simpleListener(){
return new SimpleListener();
}
}
这里将队列和消费者都注册到了spring 容器中。
好了我们来看下效果,我们首先启动之前的spring boot工程,这样等于消费者已经在监听了。
@Test
void sendSimpleMessage() {
String msg = "京东快递";
producerService.sendSimpleMessage(msg);
}
写一个单元测试,然后调用我们生产者的方法。首先控制台上已经有了显示,说明消息成功发送并被接收消费。
2021-05-09 19:22:12.734 INFO 8520 --- [ main] c.z.s.service.impl.ProducerServiceImpl : producer simple msg:[2021-05-09T19:22:12.733]
2021-05-09 19:22:12.741 INFO 8520 --- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: 127.0.0.1:5672
2021-05-09 19:22:12.759 INFO 8520 --- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: SpringAMQP#63bca84d:0/SimpleConnection@7f2ca6f8 [delegate=amqp://dev@127.0.0.1:5672//dev, localPort= 50543]
2021-05-09 19:22:12.761 INFO 8520 --- [ main] c.z.s.service.impl.ProducerServiceImpl : send simple msg:[京东快递]
这个时生产者的日志看到,成功将消息投递出去了
2021-05-09 19:22:12.776 INFO 7040 --- [ntContainer#5-1] c.z.s.service.listener.SimpleListener : simple receive msg:[京东快递]
这个时消费者的日志可以看到,消费者成功接收了消息。
到此小白入门的第一步就完成了。
然后我们再复杂一点,我们知道nginx有负载均衡的策略,同样rabbit mq中也有这种机制。我们举个例子双十一快递爆仓,上游有十万个快递到了仓库需要分拣打包,路人甲一个人忙不过来,就找了好朋友路人乙两个人一起,他们商量着一人一半进行打包。
我们接着上面的代码,在基础上增加一个消费者。队列名称不变。
public class SimpleListener2 {
@RabbitListener(queues = "simple")
public void receive(String msg){
log.info("simple2 receive msg:[{}]",msg);
}
}
同样在之前的配置类中加入这个消费者
@Bean
public SimpleListener2 simpleListener2(){
return new SimpleListener2();
}
好了重启我们的spring boot让配置生效。我们刷新控制台可以看到有两个消费者监听了这个队列
好我们重写一个单元测试方法,总共发送10个邮件带有编号。启动单元测试
@Test
void workSend(){
int total = 10;
for(int i = 0;i< total;i++){
String msg = "邮件-"+i;
producerService.sendSimpleMessage(msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2021-05-09 19:49:06.575 INFO 7040 --- [ntContainer#4-1] c.z.s.service.listener.SimpleListener : simple receive msg:[邮件-0]
2021-05-09 19:49:07.586 INFO 7040 --- [ntContainer#5-1] c.z.s.service.listener.SimpleListener2 : simple2 receive msg:[邮件-1]
2021-05-09 19:49:08.647 INFO 2416 --- [ntContainer#4-1] c.z.s.service.listener.SimpleListener : simple receive msg:[邮件-2]
2021-05-09 19:49:09.590 INFO 2416 --- [ntContainer#5-1] c.z.s.service.listener.SimpleListener2 : simple2 receive msg:[邮件-3]
2021-05-09 19:49:10.606 INFO 7040 --- [ntContainer#4-1] c.z.s.service.listener.SimpleListener : simple receive msg:[邮件-4]
2021-05-09 19:49:11.621 INFO 7040 --- [ntContainer#5-1] c.z.s.service.listener.SimpleListener2 : simple2 receive msg:[邮件-5]
2021-05-09 19:49:12.628 INFO 2416 --- [ntContainer#4-1] c.z.s.service.listener.SimpleListener : simple receive msg:[邮件-6]
2021-05-09 19:49:13.632 INFO 2416 --- [ntContainer#5-1] c.z.s.service.listener.SimpleListener2 : simple2 receive msg:[邮件-7]
2021-05-09 19:49:14.637 INFO 7040 --- [ntContainer#4-1] c.z.s.service.listener.SimpleListener : simple receive msg:[邮件-8]
2021-05-09 19:49:15.653 INFO 7040 --- [ntContainer#5-1] c.z.s.service.listener.SimpleListener2 : simple2 receive msg:[邮件-9]
可以看到两个消费者时轮询接收了消息,这是因为默认当多个消费者监听同一个队列时是使用的平均分配的规则。
这样对于rabbit mq的简单使用我们就已经学会了