1.前言说明

前面一篇博客中提到了使用原生java代码进行测试RabbitMQ实现多种交换机类型的队列场景。但是在项目中我们一般使用SpringBoot项目,而且RabbitMQ天生对于Spring的支持是非常良好的,所以这里基于SpringBoot我搭建了一个模拟购买商品订单下单并发送消息使用RabbitMQ消息队列的场景来分析实现不同模式下的场景。

也是对于SpringBoot整合RabbitMQ的一种总结。

使用到的模型如下图所示,在下订单处理的同时,采用消息队列生产者向MQ消息中间件中生产消息发送给对应的队列,创建消费者来消费队列中的消息调用服务。

2.基于SpringBoot配置类构建消息队列

项目构建我采用的是IDEA中Spring Initializr构建器创建的SpringBoot Maven项目,这部分主要是使用到了Spring RabbitMQ与SpringBoot Web的依赖组件。

由于原生支持,在IDEA中勾选对应的选项即可,非常简单,无需考虑多余的Maven Repository引入。

创建SpringBoot项目主要有springboot-order-rabbitmq-consumer与springboot-order-rabbitmq-producer两个Module。

这里还是简单说明一下pom.xml与application.yml配置:

pom.xml

  1. <dependencies>
  2. <!--rabbitmq starter依赖-->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-amqp</artifactId>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-web</artifactId>
  10. </dependency>
  11.  
  12. <dependency>
  13. <groupId>org.springframework.boot</groupId>
  14. <artifactId>spring-boot-starter-test</artifactId>
  15. <scope>test</scope>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.amqp</groupId>
  19. <artifactId>spring-rabbit-test</artifactId>
  20. <scope>test</scope>
  21. </dependency>
  22. <dependency>
  23. <groupId>junit</groupId>
  24. <artifactId>junit</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. </dependencies>

application.yml

  1. # 服务端口
  2. server:
  3. port: 8080
  4. # 配置rabbitmq服务
  5. spring:
  6. rabbitmq:
  7. username: admin
  8. password: admin
  9. virtual-host: /
  10. host: 127.0.0.1 #基于本地windows RabbitMQ测试,云服务填写对应地址即可
  11. port: 5672

2.1.生产者配置类

RabbitMQ中消息队列模式主要常用的模式就是:fanout、direct、topic模式,这里我主要讲解fanout与direct进行配置类构建生产者消费者。

整合生成消息队列(交换机、Queues及绑定关系、Routing key)可以从生产者端也可从消费者端进行。

主要构建方式有两种:

①配置类生成交换机与队列

②注解形式绑定交换机队列关系(topic使用注解方式构建)

这里先说第一种配置类方式:

使用配置类生成消息生产者队列主要配置类说明:

主要配置类XxxTypeRabbitConfig

  1. //注意:XxxType表示是交换机类型:可以是Fanout/Direct/Topic/Headers
  2. @Configuration
  3. public class XxxTypeRabbitConfig {
  4. //使用注入方式声明对应的Queue
  5. @Bean
  6. public Queue emailQueue() {
  7. // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
  8. // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
  9. // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
  10. //一般设置一下队列的持久化就好,其余两个就是默认false
  11. return new Queue("email.xxxType.queue", true);
  12. }
  13. @Bean
  14. public Queue smsQueue() {
  15. return new Queue("sms.xxxType.queue", true);
  16. }
  17. @Bean
  18. public Queue weixinQueue() {
  19. return new Queue("weixin.xxxType.queue", true);
  20. }
  21.  
  22. //声明交换机,不同的交换机类型不同:DirectExchange/FanoutExchange/TopicExchange/HeadersExchange
  23. @Bean
  24. public XxxTypeExchange xxxTypeOrderExchange() {
  25. return new XxxTypeExchange("xxxType_order_exchange", true, false);
  26. }
  27.  
  28. //绑定关系:将队列和交换机绑定, 并设置用于匹配键:routingKey
  29. @Bean
  30. public Binding bindingXxxType1() {
  31. return BindingBuilder
  32. .bind(weixinQueue()) //绑定哪个Queue
  33. .to(fanoutOrderExchange()); //是哪个交换机
  34. }
  35. @Bean
  36. public Binding bindingXxxType2() {
  37. return BindingBuilder.bind(smsQueue()).to(xxxTypeOrderExchange());
  38. }
  39.  
  40. @Bean
  41. public Binding bindingXxxType3() {
  42. return BindingBuilder.bind(emailQueue()).to(xxxTypeOrderExchange());
  43. }
  44. }

消息发送类,主要给创建的队列填充消息,这里主要用到RabbitTemplate类调用convertAndSend方法进行对应交换机消息队列的发送:

  1. @Service
  2. public class OrderService {
  3. @Autowired
  4. private RabbitTemplate rabbitTemplate;
  5. // 1: 定义交换机
  6. private String exchangeName = "";
  7. // 2: 路由key
  8. private String routeKey = "";
  9.  
  10. //XxxType类型交换机
  11. public void makeOrderXxxType(Long userId, Long productId, int num) {
  12. exchangeName = "xxxType_order_exchange";
  13. routeKey = "";
  14. // 1: 模拟用户下单
  15. String orderNumer = UUID.randomUUID().toString();
  16. // 2: 根据商品id productId 去查询商品的库存
  17. // int numstore = productSerivce.getProductNum(productId);
  18. // 3:判断库存是否充足
  19. // if(num > numstore ){ return "商品库存不足..."; }
  20. // 4: 下单逻辑
  21. // orderService.saveOrder(order);
  22. // 5: 下单成功要扣减库存
  23. // 6: 下单完成以后
  24. System.out.println("用户 " + userId + ",订单编号是:" + orderNumer);
  25. // 发送订单信息给RabbitMQ xxxType
  26. rabbitTemplate.convertAndSend(exchangeName, routeKey, orderNumer);
  27. }
  28.  
  29. }

2.2.Fanout模式消息生产者

①创建交换机与队列生成配置类,注意fanout这里绑定Queues的时候不要设置routing key,是采用广播订阅发送的方式:

  1. /**
  2. * @Description: fanout交换机类型就是对应的消息采用广播订阅模式,订阅绑定交换机的队列都应该收到消息
  3. * @Author: fengye
  4. * @Date: 2021/4/16 14:29
  5. */
  6. @Configuration
  7. public class FanoutRabbitConfig {
  8. //使用注入方式声明对应的Queue
  9. @Bean
  10. public Queue emailQueue() {
  11. // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
  12. // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
  13. // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
  14. //一般设置一下队列的持久化就好,其余两个就是默认false
  15. return new Queue("email.fanout.queue", true);
  16. }
  17. @Bean
  18. public Queue smsQueue() {
  19. return new Queue("sms.fanout.queue", true);
  20. }
  21. @Bean
  22. public Queue weixinQueue() {
  23. return new Queue("weixin.fanout.queue", true);
  24. }
  25.  
  26. //声明交换机,不同的交换机类型不同:DirectExchange/FanoutExchange/TopicExchange/HeadersExchange
  27. @Bean
  28. public FanoutExchange fanoutOrderExchange() {
  29. return new FanoutExchange("fanout_order_exchange", true, false);
  30. }
  31.  
  32. //绑定关系:将队列和交换机绑定, 并设置用于匹配键:routingKey
  33. @Bean
  34. public Binding bindingFanout1() {
  35. return BindingBuilder
  36. .bind(weixinQueue()) //绑定哪个Queue
  37. .to(fanoutOrderExchange()); //是哪个交换机
  38. }
  39. @Bean
  40. public Binding bindingFanout2() {
  41. return BindingBuilder.bind(smsQueue()).to(fanoutOrderExchange());
  42. }
  43.  
  44. @Bean
  45. public Binding bindingFanout3() {
  46. return BindingBuilder.bind(emailQueue()).to(fanoutOrderExchange());
  47. }
  48. }

②消息队列发送到Queue,使用OrderService进行发送,主要用到了RabbitTemplate:

  1. @Service
  2. public class OrderService {
  3. @Autowired
  4. private RabbitTemplate rabbitTemplate;
  5. // 1: 定义交换机
  6. private String exchangeName = "";
  7. // 2: 路由key
  8. private String routeKey = "";
  9.  
  10. //Fanout类型交换机
  11. public void makeOrderFanout(Long userId, Long productId, int num) {
  12. exchangeName = "fanout_order_exchange";
  13. routeKey = "";
  14. // 1: 模拟用户下单
  15. String orderNumer = UUID.randomUUID().toString();
  16. // 2: 根据商品id productId 去查询商品的库存
  17. // int numstore = productSerivce.getProductNum(productId);
  18. // 3:判断库存是否充足
  19. // if(num > numstore ){ return "商品库存不足..."; }
  20. // 4: 下单逻辑
  21. // orderService.saveOrder(order);
  22. // 5: 下单成功要扣减库存
  23. // 6: 下单完成以后
  24. System.out.println("用户 " + userId + ",订单编号是:" + orderNumer);
  25. // 发送订单信息给RabbitMQ fanout
  26. rabbitTemplate.convertAndSend(exchangeName, routeKey, orderNumer);
  27. }
  28. }

