使用Redis的简单消息队列
在本文中,我們將使用列表命令將Redis用作簡單的消息隊列。
假設我們有一個允許用戶上傳照片的應用程序。 然后在應用程序中,我們以不同大小顯示照片,例如Thumb,Medium和Large。
在第一個實現中,我們可以承擔在同一請求中處理上載圖像的任務。 由于這是一項昂貴的任務,因此會使我們的請求變慢。
一個可能的解決方案是使用消息隊列(MQ)使該處理異步進行,有許多眾所周知的MQ,例如ActiveMQ,RabbitMQ,IBM MQ等。 在下面的示例中,我們將使用LIST結構將Redis用作消息隊列。
這個想法是要有一個LIST,生產者將在其中放置要處理的消息,而某些消費者將觀看LIST以處理發送的消息。
基本上,生產者將使用“ RPUSH隊列消息 ”將消息添加到列表的末尾,而消費者將使用“ LPOP隊列 ”將列表開頭的消息配置為FIFO處理。
客戶端將一直在尋找新消息,為此,我們將使用BLPOP命令,該命令是LPOP命令的阻止版本。 基本上會有一個while循環調用BLPOP來處理新消息。
考慮到圖像上傳的示例,假設我們有一個ImageUploader類,負責將圖像上傳到服務器,它將在隊列中添加一條新消息,指示有要處理的圖像,消息可能是JSON字符串像這樣:
{“imagePath”:”/path/to/image”, “user”:”userid”}ImageUploder類可能是這樣的:
public class ImageUploader {public void uploadImage(HttpServletRequest request){String imagePath = saveImage(request);String jsonPayload = createJsonPayload(request, imagePath);jedis.rpush("queue", jsonPayload);//... keep with the processing}//.... other methods in the class }這只是生產者如何工作的一個例子。 在這種情況下,我們已經將圖像處理與ImageUploader類分離了。 我們只是在隊列中創建一條新消息,以便使用者處理它們。
消息使用者可能是這樣的:
package br.com.xicojunior.redistest;import java.util.List;import redis.clients.jedis.Jedis;public class MessageConsumer {public static void main( String[] args ){Jedis jedis = new Jedis("localhost"); List<String> messages = null;while(true){System.out.println("Waiting for a message in the queue");messages = jedis.blpop(0,"queue");System.out.println("Got the message");System.out.println("KEY:" + messages.get(0) + " VALUE:" + messages.get(1));String payload = messages.get(1);//Do some processing with the payloadSystem.out.println("Message received:" + payload);}} }此使用者代碼可以在不同的進程甚至不同的機器上運行。 這個使用者代碼是可運行的,我們可以編譯它并使用eclipse或java命令運行它。
對于此代碼,我們使用jedis.blpop方法,它返回包含2個字符串的列表,(0)–關鍵字,(1)–返回的值。 該方法還接收一個整數,它表示超時。 我們傳遞了0表示沒有超時。
當我們運行此代碼并且列表中沒有值時,在控制臺中,我們將僅看到消息
"Waiting for a message in the queue".然后,如果客戶在“隊列”列表中添加元素,我們的消費者類將獲得其價值。 我們可以通過使用redis-cli或什至另一個將在隊列中添加元素的類來模擬測試,如下所示:
package br.com.xicojunior.redistest;import redis.clients.jedis.Jedis;public class MessageProducer {public static void main(String[] args) {Jedis jedis = new Jedis("localhost");jedis.rpush("queue", "Value 1");jedis.rpush("queue", "Value 2");jedis.rpush("queue", "Value 3");}}如果我們在MessageConsumer類已經運行之后運行MessageProducer類,我們將在控制臺中看到以下輸出:
Waiting for a message in the queue Got the message KEY:queue VALUE:Value 1 Message received:Value 1 Waiting for a message in the queue Got the message KEY:queue VALUE:Value 2 Message received:Value 2 Waiting for a message in the queue Got the message KEY:queue VALUE:Value 3 Message received:Value 3 Waiting for a message in the queue 因此,消息隊列將是Redis的另一個可能的用例。 在redis之上建立了一些隊列,如RestMQ , Resque – Job Queue等。
翻譯自: https://www.javacodegeeks.com/2014/01/simple-message-queue-using-redis.html
總結
以上是生活随笔為你收集整理的使用Redis的简单消息队列的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OutOfMemoryError:解决方
- 下一篇: Redis与Jedis排序