首頁 > 軟體

Springboot 整合 RabbitMQ 訊息佇列 詳情

2022-08-17 18:01:51

生產者工程

POM依賴

可以在建立工程時直接選擇新增依賴。

application檔案

因為rabbitmq具有預設地址及使用者資訊,所以如果是本地rabbitmq可以不需要進行設定。

RabbitMQ組態檔:

在使用相關交換機及佇列時,我們需要實現宣告交換機及佇列,如果沒有對應資訊,則啟動專案會失敗。所以在使用springboot整合rabbitmq時,我們可以通過組態檔來進行交換機、佇列的宣告及二者之間的關係繫結。 由於目前在演示Fanout模式,所以使用FanoutExchange來宣告交換機,其他模式則使用相對應的TopicExchange,DirectExchange來宣告。

@Configuration
public class RabbitMQConfiguration {

//宣告fanout模式的交換機
@Bean
public FanoutExchange fanoutExchange() {
    return new FanoutExchange("fanout_order_exchange", true, false);
}

//宣告佇列
@Bean
public Queue smsQueue() {
    return new Queue("sms.fanout.queue", true);
}

@Bean
public Queue emailQueue() {
    return new Queue("email.fanout.queue", true);
}

@Bean
public Queue duanxinQueue() {
    return new Queue("duanxin.fanout.queue", true);
}
//繫結

@Bean
public Binding smsBinding() {
    return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
}

@Bean
public Binding emailBinding() {
    return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
}

@Bean
public Binding duanxinBinding() {
    return BindingBuilder.bind(duanxinQueue()).to(fanoutExchange());
}
}

生產者業務程式碼

這部分程式碼就簡單的通過呼叫rabbitTemplate來進行訊息的分發。@Service public class OrderService {

@Autowired
private RabbitTemplate rabbitTemplate;

public void makeOrder() {
    // 儲存訂單
    String orderId = UUID.randomUUID().toString();
    System.out.println("下單成功:" + orderId);
    // 通過MQ完成訊息的分發
    // 引數1:交換機 ;引數2:路由key/佇列名;引數3:訊息內容
    String exchangeName = "fanout_order_exchange";
    rabbitTemplate.convertAndSend(exchangeName, "", orderId);
}
}

消費者:

消費者工程和生產者工程類似,我們首先需要引入依賴,然後在application檔案中進行相關的設定即可開始編寫程式碼。 在消費者工程中我們也可以編寫rabbitmq的組態檔來進行交換機及佇列的宣告。建議在消費端編寫組態檔,因為消費端是先啟動的工程,如果交換機和佇列未建立會導致工程啟動失敗。 訊息監聽

我們通過RabbitListener註解來監聽訊息佇列。需要注意的是我們需要通過Component註解將該監聽交給spring管理,否則不能正常接收伺服器端的訊息。 這邊只給出一個email的訊息監聽,上文生產者宣告的duanxin,sms佇列可以自行建立,只需要修改佇列名即可。@Service public class OrderService {

@RabbitListener(queues = {"email.fanout.queue"})
@Component
public class FanoutEmailService {
    @RabbitHandler
    public void receive(String message) {
        System.out.println("email fanout -----》接收到" + message);
    }
}

測試

首先啟動消費者工程,然後在生產者工程中建立測試類傳送訊息即可。

@SpringBootTest class SpringbootOrderRabbitmqProducerApplicationTests {

@Autowired
private OrderService orderService;

@Test
void contextLoads() {
    orderService.makeOrder();
}
}

當傳送訊息後,我們可以在控制檯中發現消費者成功接受訊息。

Direct 模式

生產者

建立工程的步驟和上文相同。

組態檔

設定和上文基本相同,由於該部分測試direct模式,所以需要使用DirectExchange建立交換機。需要注意的是該類中的方法名不能和上文rabbitmq的組態檔中的方法名相同,因為我們使用bean註解將其交給spring管理,如果名字相同,則會啟動專案失敗。

@Configuration
public class DirectRabbitMQConfiguration {

//宣告direct模式的交換機
@Bean
public DirectExchange directExchange() {
    return new DirectExchange("direct_order_exchange", true, false);
}

//宣告佇列
@Bean
public Queue smsDirectQueue() {
    return new Queue("sms.direct.queue", true);
}

@Bean
public Queue emailDirectQueue() {
    return new Queue("email.direct.queue", true);
}

@Bean
public Queue duanxinDirectQueue() {
    return new Queue("duanxin.direct.queue", true);
}
//繫結

@Bean
public Binding smsDirectBinding() {
    return BindingBuilder.bind(smsDirectQueue()).to(directExchange()).with("sms");
}

@Bean
public Binding emailDirectBinding() {
    return BindingBuilder.bind(emailDirectQueue()).to(directExchange()).with("email");
}

@Bean
public Binding duanxinDirectBinding() {
    return BindingBuilder.bind(duanxinDirectQueue()).to(directExchange()).with("duanxin");
}
}

業務程式碼

@Service
public class OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void makeOrderDirect() {
        // 儲存訂單
        String orderId = UUID.randomUUID().toString();
        System.out.println("下單成功:" + orderId);
        String exchangeName = "direct_order_exchange";
        rabbitTemplate.convertAndSend(exchangeName, "sms", orderId);
        rabbitTemplate.convertAndSend(exchangeName, "email", orderId);
    }

}

消費者

訊息監聽

和上文相同,只需注意佇列名即可。

@RabbitListener(queues = {"email.direct.queue"})
@Component
public class DirectEmailService {
    @RabbitHandler
    public void receive(String message) {
        System.out.println("email direct -----》接收到" + message);
    }
}

Topic 模式

上文中個模式都是通過組態檔來宣告交換機,佇列及繫結二者之間的關係;實際上我們還可以通過註解的方式來宣告交換機及註解。

生產者

由於使用註解方式宣告,所以我們不需要建立組態檔,直接編寫業務程式碼即可。測試的時候我們只需修改路由名即可,具體如何修改,請前往文章開頭連結檢視各模式是如何使用的。

@Service
public class OrderService {

@Autowired
private RabbitTemplate rabbitTemplate;

public void makeOrderTopic() {
    // 儲存訂單
    String orderId = UUID.randomUUID().toString();
    System.out.println("下單成功:" + orderId);
    String exchangeName = "topic_order_exchange";
    String routingKey = "com.email";
    rabbitTemplate.convertAndSend(exchangeName, routingKey, orderId);
}
}

消費者

程式碼和上文基本相同,區別在於我們直接在RabbitListener註解中將佇列和交換機進行繫結。需要注意的是各引數中都是使用字串。 value對應的是佇列,相應的引數分別是佇列名、持久化、自動刪除。 exchange對應的交換機,相應的引數分別是交換機名以及交換機型別。 key對應的是路由名。

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(value = "email.topic.queue",durable = "true",autoDelete = "false"),
        exchange = @Exchange(value = "topic_order_exchange",type = ExchangeTypes.TOPIC),
        key = "*.email.#"
))
@Component
public class TopicEmailService {
    @RabbitHandler
    public void receive(String message) {
        System.out.println("email topic -----》接收到" + message);
    }
}

以上便是springboot 整合 rabbitmq的兩種方式。但是在日常開發中更推薦使用組態檔的形式來實現,因為在組態檔中可以更好的處理過期時間、死信佇列等訊息佇列中的高階特性。

到此這篇關於Springboot 整合 RabbitMQ 訊息佇列 詳情的文章就介紹到這了,更多相關Springboot 整合 RabbitMQ 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com