使用spring-amqp库异步发送消息时如何使用rabbit mq处理网络超时异常
How to handle network time-out exception with rabbit mq while sending messages asynchronously using spring-amqp library
我编写了一个需要多个队列交互的程序 - 意味着一个队列的消费者将消息写入另一个队列,并且同一个程序让消费者对该队列采取行动。
问题:使用 spring rabbit ampq 库异步发送消息时,如何处理队列的网络超时问题?或者如果存在网络问题,RabbitTemplate.send() 函数必须抛出异常。
目前,我已经立即实施了 RabbitTemplate.send() returns 并且工作正常。但是,如果网络出现故障,立即发送函数 returns,不会抛出任何异常并且客户端代码假定成功。结果,我在数据库中的状态不一致,消息已成功处理。请注意,对发送函数的调用包含在事务块中,目标是如果队列写入失败,数据库提交也必须回滚。我正在探索以下解决方案但没有成功:
我们能否将 rabbitTemplate 配置为在出现任何网络连接问题时抛出 运行 次异常,以便通知客户端调用?请建议如何执行此操作。
要不要用同步的SendAndReceive函数调用,但是会导致处理延迟?使用此函数观察到的另一个问题是,我的消费者代码收到通知,而 sendAndReceive 函数仍被阻止以将消息写入队列。请告知我们是否可以延迟通知队列,除非 sendAndReceive 函数是 returned。但是如果网络出现故障,调用 SendAndReceive() 会抛出一个 amqp 异常,我们能够捕获它,但它的成本与性能相关。
我的应用程序是多线程的,如果多个线程正在使用 sendAndReceive() 发送消息,spring-amqp 库如何管理队列通信?它是否在内部根据请求创建频道?如果消息通过相同的通道传递,这将对多线程应用程序的性能产生很大影响。
有人可以分享使用 SendAndReceive 函数的最佳实践示例代码吗?
我们在 spring-amqp 库中是否有任何函数可以在提交发送函数调用之前检查 RabbitMQ 服务器的健康状况?我探索了 rabbitTemplate.isRunning() 但没有得到正确的结果。如需具体配置,请提出建议。
要考虑的保证消息传递或处理网络超时问题以向客户端抛出 运行时间异常的任何其他解决方案..
根据下面的 Gary 评论,我设置了:rabbitTemplate.setChannelTransacted(true);它使通话同步。问题的下一部分是,如果我在外部块上有事务块,请立即调用 RabbitTemplate.send() returns。我希望外部函数的事务块必须等待内部函数 return,否则,虽然我们将 setChannelTransacted 启用为 true,但我的数据库更改仍然存在,因此无法获得预期结果。我尝试了各种事务传播级别但没有成功。如果我做错了什么请告知并检查交易传播设置如下
@Transactional
public void notifyQueueAndDB(DBRequest dbRequest) {
logger.info("Updating Request in DB");
dbService.updateRequest(dbRequest));
//Below is call to RabbitMQ library
mqService.sendmessage(dbRequest); //If sendMessage fails because of network outage, I want DB commit also to be rolled-back.
}
MQService 在另一个项目库中定义,下面是代码片段。
@Transactional( propagation = Propagation.NESTED)
private void sendMessage(......) {
....
rabbitTemplate.send(this.queueExchange, queueName, amqpMessage);
}catch (Exception exception) {
throw exception
}
- 启用事务以便同步发送。
或
- 使用 Publisher 确认并等待收到确认。
任何一个都会慢很多。
我编写了一个需要多个队列交互的程序 - 意味着一个队列的消费者将消息写入另一个队列,并且同一个程序让消费者对该队列采取行动。 问题:使用 spring rabbit ampq 库异步发送消息时,如何处理队列的网络超时问题?或者如果存在网络问题,RabbitTemplate.send() 函数必须抛出异常。 目前,我已经立即实施了 RabbitTemplate.send() returns 并且工作正常。但是,如果网络出现故障,立即发送函数 returns,不会抛出任何异常并且客户端代码假定成功。结果,我在数据库中的状态不一致,消息已成功处理。请注意,对发送函数的调用包含在事务块中,目标是如果队列写入失败,数据库提交也必须回滚。我正在探索以下解决方案但没有成功:
我们能否将 rabbitTemplate 配置为在出现任何网络连接问题时抛出 运行 次异常,以便通知客户端调用?请建议如何执行此操作。
要不要用同步的SendAndReceive函数调用,但是会导致处理延迟?使用此函数观察到的另一个问题是,我的消费者代码收到通知,而 sendAndReceive 函数仍被阻止以将消息写入队列。请告知我们是否可以延迟通知队列,除非 sendAndReceive 函数是 returned。但是如果网络出现故障,调用 SendAndReceive() 会抛出一个 amqp 异常,我们能够捕获它,但它的成本与性能相关。 我的应用程序是多线程的,如果多个线程正在使用 sendAndReceive() 发送消息,spring-amqp 库如何管理队列通信?它是否在内部根据请求创建频道?如果消息通过相同的通道传递,这将对多线程应用程序的性能产生很大影响。
有人可以分享使用 SendAndReceive 函数的最佳实践示例代码吗?
我们在 spring-amqp 库中是否有任何函数可以在提交发送函数调用之前检查 RabbitMQ 服务器的健康状况?我探索了 rabbitTemplate.isRunning() 但没有得到正确的结果。如需具体配置,请提出建议。
要考虑的保证消息传递或处理网络超时问题以向客户端抛出 运行时间异常的任何其他解决方案..
根据下面的 Gary 评论,我设置了:rabbitTemplate.setChannelTransacted(true);它使通话同步。问题的下一部分是,如果我在外部块上有事务块,请立即调用 RabbitTemplate.send() returns。我希望外部函数的事务块必须等待内部函数 return,否则,虽然我们将 setChannelTransacted 启用为 true,但我的数据库更改仍然存在,因此无法获得预期结果。我尝试了各种事务传播级别但没有成功。如果我做错了什么请告知并检查交易传播设置如下
@Transactional
public void notifyQueueAndDB(DBRequest dbRequest) {
logger.info("Updating Request in DB");
dbService.updateRequest(dbRequest));
//Below is call to RabbitMQ library
mqService.sendmessage(dbRequest); //If sendMessage fails because of network outage, I want DB commit also to be rolled-back.
}
MQService 在另一个项目库中定义,下面是代码片段。
@Transactional( propagation = Propagation.NESTED)
private void sendMessage(......) {
....
rabbitTemplate.send(this.queueExchange, queueName, amqpMessage);
}catch (Exception exception) {
throw exception
}
- 启用事务以便同步发送。
或
- 使用 Publisher 确认并等待收到确认。
任何一个都会慢很多。