RabbitMq(2)优先级队列、RPC实现

一、优先级队列

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();
	}
}

运行结果:
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值