③生产者方启动测试类向fanout_order_exchange交换机队列发送消息,存储到消息队列中:

  1. @SpringBootTest
  2. class RabbitmqApplicationTests {
  3.  
  4. @Autowired
  5. private OrderService orderService;
  6.  
  7. @Test
  8. void fanoutTest() throws InterruptedException {
  9. for (int i = 0; i < 10; i++) {
  10. Thread.sleep(1000);
  11. Long userId = 100L + i;
  12. Long productId = 10001L + i;
  13. int num = 10;
  14. orderService.makeOrderFanout(userId, productId, num);
  15. }
  16. }
  17. }

运行结果:

生成队列并存储10条消息。

2.3.Fanout模式消息消费者

①配置类实现消息消费者队列比较简单,主要就是使用@RabbitListener绑定对应的队列,并使用@RabbitHandler接收消息对应中的参数信息即可,注意选择合适的数据类型接收:

对应消息队列类配置:

  1. //通过@RabbitListener绑定队列接收消息
  2. @RabbitListener(queues = {"weixin.fanout.queue"})
  3. @Component
  4. public class FanoutDuanxinConsumer {
  5. //队列中的消息会通过@RabbitHandler注解注入到方法参数中,就可以获取到队列中的消息
  6. @RabbitHandler
  7. public void reviceMessage(String message){
  8. System.out.println("weixin fanout----接收到了订单信息是:->" + message);
  9. }
  10. }
  11.  
  12. @RabbitListener(queues = {"email.fanout.queue"})
  13. @Component
  14. public class FanoutEmailConsumer {
  15. @RabbitHandler
  16. public void reviceMessage(String message){
  17. System.out.println("email fanout----接收到了订单信息是:->" + message);
  18. }
  19. }
  20.  
  21. @RabbitListener(queues = {"sms.fanout.queue"})
  22. @Component
  23. public class FanoutSMSConsumer {
  24. @RabbitHandler
  25. public void reviceMessage(String message){
  26. System.out.println("sms fanout----接收到了订单信息是:->" + message);
  27. }
  28. }

启动消息接收者consumer SpringBoot项目:

可以看到消息队列存储消息已被消费,控制台打印出了对应的消息信息。

2.4.Direct模式消息生产者

Direct模式消息生产者基于配置类构建与Fanout一样,这里简单说明一下配置类的增加的代码就行:

修改XxxTypeConfig基类为DirectExchange:

  1. /**
  2. * @Description: direct交换机类型采用routing key与Queue进行绑定,通过key不同一对一进行消息传递
  3. * @Author: fengye
  4. * @Date: 2021/4/16 14:29
  5. */
  6. @Configuration
  7. public class DirectRabbitConfig {
  8. //使用注入方式声明对应的Queue
  9. @Bean
  10. public Queue emailQueue() {
  11. // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
  12. // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
  13. // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
  14. //一般设置一下队列的持久化就好,其余两个就是默认false
  15. return new Queue("email.direct.queue", true);
  16. }
  17. @Bean
  18. public Queue smsQueue() {
  19. return new Queue("sms.direct.queue", true);
  20. }
  21. @Bean
  22. public Queue weixinQueue() {
  23. return new Queue("weixin.direct.queue", true);
  24. }
  25.  
  26. //声明交换机,不同的交换机类型不同:DirectExchange/FanoutExchange/TopicExchange/HeadersExchange
  27. @Bean
  28. public DirectExchange directOrderExchange() {
  29. return new DirectExchange("direct_order_exchange", true, false);
  30. }
  31.  
  32. //绑定关系:将队列和交换机绑定, 并设置用于匹配键:routingKey
  33. @Bean
  34. public Binding bindingFanout1() {
  35. return BindingBuilder
  36. .bind(weixinQueue()) //绑定哪个Queue
  37. .to(directOrderExchange()) //是哪个交换机
  38. .with("weixin"); //对应什么key
  39. }
  40. @Bean
  41. public Binding bindingFanout2() {
  42. return BindingBuilder.bind(smsQueue()).to(directOrderExchange()).with("sms");
  43. }
  44.  
  45. @Bean
  46. public Binding bindingFanout3() {
  47. return BindingBuilder.bind(emailQueue()).to(directOrderExchange()).with("email");
  48. }
  49. }

