下载安装Erlang和RabbitMQ

Erlang和RabbitMQ:https://www.cnblogs.com/theRhyme/p/10069611.html

AMQP协议详解与RABBITMQ,MQ消息队列的应用场景,如何避免消息丢失

https://www.cnblogs.com/theRhyme/p/9578675.html

项目创建和依赖

推荐SpringCloud项目在线创建:https://start.spring.io/

不用上面这个也行,下面有代码和依赖;

gradle的依赖,和maven差不多:

  1. buildscript {
  2. ext {
  3. springBootVersion = '2.1.1.RELEASE'
  4. }
  5. repositories {
  6. mavenCentral()
  7. }
  8. dependencies {
  9. classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
  10. }
  11. }
  12.  
  13. apply plugin: 'java'
  14. apply plugin: 'eclipse'
  15. apply plugin: 'org.springframework.boot'
  16. apply plugin: 'io.spring.dependency-management'
  17.  
  18. group = 'xy.study'
  19. version = '0.0.1-SNAPSHOT'
  20. sourceCompatibility = 1.8
  21.  
  22. repositories {
  23. mavenCentral()
  24. }
  25.  
  26. dependencies {
  27. implementation('org.springframework.boot:spring-boot-starter-amqp')
  28. implementation('org.projectlombok:lombok:1.16.+')
  29. runtimeOnly('org.springframework.boot:spring-boot-devtools')
  30. testImplementation('org.springframework.boot:spring-boot-starter-test')
  31. }

代码

配置文件application.properties

  1. spring.application.name=spring-boot-rabbitmq
  2.  
  3. spring.rabbitmq.host=localhost
  4. spring.rabbitmq.port=5672
  5. spring.rabbitmq.username=guest
  6. spring.rabbitmq.password=guest
  7.  
  8. server.port = 5678

RabbitMQ配置文件类(注释的代码可以直接删掉):

  1. import org.springframework.amqp.core.Binding;
  2. import org.springframework.amqp.core.BindingBuilder;
  3. import org.springframework.amqp.core.Queue;
  4. import org.springframework.amqp.core.TopicExchange;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7.  
  8. /**
  9. * topic 是RabbitMQ中最灵活的一种方式,可以根据routing_key自由的绑定不同的队列
  10. * 首先对topic规则配置
  11. */
  12. //@Configuration
  13. public class TopicRabbitConfig {
  14.  
  15. final public static String QUEUE_NAME = "queue.name";
  16. final public static String TEST_TOPIC_ROUTINGKEY = "test.topic.routingKey";
  17. final public static String TEST_EXCHANGE_HAHA = "test.exchange.haha";
  18.  
  19. /**
  20. * 设置交换器的名称
  21. * @return
  22. *//*
  23. @Bean
  24. TopicExchange exchange() {
  25. return new TopicExchange(TopicRabbitConfig.TEST_EXCHANGE_HAHA);
  26. }
  27.  
  28. *//**
  29. * 队列名称
  30. * @return
  31. *//*
  32. @Bean
  33. public Queue queueMessage() {
  34. return new Queue(TopicRabbitConfig.QUEUE_NAME);
  35. }
  36.  
  37. *//**
  38. * 将指定routing key的名称绑定交换器的队列
  39. * @param queueMessage
  40. * @param exchange
  41. * @return
  42. *//*
  43. @Bean
  44. Binding bindingExchangeMessage(Queue queueMessage, TopicExchange exchange) {
  45. return BindingBuilder.bind(queueMessage).to(exchange).with(TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY);
  46. }*/
  47.  
  48. /**
  49. * 匹配以topic开头的路由键routing key
  50. * 交换机绑定多个队列
  51. */
  52.  
  53. /*@Bean
  54. Binding bindingExchangeMessages(Queue queueMessages, TopicExchange exchange) {
  55. return BindingBuilder.bind(queueMessages).to(exchange).with("topic.#");
  56. }*/
  57. }

生产者,这里根据Exchange和Routing Key,直接发送一个字符串:

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.springframework.amqp.rabbit.core.RabbitTemplate;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.stereotype.Component;
  5. import xy.study.rabbitmq.conf.TopicRabbitConfig;
  6.  
  7. @Component
  8. @Slf4j
  9. public class HelloSender {
  10.  
  11. @Autowired
  12. private RabbitTemplate rabbitTemplate;
  13.  
  14. /**
  15. * 通过exchange和routingKey的方式
  16. * rabbitTemplate.convertAndSend(String exchange, String routingKey, Object object)
  17. * @param i
  18. */
  19. public void send(int i) {
  20. String context = "hello " + i;
  21. log.info("Sender : {}", context);
  22. this.rabbitTemplate.convertAndSend(TopicRabbitConfig.TEST_EXCHANGE_HAHA,TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY, context);
  23. }
  24. }

消费者,绑定对应的Exchange,Queue和Routing Key,直接打印获取的信息:

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.springframework.amqp.core.ExchangeTypes;
  3. import org.springframework.amqp.rabbit.annotation.Exchange;
  4. import org.springframework.amqp.rabbit.annotation.Queue;
  5. import org.springframework.amqp.rabbit.annotation.QueueBinding;
  6. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  7. import org.springframework.messaging.handler.annotation.Payload;
  8. import org.springframework.stereotype.Component;
  9. import xy.study.rabbitmq.conf.TopicRabbitConfig;
  10.  
  11. @Component
  12. @Slf4j
  13. public class HelloReceiver {
  14. @RabbitListener(bindings = @QueueBinding(
  15. value = @Queue(value = TopicRabbitConfig.QUEUE_NAME, durable = "true"),
  16. exchange = @Exchange(value = TopicRabbitConfig.TEST_EXCHANGE_HAHA, type = ExchangeTypes.TOPIC),
  17. key = TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY)
  18. )
  19. public void onOrgDeleted(@Payload String msg) {
  20. log.info("HelloReceiver msg : {}",msg);
  21. }
  22. }

测试类,调用生产者发送信息的函数send,消费者会监听消费:

  1. import org.junit.Test;
  2. import org.junit.runner.RunWith;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import org.springframework.test.context.junit4.SpringRunner;
  6. import xy.study.rabbitmq.producer.HelloSender;
  7.  
  8. @RunWith(SpringRunner.class)
  9. @SpringBootTest
  10. public class RabbitmqApplicationTests {
  11.  
  12. @Autowired
  13. private HelloSender sender;
  14.  
  15. @Test
  16. public void testSend() {
  17. sender.send(666);
  18. }
  19.  
  20. }

如图,控制台日志,能生成消息,并且能被对应的消费者消费。

topic exchange 通配路由中多个消费者的情况

修改消费者的代码如下:

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.springframework.amqp.core.ExchangeTypes;
  3. import org.springframework.amqp.rabbit.annotation.Exchange;
  4. import org.springframework.amqp.rabbit.annotation.Queue;
  5. import org.springframework.amqp.rabbit.annotation.QueueBinding;
  6. import org.springframework.amqp.rabbit.annotation.RabbitListener;
  7. import org.springframework.messaging.handler.annotation.Payload;
  8. import org.springframework.stereotype.Component;
  9. import xy.study.rabbitmq.conf.TopicRabbitConfig;
  10.  
  11. @Component
  12. @Slf4j
  13. public class HelloReceiver {
  14.  
  15. /**
  16. * 下面四个消费者,exchange和RoutingKey都相同,最后两个消费者队列名都相同
  17. * @param msg
  18. */
  19. @RabbitListener(bindings = @QueueBinding(
  20. value = @Queue(value = TopicRabbitConfig.QUEUE_NAME, durable = "true"),
  21. exchange = @Exchange(value = TopicRabbitConfig.TEST_EXCHANGE_HAHA, type = ExchangeTypes.TOPIC),
  22. key = TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY)
  23. )
  24. public void queueName(@Payload String msg) {
  25. log.info("{}-----HelloReceiver msg : {}",TopicRabbitConfig.QUEUE_NAME,msg);
  26. }
  27.  
  28. @RabbitListener(bindings = @QueueBinding(
  29. value = @Queue(value = TopicRabbitConfig.QUEUE_NAME+".test", durable = "true"),
  30. exchange = @Exchange(value = TopicRabbitConfig.TEST_EXCHANGE_HAHA, type = ExchangeTypes.TOPIC),
  31. key = TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY)
  32. )
  33. public void queueNameTest(@Payload String msg) {
  34. log.info("{}-----HelloReceiver msg : {}",TopicRabbitConfig.QUEUE_NAME+".test",msg);
  35. }
  36.  
  37. /**
  38. * 这里我的消费者队列名"123445",是乱写的,也能够接受
  39. * @param msg
  40. */
  41. @RabbitListener(bindings = @QueueBinding(
  42. value = @Queue(value = 123445+"", durable = "true"),
  43. exchange = @Exchange(value = TopicRabbitConfig.TEST_EXCHANGE_HAHA, type = ExchangeTypes.TOPIC),
  44. key = TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY)
  45. )
  46. public void queueNameNumber(@Payload String msg) {
  47. log.info("{}-----HelloReceiver msg : {}",123445+""+".test",msg);
  48. }
  49.  
  50. /**
  51. * 由于这个和上面的Exchange、RoutingKey、queue完全相同,所以这两个消费者,一条消息,只有一个能消费(随机)
  52. * @param msg
  53. */
  54. @RabbitListener(bindings = @QueueBinding(
  55. value = @Queue(value = 123445+"", durable = "true"),
  56. exchange = @Exchange(value = TopicRabbitConfig.TEST_EXCHANGE_HAHA, type = ExchangeTypes.TOPIC),
  57. key = TopicRabbitConfig.TEST_TOPIC_ROUTINGKEY)
  58. )
  59. public void queueNameNumberSame(@Payload String msg) {
  60. log.info("same+{}-----HelloReceiver msg : {}",123445+""+".test",msg);
  61. }
  62. }

再次执行测试,测试结果如下:

上面四个消费者代码,Exchange和RoutingKey都相同,最后两个消费者队列名都相同。

根据结果可知,当Exchange和RoutingKey相同、queue不同时,所有消费者都能消费同样的信息;

当Exchange和RoutingKey、queue都相同时(最后两个消费者),消费者中只有一个能消费信息,其他消费者都不能消费该信息。

SpringBoot整合RabbitMQ,实现消息发送和消费以及多个消费者的情况的更多相关文章

  1. SpringBoot 整合 RabbitMQ 实现消息可靠传输

    消息的可靠传输是面试必问的问题之一,保证消息的可靠传输主要在生产端开启 comfirm 模式,RabbitMQ 开启持久化,消费端关闭自动 ack 模式. 环境配置 SpringBoot 整合 Rab ...

  2. springboot整合rabbitmq,支持消息确认机制

    安装 推荐一篇博客https://blog.csdn.net/zhuzhezhuzhe1/article/details/80464291 项目结构 POM.XML <?xml version= ...

  3. springboot整合rabbitMq实现消息延时发送

    实现思路:利用mq的ttl设置消息失效时间 当达到设置时间后通过交换机到达死信队列中,消费者端绑定读取死信队列中信息来达到延时发送消息的功能. demo 如下: (1)在pom.xml 中引入rabb ...

  4. SpringBoot整合Rabbitmq设置消息请求头

    String str = "{\"origin\":\"BBC\",\"origin_coupon_id\":51,\" ...

  5. SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 整合消息服务 2.具体内容 对于异步消息组件在实际的应用之中会有两类: · JMS:代表作就是 ...

  6. springboot整合rabbitmq实现生产者消息确认、死信交换器、未路由到队列的消息

    在上篇文章  springboot 整合 rabbitmq 中,我们实现了springboot 和rabbitmq的简单整合,这篇文章主要是对上篇文章功能的增强,主要完成如下功能. 需求: 生产者在启 ...

  7. springboot学习笔记-6 springboot整合RabbitMQ

    一 RabbitMQ的介绍 RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿 ...

  8. 一篇学习完rabbitmq基础知识,springboot整合rabbitmq

    一   rabbitmq 介绍 MQ全称为Message Queue,即消息队列, RabbitMQ是由erlang语言开发,基于AMQP(Advanced MessageQueue 高级消息队列协议 ...

  9. 【MQ中间件】RabbitMQ -- SpringBoot整合RabbitMQ(3)

    1.前言说明 前面一篇博客中提到了使用原生java代码进行测试RabbitMQ实现多种交换机类型的队列场景.但是在项目中我们一般使用SpringBoot项目,而且RabbitMQ天生对于Spring的 ...

随机推荐

  1. solr7.1.0学习笔记(10)---Solr发布到Tomcat

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/weixin_39082031/article/details/79069554 将solr作为一个单 ...

  2. solr 忽略大小写

    1.types标签下加入如下fieldType <fieldType name="str_lower" class="solr.TextField" so ...

  3. jmeter插件如何协助进行内存监控 之 PerfMon Metrics Collector设置

    参考文章: http://www.cnblogs.com/zhaoxd07/p/5197669.html 当然最重要的是自己的实践,之前试的别人用的老的包 如XXstand.jar,结果并没有成功. ...

  4. 安全测试8_Web安全实战1(DVWA部署)

    1.渗透神器的打造(火狐浏览器的打造) Firebug HackBar(渗透插件) Tamper Data(抓包.截包.改包等功能) Proxy Switcher(代理设置) 2.PHP环境安装(ph ...

  5. Javascript强制转换

    Javascript强制转换 Javascript强制转换强制转换一共有五种转换方式,各有各的用处,希望大家在实际的使用中灵活运用,不要死板. <!DOCTYPE html> <ht ...

  6. 纯CSS3实现垂直居中的九种方法

    浏览时看到的资料,每个都做了测试,很好,就先收了~ 测试的是谷歌浏览器,没有任何问题,用360,IE11,火狐,搜狗浏览器做测试时,第五个方法在360,搜狗,和IE11有点问题,第七个在IE11有问题 ...

  7. PHP微信公共号发送模板消息。

    1.首先从微信公共平台(https://mp.weixin.qq.com/)添加模板. 2. /** * 经纪人生成电子合同通知租客.业主 * @param string $openid openid ...

  8. php图片上传base64数据编码。

    /** * base64图片上传 */ function IdImg($base64_img = ''){ $up_dir = 'upload/';//存放在当前目录的upload文件夹下 if(!f ...

  9. HTML页面过渡效果大全

    IE要求: 在IE5.5及以上版本的浏览器中.启用网页过渡效果 默认情况下都已经启用了,如果需要手动启用则只需在Internet选项中: Advanced(高级) - Browsing(浏览) - E ...

  10. leetcode1002

    class Solution: def commonChars(self, A: 'List[str]') -> 'List[str]': n = len(A) if n == 1: retur ...