我正在使用rabbitmq rpc来获取多线程环境中的数据,我在下面跟着
问题:
我的问题是第3次我无法获得一次又一次使用同一消费者的rabbitmq java API。
如果我让每个频道创建一个消费者,那么该消费者永远不会因为与某个频道相关联的原因而被GC,并且该频道永远不会被删除(设置中的第2点)。但如果我删除每个频道得到GCed。
可能解决的方法:
我应该创建并发HashMap并将所有使用者保留在并发Hash Map中并来回加载吗?
rabbit mq basicGet()API:这看起来很混乱: 有时它返回null响应,而rpc-server继续返回正确的值。这里可能的工作是放
而(真){ //继续投票 //一旦获得数据就中断 }
这对我来说似乎是个黑客。
我不认为这里有任何其他选择。
以下是我用来使用来自rabbit mq rpc的数据的代码:
public String fetchDataFromRpc(String requestQueueName, byte[] message, Channel channel) throws IOException, InterruptedException {
final BlockingQueue<String> response = new LinkedBlockingQueue<>();
String replyQueueName = channel.queueDeclare().getQueue();
String corrId = UUID.randomUUID().toString();
System.out.println(" corr id : "+corrId);
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().correlationId(corrId).replyTo(replyQueueName).build();
channel.basicPublish("", requestQueueName, props, message);
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
if (properties.getCorrelationId().equals(corrId)) {
response.offer(new String(body, "UTF-8"));
channel.queueDelete(replyQueueName);
System.out.println(" res corr id : "+corrId);
}
}
};
channel.basicConsume(replyQueueName, true, consumer);
return response.take();
}
行: channel.basicConsume(replyQueueName,true,consumer); 每次线程进入这个块时都会不断创建新的消费者,旧的消费者永远不会得到GCed,我得到它是因为它链接到通道而不是GCed所以我可以使用HashMap来存储每个线程的所有消费者并从那里继续加载吗?
答案 0 :(得分:0)
完成后你应该basicCancel()
消费者。
但是,您应该进行handleCancel()
调用,因为您删除了消费者的队列,因此我不明白为什么消费者不会使用GC。
为每个请求创建临时回复队列效率不高。 RabbitMQ现在提供了一个带有伪回复队列的特殊直接replyTo机制。
为什么要添加spring-rabbitmq代码?我在你的问题中看不到弹簧代码。
另一方面,如果您是春季商店,RabbitTemplate.sendAndReceive()
(和convertSendAndReceive()
)方法将为您处理所有这些(以及it uses direct replyTo, by default, if the broker is new enough)。
答案 1 :(得分:0)
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
if (properties.getCorrelationId().equals(corrId)) {
response.offer(new String(body, "UTF-8"));
channel.basicCancel(consumerTag);
channel.queueDelete(replyQueueName);
}
}