对应消息发送Service类:

  1. @Service
  2. public class OrderService {
  3. @Autowired
  4. private RabbitTemplate rabbitTemplate;
  5. // 1: 定义交换机
  6. private String exchangeName = "";
  7. // 2: 路由key
  8. private String routeKey = "";
  9.  
  10. //Direct类型交换机
  11. public void makeOrderDirect(Long userId, Long productId, int num) {
  12. exchangeName = "direct_order_exchange";
  13. routeKey = "weixin";
  14. // 1: 模拟用户下单
  15. String orderNumer = UUID.randomUUID().toString();
  16. // 2: 根据商品id productId 去查询商品的库存
  17. // int numstore = productSerivce.getProductNum(productId);
  18. // 3:判断库存是否充足
  19. // if(num > numstore ){ return "商品库存不足..."; }
  20. // 4: 下单逻辑
  21. // orderService.saveOrder(order);
  22. // 5: 下单成功要扣减库存
  23. // 6: 下单完成以后
  24. System.out.println("用户 " + userId + ",订单编号是:" + orderNumer);
  25. // 发送订单信息给RabbitMQ fanout
  26. rabbitTemplate.convertAndSend(exchangeName, routeKey, orderNumer);
  27. }
  28. }

执行测试类进行测试:

  1. @SpringBootTest
  2. class RabbitmqApplicationTests {
  3.  
  4. @Autowired
  5. private OrderService orderService;
  6.  
  7. @Test
  8. void directTest() throws InterruptedException {
  9. for (int i = 0; i < 10; i++) {
  10. Thread.sleep(1000);
  11. Long userId = 100L + i;
  12. Long productId = 10001L + i;
  13. int num = 10;
  14. orderService.makeOrderDirect(userId, productId, num);
  15. }
  16. }
  17. }

运行结果:

可以看到DirectQueue消息队列已经生成并存储到对应的weixin路由Key的队列中:

2.5.Direct模式消息消费者

①创建对应的消息队列消费者类,使用@RabbitListener、@RabbitHandler进行监听并绑定消息获取结果,这部分与上面的Fanout模式消费者是一样的:

  1. //通过@RabbitListener绑定队列接收消息
  2. @RabbitListener(queues = {"weixin.direct.queue"})
  3. @Component
  4. public class DirectDuanxinConsumer {
  5. //队列中的消息会通过@RabbitHandler注解注入到方法参数中,就可以获取到队列中的消息
  6. @RabbitHandler
  7. public void reviceMessage(String message){
  8. System.out.println("duanxin direct queue----接收到了订单信息是:->" + message);
  9. }
  10. }
  11.  
  12. @RabbitListener(queues = {"email.direct.queue"})
  13. @Component
  14. public class DirectEmailConsumer {
  15. @RabbitHandler
  16. public void reviceMessage(String message){
  17. System.out.println("email direct----接收到了订单信息是:->" + message);
  18. }
  19. }
  20.  
  21. @RabbitListener(queues = {"sms.direct.queue"})
  22. @Component
  23. public class DirectSMSConsumer {
  24. @RabbitHandler
  25. public void reviceMessage(String message){
  26. System.out.println("sms direct----接收到了订单信息是:->" + message);
  27. }
  28. }

②启动SpringBoot项目进行消费测试:

可以看到消息队列中绑定weixin端队列收到了10条消息。

3.基于SpringBoot注解类构建消息队列

使用注解方式实现消息队列主要是从消费者进行交换机与Queues队列的绑定关系建立,并使用@Component进行注入,可以比较简单地处理交换机与队列之间的绑定关系,随SpringBoot项目一启动就同时创建Exchange与Queues队列的关系。

下面总的说一下主要的注解:

  1. //通过@RabbitListener绑定队列接收消息
  2. // bindings其实就是用来确定队列和交换机绑定关系
  3. @RabbitListener(bindings = @QueueBinding(
  4. //队列名字,绑定对应的队列接收消息
  5. value = @Queue(value = "weixin.xxxType.queue", autoDelete = "false"),
  6. //交换机名字,必须和生产者中交换机名相同;指定绑定的交换机类型
  7. exchange = @Exchange(value = "xxxType_order_exchange", type = ExchangeTypes.XXXType),
  8. key = "com.#"
  9. ))
  1. //队列中的消息会通过@RabbitHandler注解注入到方法参数中,就可以获取到队列中的消息
  2. @RabbitHandler

3.1.Topic模式消息消费者

topic模式这里从消息消费者Springboot项目入手,优先创建出RabbitMQ上的消息队列与交换机进行绑定,基于@RabbitListener与@QueueBinding会随项目启动自动创建消息队列:

  1. //通过@RabbitListener绑定队列接收消息
  2. // bindings其实就是用来确定队列和交换机绑定关系
  3. @RabbitListener(bindings = @QueueBinding(
  4. //队列名字,绑定对应的队列接收消息
  5. value = @Queue(value = "weixin.topic.queue", autoDelete = "false"),
  6. //交换机名字,必须和生产者中交换机名相同;指定绑定的交换机类型
  7. exchange = @Exchange(value = "topic_order_exchange", type = ExchangeTypes.TOPIC),
  8. key = "com.#"
  9. ))
  10. @Component
  11. public class TopicDuanxinConsumer {
  12. //队列中的消息会通过@RabbitHandler注解注入到方法参数中,就可以获取到队列中的消息
  13. @RabbitHandler
  14. public void reviceMessage(String message){
  15. System.out.println("duanxin topic----接收到了订单信息是:->" + message);
  16. }
  17. }
  18.  
  19. @RabbitListener(bindings = @QueueBinding(
  20. //队列名字,绑定对应的队列接收消息
  21. value = @Queue(value = "email.topic.queue", autoDelete = "false"),
  22. //交换机名字,必须和生产者中交换机名相同;指定绑定的交换机类型
  23. exchange = @Exchange(value = "topic_order_exchange", type = ExchangeTypes.TOPIC),
  24. key = "#.order.#"
  25. ))
  26. @Component
  27. public class TopicEmailConsumer {
  28. //队列中的消息会通过@RabbitHandler注解注入到方法参数中,就可以获取到队列中的消息
  29. @RabbitHandler
  30. public void reviceMessage(String message){
  31. System.out.println("email topic----接收到了订单信息是:->" + message);
  32. }
  33.  
  34. }
  35.  
  36. @RabbitListener(bindings = @QueueBinding(
  37. //队列名字,绑定对应的队列接收消息
  38. value = @Queue(value = "sms.topic.queue", autoDelete = "false"),
  39. //交换机名字,必须和生产者中交换机名相同;指定绑定的交换机类型
  40. exchange = @Exchange(value = "topic_order_exchange", type = ExchangeTypes.TOPIC),
  41. key = "*.course.*"
  42. ))
  43. @Component
  44. public class TopicSMSConsumer {
  45. //队列中的消息会通过@RabbitHandler注解注入到方法参数中,就可以获取到队列中的消息
  46. @RabbitHandler
  47. public void reviceMessage(String message){
  48. System.out.println("sms topic----接收到了订单信息是:->" + message);
  49. }
  50. }

启动SpringBoot消费者项目,进行验证:

3.2.Topic模式消息生产者

使用注解配置无需再创建对应的配置类Config来绑定Exchange与Queues的关系了。

直接使用Sevice调用服务发送消息即可。

①服务调用、向队列中发送消息:

  1. @Service
  2. public class OrderService {
  3. @Autowired
  4. private RabbitTemplate rabbitTemplate;
  5. // 1: 定义交换机
  6. private String exchangeName = "";
  7. // 2: 路由key
  8. private String routeKey = "";
  9.  
  10. //Topic类型交换机
  11. public void makeOrderTopic(Long userId, Long productId, int num) {
  12. exchangeName = "topic_order_exchange";
  13. routeKey = "com.course.user";
  14. // 1: 模拟用户下单
  15. String orderNumer = UUID.randomUUID().toString();
  16. // 2: 根据商品id productId 去查询商品的库存
  17. // int numstore = productSerivce.getProductNum(productId);
  18. // 3:判断库存是否充足
  19. // if(num > numstore ){ return "商品库存不足..."; }
  20. // 4: 下单逻辑
  21. // orderService.saveOrder(order);
  22. // 5: 下单成功要扣减库存
  23. // 6: 下单完成以后
  24. System.out.println("用户 " + userId + ",订单编号是:" + orderNumer);
  25. // 发送订单信息给RabbitMQ fanout
  26. rabbitTemplate.convertAndSend(exchangeName, routeKey, orderNumer);
  27. }
  28. }

