redis简单队列java
在本文中,我们将使用列表命令将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 payload
System.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简单队列java