一、优先级队列
rabbitMq提供了优先级队列的实现,可以通过设置队列的x-max-priority参数来实现。
Map<String, Object> arg = new HashMap<String, Object>();
arg.put("x-max-priority", 10);
channel.queueDeclare("queue.priority", true, false, false, arg);
上面一段代码设置了queue.priority队列共有10个优先级,优先级越大的消息越先被投递。使用优先级队列需要注意:当消费者消费消息的速度大于生产者生产消息的速度时,优先级队列将毫无意义,只有当队列中存在累积的消息时,消息才会被按照优先级的顺序投递。
生产者代码:
//创建connection,channel...
channel.exchangeDeclare("exchange.priority", "direct", true);
Map<String, Object> arg = new HashMap<String, Object>();
arg.put("x-max-priority", 10);
channel.queueDeclare("queue.priority", true, false, false, arg);
channel.queueBind("queue.priority", "exchange.priority", "routingkey-priority");
Builder builder1 = new AMQP.BasicProperties.Builder();
builder1.priority(10);
channel.basicPublish("exchange.priority", "routingkey-priority", builder1.build(), "Test priority 10".getBytes());
Builder builder2 = new AMQP.BasicProperties.Builder();
builder2.priority(1);
channel.basicPublish("exchange.priority", "routingkey-priority", builder2.build(), "Test priority 1".getBytes());
Builder builder3 = new AMQP.BasicProperties.Builder();
builder3.priority(5);
channel.basicPublish("exchange.priority", "routingkey-priority", builder3.build(), "Test priority 5".getBytes());
//释放资源...
消费者代码:
channel.basicConsume("queue.priority", true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
System.out.println("Message : " + new String(body));
}
});
运行结果:
二、RPC实现
rabbitMq可以通过设置消息的的correlationId和replayTo属性来实现RPC请求调用。
- replyTo:回调队列,当服务端处理完请求之后,把响应信息发布到回调队列。
- correlationId:关联客户端的请求与服务端的响应。当多个请求使用同一个回调队列时,这个属性可以用来区分不同请求对应的的响应信息。
服务端代码:
public class RPCServer {
final static String queueName = "RPCQueue";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("root");
factory.setPassword("root");
Connection connection = factory
.newConnection(new Address[] { new Address("192.168.79.108",
5672) });
final Channel channel = connection.createChannel();
channel.basicConsume(queueName, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
builder.correlationId(properties.getCorrelationId());
try {
System.out
.println("Received message : " + new String(body));
} catch (Exception e) {
} finally {
//把响应信息发布到回调队列
channel.basicPublish("", properties.getReplyTo(),
builder.build(), "Response.".getBytes());
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
});
}
}
客户端代码:
public class RPCClient {
final static String queueName = "RPCQueue";
public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.79.108");
factory.setPort(5672);
factory.setUsername("root");
factory.setPassword("root");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.exchangeDeclare("RPCExchange", "direct", true, false, false, null);
channel.queueDeclare(queueName, true, false, false, null);
channel.queueBind(queueName, "RPCExchange", "routingkeyRPC");
//声明回调队列
DeclareOk declareOk = channel.queueDeclare();
final String replyQueue = declareOk.getQueue();
String correlationId = UUID.randomUUID().toString();
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
//客户端通过correlationId相关联
builder.correlationId(correlationId);
builder.replyTo(replyQueue);
channel.basicPublish("RPCExchange", "routingkeyRPC", builder.build(), "Request.".getBytes());
QueueingConsumer consumer = new QueueingConsumer(channel);
//客户端消费回调队列,服务端处理完请求会往回调队列发送消息
channel.basicConsume(replyQueue, true, consumer);
while (true) {
Delivery delivery = consumer.nextDelivery();
if (delivery.getProperties().getCorrelationId().equals(correlationId)) {
System.out.println("Result : " + new String(delivery.getBody()));
break;
}
}
connection.close();
}
}
运行结果: