1. 程式人生 > >Redis常用技術-----釋出訂閱

Redis常用技術-----釋出訂閱

銀行卡消費的時候,銀行往往會通過微信、簡訊或郵件通知使用者交易的詳細資訊,這便是釋出訂閱模式。

交易資訊釋出訂閱機制

我們可以使用下面的命令進行模擬

先開啟一個客戶端1,輸入命令

SUBSCRIBE chat

表示客戶端1訂閱一個名為chat的渠道,之後開啟客戶端2,輸入命令

publish chat "Hello World!"

這個時候客戶端2就向渠道chat傳送了一條訊息,再看客戶端1,可以看到訊息已經輸出。
Redis的釋出訂閱過程

在Spring中,我們自定義接收訊息的類,需要實現MessageListener介面,並實現介面定義的方法onMessage,程式碼如下。

public
class RedisMessageListener implements MessageListener { @SuppressWarnings("rawtypes") private RedisTemplate rt; @SuppressWarnings("rawtypes") public RedisTemplate getRt() { return rt; } @SuppressWarnings("rawtypes") public void setRt(RedisTemplate rt) { this
.rt = rt; } @Override public void onMessage(Message message, byte[] pattern) { // 獲取訊息 byte[] body = message.getBody(); // 使用值序列化器轉換 String msgBody = (String)getRt().getValueSerializer().deserialize(body); System.out.println(msgBody); // 獲取channel
byte[] channel = message.getChannel(); // 使用字串序列化器轉換 String channelStr = (String)getRt().getStringSerializer().deserialize(channel); System.out.println(channelStr); // 渠道名稱轉換 String bytesStr = new String(pattern); System.out.println(bytesStr); } }

這裡我們沒有使用註解,所以要去spring.xml中註冊bean

<!-- 例項化類 -->
<bean id="redisMsgListener" class="com.codeliu.transaction.RedisMessageListener">
    <property name="rt" ref="redisTemplate"></property>
</bean>

例項化監聽類之後還不行,還得給一個監聽容器,在Spring中對應的類為RedisMessageListenerContainer,它可以用來監聽Redis的釋出訂閱訊息。同樣在Spring.xml中進行配置

<!-- 配置監聽容器 -->
<bean id="topicContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer" destroy-method="destroy">
    <!-- redis連線工廠 -->
    <property name="connectionFactory" ref="connectionFactory"></property>      
    <!-- 連線池,只有執行緒池生存,才能繼續監聽 -->
    <property name="taskExecutor">
        <bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
            <property name="poolSize" value="3"></property>
        </bean>
    </property>     
    <!-- 訊息監聽map -->
    <property name="messageListeners">
        <map>
            <!-- 配置監聽者,key-ref與bean id保持一致 -->
            <entry key-ref="redisMsgListener">
                <!-- 監聽類 -->
                <bean class="org.springframework.data.redis.listener.ChannelTopic">
                    <constructor-arg value="chat"></constructor-arg>
                </bean>
            </entry>
        </map>
    </property>
</bean>

這裡配置了執行緒池,這個執行緒池將會持續的生存以等待訊息傳入,而這裡配置了容器用id為redisMsgListener的Bean進行渠道chat的監聽。當訊息通過渠道chat方法的時候,就會使用id為redisMsgListener的Bean處理訊息。

下面進行測試

public static void main(String[] args) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    RedisTemplate rt = applicationContext.getBean(RedisTemplate.class);
    String channel = "chat";
    // 向渠道chat傳送訊息
    rt.convertAndSend(channel, "Hello World!");
}

convertAndSend方法就是向指定的渠道傳送訊息。

輸出

Hello World!
chat
chat