Java Springboot 整合RabbitMQ(四):路由(Routing)-B2B2C小程式電子商務

gung123發表於2020-03-06

在本文中,我們將實現另一個功能 —— 只訂閱一部分訊息。例如,我們只需要把嚴重的錯誤日誌資訊寫入日誌檔案(儲存到磁碟),但同時仍然把所有的日誌資訊輸出到控制檯中

繫結(Binding)

在之前的例子中,我們已經建立了繫結。可以在我們的 Tut3Config 檔案中回憶一下這樣的程式碼:

@Bean
public Binding binding1(FanoutExchange fanout, Queue autoDeleteQueue1) {
    return BindingBuilder.bind(autoDeleteQueue1).to(fanout);
}

繫結(binding)是指交換器(exchange)和佇列(queue)的關係。可以簡單理解為:這個佇列(queue)對這個交換器(exchange)的訊息感興趣。

繫結可以使用一個額外的引數 routingKey。我們將交換器和佇列傳入到 BindingBuilder,並將 routingKey 繫結到交換器,如下所示:

@Bean
public Binding binding1a(DirectExchange direct, Queue autoDeleteQueue1) {
    return BindingBuilder.bind(autoDeleteQueue1)
        .to(direct)
        .with("orange");
}

routingKey 含義取決於交換型別。比如我們之前使用的 fanout exchange,會忽略它的值。


Direct exchange

我們的日誌系統廣播所有的訊息給所有的消費者(consumers)。我們打算擴充套件它,使其基於日誌的嚴重程度進行訊息過濾。例如我們也許只是希望將比較嚴重的錯誤(error)日誌寫入磁碟,以免在警告(warning)或者資訊(info)日誌上浪費磁碟空間。


我們使用的 fanout exchange 沒有足夠的靈活性 —— 它能做的僅僅是廣播。


我們將會使用 direct exchange 來代替。路由的演算法很簡單 —— 交換器將會對繫結鍵(binding key)和路由鍵(routing key)進行精確匹配,從而確定訊息該分發到哪個佇列。

下圖能夠很好的描述這個場景:



在這個場景中,我們可以看到 direct exchange X 和兩個佇列進行了繫結。第一個佇列使用 orange 作為繫結鍵,第二個佇列有兩個繫結,一個使用 black 作為繫結鍵,另外一個使用 green。


這樣以來,當路由鍵為 orange 的訊息釋出到交換器,就會被路由到佇列 Q1。路由鍵為 black 或者 green 的訊息就會路由到 Q2。其他的所有訊息都將會被丟棄。


多個繫結(Multiple bindings)


多個佇列使用相同的繫結鍵是可以的。這個例子中,我們可以新增一個 X 和 Q1 之間的繫結,使用 black 繫結鍵。這樣一來,direct exchange 就和 fanout exchange 的行為一樣,會將訊息廣播到所有匹配的佇列。帶有 black 路由鍵的訊息會同時傳送到 Q1 和 Q2。


釋出訊息

我們將使用以上這個模型作為我們的路由系統,將訊息傳送到 direct exchange 而不是 fanout exchange。我們將使用顏色作為路由鍵,這樣消費者將能透過選擇想要接收(或訂閱)的顏色來消費對應的訊息。


我們在 Tut4Config 中做一些 Spring 啟動配置,需要先建立一個交換器

@Bean
public DirectExchange direct() {
    return new DirectExchange("tut.direct");
}

接收訊息的方式與上一個教程中的一樣,但也有一些不同 —— 我們需要為每個感興趣的顏色建立一個新的繫結。
瞭解springcloud架構可以加求求:三五三六二四七二五九

@Bean
public Binding binding1a(DirectExchange direct, Queue autoDeleteQueue1) {
    return BindingBuilder.bind(autoDeleteQueue1)
        .to(direct)
        .with("orange");

程式碼整合
在這裡插入圖片描述
生產者

public class Tut4Sender {
   @Autowird 
    private AmqpTemplate template;
    @Autowird
    private DirectExchange direct;
    private int index;
    private int count;
    private final String[] keys = {"orange", "black", "green"};
    @Scheduled(fixedDelay = 1000, initialDelay = 500)
    public void send() {
        StringBuilder builder = new StringBuilder("Hello to ");
        if (++this.index == 3) {
            this.index = 0;
        }
        String key = keys[this.index];
        builder.append(key).append(' ').append(Integer.toString(++this.count));
        String message = builder.toString();
        template.convertAndSend(direct.getName(), key, message);
        System.out.println(" [x] Sent '" + message + "'");
    }
}

消費者

public class Tut4Receiver {
    @RabbitListener(queues = "#{autoDeleteQueue1.name}")
    public void receiver1(String in) throws InterruptedException {
        receiver(in, 1);
    }
    @RabbitListener(queues = "#{autoDeleteQueue2.name}")
    public void receiver2(String in) throws InterruptedException {
        receiver(in, 2);
    }
    private void receiver(String in, int instance) throws InterruptedException {
        StopWatch watch = new StopWatch();
        watch.start();
        System.out.println("instance " + instance + " [x] Received '" + in + "'");
        doWork(in);
        watch.stop();
        System.out.println("instance " + instance + " [x] Done in " +
                watch.getTotalTimeSeconds() + "s");
    }
    private void doWork(String in) throws InterruptedException {
        for (char ch : in.toCharArray()) {
            if (ch == '.') {
                Thread.sleep(1000);
            }
        }
    }
}

配置類

@Profile({"tut4", "routing"})
@Configuration
public class Tut4Config {
    @Bean
    public DirectExchange direct() {
        return new DirectExchange("tut.direct");
    }
   @Profile ("receiver")
    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();
        }
    }
   @Profile("sender")
    @Bean
    public Tut4Sender sender() {
        return new Tut4Sender();
    }
}

執行

maven 編譯


mvn clean package -Dmaven.test.skip=true

執行


java -jar target/rabbitmq-tutorial-0.0.1-SNAPSHOT.jar --spring.profiles.active=tut4,receiver --tutorial.client.duration=60000

java -jar target/rabbitmq-tutorial-0.0.1-SNAPSHOT.jar --spring.profiles.active=tut4,sender --tutorial.client.duration=60000

輸出


// Sender

Ready … running for 60000ms

[x] Sent ‘Hello to black 1’

[x] Sent ‘Hello to green 2’

[x] Sent ‘Hello to orange 3’

[x] Sent ‘Hello to black 4’


// Receiver

Ready … running for 60000ms

instance 2 [x] Received ‘Hello to black 1’

instance 1 [x] Received ‘Hello to black 1’

instance 2 [x] Done in 0.0s

instance 1 [x] Done in 0.0s

instance 2 [x] Received ‘Hello to green 2’

instance 2 [x] Done in 0.0s

instance 1 [x] Received ‘Hello to orange 3’

instance 1 [x] Done in 0.0s

instance 1 [x] Received ‘Hello to black 4’

instance 1 [x] Done in 0.0s

instance 2 [x] Received ‘Hello to black 4’

instance 2 [x] Done in 0.0s




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952307/viewspace-2678807/,如需轉載,請註明出處,否則將追究法律責任。

相關文章