②服务测试:

  1. @SpringBootTest
  2. class RabbitmqApplicationTests {
  3.  
  4. @Autowired
  5. private OrderService orderService;
  6.  
  7. @Test
  8. void topicTest() throws InterruptedException {
  9. for (int i = 0; i < 10; i++) {
  10. Thread.sleep(1000);
  11. Long userId = 100L + i;
  12. Long productId = 10001L + i;
  13. int num = 10;
  14. orderService.makeOrderTopic(userId, productId, num);
  15. }
  16. }
  17. }

消息发送:

消费方consumer服务(消费者服务不停止)接收消息:

本博客示例涉及代码均已上传至Github:

RabbitMQStudy

【MQ中间件】RabbitMQ -- SpringBoot整合RabbitMQ(3)的更多相关文章

  1. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

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

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

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

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

  4. 功能:SpringBoot整合rabbitmq,长篇幅超详细

    SpringBoot整合rabbitMq 一.介绍 消息队列(Message Queue)简称mq,本文将介绍SpringBoot整合rabbitmq的功能使用 队列是一种数据结构,就像排队一样,遵循 ...

  5. 【SpringBoot系列5】SpringBoot整合RabbitMQ

    前言: 因为项目需要用到RabbitMQ,前几天就看了看RabbitMQ的知识,记录下SpringBoot整合RabbitMQ的过程. 给出两个网址: RabbitMQ官方教程:http://www. ...

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

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

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

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

  8. Springboot 整合RabbitMq ,用心看完这一篇就够了

    该篇文章内容较多,包括有rabbitMq相关的一些简单理论介绍,provider消息推送实例,consumer消息消费实例,Direct.Topic.Fanout的使用,消息回调.手动确认等. (但是 ...

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

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

随机推荐

  1. Java 添加 、读取以及删除PPT幻灯片中的视频、音频文件

    在PPT中,可以操作很多种元素,如形状.图形.文字.图片.表格等,也可以插入视频或者音频文件,来丰富幻灯片的内容呈现方式.下面将介绍在Java程序中如何来添加视频.音频文件到PPT幻灯片,读取和删除幻 ...

  2. Unity安卓apk打包过程

    前言:对于Unity开发小白来说,Android打包无疑是个头痛的问题,所以我总结了 Unity安卓APK的打包过程 第一步:下载对应版本的Android Platform 第二步:安装JDK并配置J ...

  3. Java 动态调试技术原理及实践

    本文转载自Java 动态调试技术原理及实践 导语 断点调试是我们最常使用的调试手段,它可以获取到方法执行过程中的变量信息,并可以观察到方法的执行路径.但断点调试会在断点位置停顿,使得整个应用停止响应. ...

  4. kali 将家目录下的中文文件名修改成英文

    修改vim ~/.config/user-dirs.dirs 打开`文件,删除那些中文目录 在目录下创建英文目录 重启 参考 https://elementaryos.stackexchange.co ...

  5. Node更丝滑的打开方式

    Node更丝滑的打开方式 1. 使用背景 最近前端的一个项目,使用gulp作为工程化.在运行过程中出现如下错误 gulp[3192]: src\node_contextify.cc:628: Asse ...

  6. 185. 部门工资前三高的所有员工 + 多表联合 + join + dense_rank()

    185. 部门工资前三高的所有员工 LeetCode_MySql_185 题目描述 方法一:使用join on # Write your MySQL query statement below sel ...

  7. pytorch(11)模型创建步骤与nn.Module

    模型创建与nn.Module 网络模型创建步骤 nn.Module graph LR 模型 --> 模型创建 模型创建 --> 构建网络层 构建网络层 --> id[卷积层,池化层, ...

  8. 【老孟Flutter】Flutter 2.0 重磅更新

    老孟导读:昨天期待已久的 Flutter 2.0 终于发布了,Web 端终于提正了,春季期间我发布的一篇文章,其中的一个预测就是 Web 正式发布,已经实现了,还有一个预测是:2021年将是 Flut ...

  9. Flink的日志配置

    ------------恢复内容开始------------ 介绍flink在本地运行和on yarn运行时的日志配置. 很多现代框架都是用门面模式进行日志输出,例如使用Slf4j中的接口输出日志,具 ...

  10. 还在用crontab? 分布式定时任务了解一下

    前言 日常任务开放中,我们会有很多异步.批量.定时.延迟任务要处理,go-zero中有 go-queue,推荐使用 go-queue 去处理,go-queue 本身也是基于 go-zero 开发的,其 ...