Routing(路由模式)

Posted haizhilangzi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Routing(路由模式)相关的知识,希望对你有一定的参考价值。

  • Routing(路由模式)

    生产者将消息发送到direct交换器,在绑定队列和交换器的时候有一个路由key,生产者发送的消息会指定一个路由key,那么消息只会发送到相应key相同的队列,接着监听该队列的消费者消费信息.

    • Direct exchange

      会把消息路由到那些binding key与routing key完全匹配的Queue中
      我们可以看到绑定了两个队列的exchange X。第一个队列binding key 为orange,第二个binding key为两个,一个binding key为black,另一个binding key为green。
      使用routing key为orange发布到交换机的消息 将被路由到队列Q1。routing key为black 或green的消息将转到Q2。所有其他消息将被丢弃。技术图片

      Multiple Bindings

      用相同的binding key 绑定多个队列,可以使用binding key 为black在X和Q1与Q2之间添加绑定。在这种情况下,exchange的行为将类似于扇出,并将消息广播到所有匹配的队列。routing key为black的消息将同时传递给 Q1和Q2

    • 下面代码实现生产者和消费者的Direct模式

      生产者代码:

      public class DirectEmitLog {
      
          private static final String EXCHANGE_NAME = "direct_logs";
      
          public static void main(String[] args) throws Exception {
              //获取连接
              Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
      
              Channel channel = connection.createChannel();
      
              //创建队列
              channel.queueDeclare("direct_loge",false,false,false,null);
              //声明交换机,
              channel.exchangeDeclare(EXCHANGE_NAME, "direct");
      
              String message="hello";
              //发送消息
      
      //        for (int i = 0; i < 10; i++) {
      //            String message = " message" + i;
      //            System.out.println("[send]:" + message);
                  //发送消息
                  channel.basicPublish(EXCHANGE_NAME, "err", null, message.getBytes("utf-8"));
      
              //}
              channel.close();
              connection.close();
      
          }
      
      }

      消费者代码:

      public class DirectRecv {
      
          private final static String QUEUE_NAME = "direct_loge";
          private static final String EXCHANGE_NAME = "direct_logs";
          public static void main(String[] args) throws Exception {
              //获取连接
              Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
      
              //声明通道
              Channel channel = connection.createChannel();
      
              channel.exchangeDeclare(EXCHANGE_NAME, "direct");
      
              //声明队列队列
              channel.queueDeclare(QUEUE_NAME, false, false, false, null);
              channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "err");
      
              DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                  String message = new String(delivery.getBody(), "UTF-8");
      
                  System.out.println(" [x] Received '" + message + "'");
                  try {
                      doWork(message);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  } finally {
                      System.out.println(" [x] Done");
                      //channel.basicAck();
                      //channel.basicNack();
                  }
              };
              boolean autoAck = true; // acknowledgment is covered below
              channel.basicConsume(QUEUE_NAME, autoAck, deliverCallback, consumerTag -> {
              });
      
      
      //        DeliverCallback deliverCallback = new DeliverCallback(){
      //            @Override
      //            public void handle(String consumerTag, Delivery delivery) throws IOException {
      //                String message = new String(delivery.getBody(), "UTF-8");
      //                System.out.println(" [x] Received '" + message + "'");
      //            }
      //        };
      //
      //        channel.basicConsume(QUEUE_NAME, true, deliverCallback, new CancelCallback(){
      //            @Override
      //            public void handle(String consumerTag) throws IOException {
      //
      //            }
      //        });
      
          }
      
          private static void doWork(String task) throws InterruptedException {
              for (char ch : task.toCharArray()) {
                  if (ch == '.') Thread.sleep(1000);
              }
          }
      
      }
    • SpringBoot相关代码:

      @SpringBootApplication
      @EnableScheduling
      public class RabbitAmqpTutorialsApplication {
      
          public static void main(String[] args) throws Exception {
              SpringApplication.run(RabbitAmqpTutorialsApplication.class, args);
          }
      
      }
      @Configuration
      public class Tut4Config {
      
          @Bean
          public DirectExchange direct() {
              return new DirectExchange("tut.direct");
          }
      
          private static class ReceiverConfig {
      
              @Bean
              public Queue autoDeleteQueue1() {
                  return new AnonymousQueue();
              }
      
              @Bean
              public Queue autoDeleteQueue2() {
                  return new AnonymousQueue();
              }
      
              @Bean
              public Binding binding1a(DirectExchange direct,
                                       Queue autoDeleteQueue1) {
                  return BindingBuilder.bind(autoDeleteQueue1)
                          .to(direct)
                          .with("orange");
              }
      
              @Bean
              public Binding binding1b(DirectExchange direct,
                                       Queue autoDeleteQueue1) {
                  return BindingBuilder.bind(autoDeleteQueue1)
                          .to(direct)
                          .with("black");
              }
      
              @Bean
              public Binding binding2a(DirectExchange direct,
                                       Queue autoDeleteQueue2) {
                  return BindingBuilder.bind(autoDeleteQueue2)
                          .to(direct)
                          .with("green");
              }
      
              @Bean
              public Binding binding2b(DirectExchange direct,
                                       Queue autoDeleteQueue2) {
                  return BindingBuilder.bind(autoDeleteQueue2)
                          .to(direct)
                          .with("black");
              }
      
              @Bean
              public Tut4Receiver receiver() {
                  return new Tut4Receiver();
              }
          }
      
          @Bean
          public Tut4Sender sender() {
              return new Tut4Sender();
          }
      
      }
      public class Tut4Receiver {
      
          @RabbitListener(queues = "#{autoDeleteQueue1.name}")
          public void receive1(String in) throws InterruptedException {
              receive(in, 1);
          }
      
          @RabbitListener(queues = "#{autoDeleteQueue2.name}")
          public void receive2(String in) throws InterruptedException {
              receive(in, 2);
          }
      
          public void receive(String in, int receiver) throws InterruptedException {
              StopWatch watch = new StopWatch();
              watch.start();
              System.out.println("instance " + receiver + " [x] Received '" + in + "'");
              doWork(in);
              watch.stop();
              System.out.println("instance " + receiver + " [x] Done in " +
                      watch.getTotalTimeSeconds() + "s");
          }
      
          private void doWork(String in) throws InterruptedException {
              for (char ch : in.toCharArray()) {
                  if (ch == '.') {
                      Thread.sleep(1000);
                  }
              }
          }
      
      }
      public class Tut4Sender {
      
          @Autowired
          private RabbitTemplate template;
      
          @Autowired
          private DirectExchange direct;
      
          AtomicInteger index = new AtomicInteger(0);
      
          AtomicInteger count = new AtomicInteger(0);
      
          private final String[] keys = {"orange", "black", "green"};
      
          @Scheduled(fixedDelay = 1000, initialDelay = 500)
          public void send() {
              StringBuilder builder = new StringBuilder("Hello to ");
              if (this.index.incrementAndGet() == 3) {
                  this.index.set(0);
              }
              String key = keys[this.index.get()];
              builder.append(key).append(' ');
              builder.append(this.count.get());
              String message = builder.toString();
              template.convertAndSend(direct.getName(), key, message);
              System.out.println(" [x] Sent '" + message + "'");
          }
      
      }

      相关代码链接: https://github.com/albert-liu435/springmq

以上是关于Routing(路由模式)的主要内容,如果未能解决你的问题,请参考以下文章

springBoot集成rabbitmq 之路由模式模式(Routing)

Routing(路由模式)

routing路由模式

RabbitMQJava系列5-Routing模式

RabbitMQ02_简单模式Publish/Subscribe发布与订阅模式Routing路由模式Topics通配符模式Work模式-轮询公平

RabbitMQ02_简单模式Publish/Subscribe发布与订阅模式Routing路由模式Topics通配符模式Work模式-轮询公平