使用Spring Data Redis 釋出訂閱訊息

信碼由韁發表於2022-12-15

使用 Spring Data Redis 釋出訂閱訊息

1. 概述

在 Redis 中,釋出者並沒有將訊息傳送給特定的訂閱者。是將釋出的訊息被劃分為通道,並不知道會有哪些訂閱者(如果有的話)。

類似地,訂閱者表示對一個或多個主題感興趣,並且只接收感興趣的訊息,而不知道有哪些釋出者(如果有的話)。

釋出者和訂閱者的這種解耦可以實現更大的可伸縮性和更動態的網路拓撲。

2. Redis 配置

讓我們開始新增訊息佇列所需的配置。

首先,我們將定義一個 MessageListenerAdapter,其中包含名為 RedisMessageSubscriberMessageListener 介面的自定義實現。這個 bean 充當釋出-訂閱訊息模型中的訂閱者:

@Bean
MessageListenerAdapter messageListener() { 
    return new MessageListenerAdapter(new RedisMessageSubscriber());
}

RedisMessageListenerContainer 是 Spring Data Redis 提供的一個類。這是內部呼叫的,根據 Spring Data Redis 文件 的說法 —— “處理監聽、轉換和訊息排程的底層細節。”

@Bean
RedisMessageListenerContainer redisContainer() {
    RedisMessageListenerContainer container 
      = new RedisMessageListenerContainer(); 
    container.setConnectionFactory(jedisConnectionFactory()); 
    container.addMessageListener(messageListener(), topic()); 
    return container; 
}

我們還將使用定製的 MessagePublisher 介面和 RedisMessagePublisher 實現建立 bean。這樣,我們可以有一個通用的訊息釋出 API,並讓 Redis 實現採用 redisTemplatetopic 作為建構函式引數:

@Bean
MessagePublisher redisPublisher() { 
    return new RedisMessagePublisher(redisTemplate(), topic());
}

最後,我們將設定一個主題,釋出者將向其傳送訊息,訂閱者將接收訊息:

@Bean
ChannelTopic topic() {
    return new ChannelTopic("messageQueue");
}

3. 釋出訊息

3.1. 定義 MessagePublisher 介面

Spring Data Redis 沒有提供用於訊息分發的 MessagePublisher 介面。:我們可以定義一個自定義介面,它將在實現中使用 redisTemplate:

public interface MessagePublisher {
    void publish(String message);
}

3.2. RedisMessagePublisher 實現[

我們接下來提供 MessagePublisher 介面的實現,新增訊息釋出的細節並使用 redisTemplate 中的函式。

該模板包含了一組非常豐富的函式,用於廣泛的操作—— 其中 convertAndSend 能夠透過主題向佇列傳送訊息:

public class RedisMessagePublisher implements MessagePublisher {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private ChannelTopic topic;

    public RedisMessagePublisher() {
    }

    public RedisMessagePublisher(
      RedisTemplate<String, Object> redisTemplate, ChannelTopic topic) {
      this.redisTemplate = redisTemplate;
      this.topic = topic;
    }

    public void publish(String message) {
        redisTemplate.convertAndSend(topic.getTopic(), message);
    }
}

如您所見,釋出者實現非常簡單。它使用 redisTemplateconvertAndSend() 方法格式化給定的訊息並將其釋出到配置的主題。

主題實現了釋出和訂閱語義:當訊息釋出時,它將傳送給所有註冊偵聽該主題的訂閱者。

4. 訂閱訊息

RedisMessageSubscriber 實現了 Spring Data Redis 提供的 MessageListener 介面:

@Service
public class RedisMessageSubscriber implements MessageListener {

    public static List<String> messageList = new ArrayList<String>();

    public void onMessage(Message message, byte[] pattern) {
        messageList.add(message.toString());
        System.out.println("Message received: " + message.toString());
    }
}

注意,還有第二個引數 pattern,在本例中我們沒有使用它。Spring Data Redis 文件指出,該參數列示“匹配通道的模式(如果指定)”,但它可以為 null

5. 傳送與接收訊息

現在我們把它們結合起來。我們建立一個訊息,然後使用 RedisMessagePublisher 釋出它:

String message = "Message " + UUID.randomUUID();
redisMessagePublisher.publish(message);

當我們呼叫 publish(message) 時,內容被髮送到 Redis,在那裡它被路由到我們的釋出者中定義的訊息佇列主題。然後將它分發給該主題的訂閱者。

您可能已經注意到 RedisMessageSubscriber 是一個偵聽器,它將自己註冊到佇列以檢索訊息。

訊息到達時,訂閱者定義的 onMessage() 方法被觸發。

在我們的例子中,我們可以透過檢查 RedisMessageSubscriber 中的 messageList 來驗證我們已經收到了已經發布的訊息:

RedisMessageSubscriber.messageList.get(0).contains(message)

6. 結論

在本文中,我們研究了使用Spring Data Redis 實現的釋出/訂閱訊息佇列。

上述示例的實現可以在 GitHub project 專案中找到。


【注】本文譯自:PubSub Messaging with Spring Data Redis | Baeldung


相關文章