java - 如何在 Web 上下文中设置 RabbitMQ RPC

标签 java tomcat rabbitmq rpc

RabbitMQ 远程过程调用

我决定按照描述使用 RabbitMQ RPC here .

我的设置

传入的 Web 请求(在 Tomcat 上)将通过 RabbitMQ 将 RPC 请求分派(dispatch)到不同的服务并组合结果。我将一个回复队列与一个自定义消费者一起使用,该消费者监听所有 RPC 响应并将它们与它们的相关 ID 一起收集在一个简单的 HashMap 中。那里没什么好看的。 这在 Controller 级别的简单集成测试中效果很好。

问题

当我尝试在部署在 Tomcat 上的 Web 项目中执行此操作时,Tomcat 拒绝关闭。 jstack 和一些调试让我了解到一个线程被生成以监听 RPC 响应并阻止 Tomcat 正常关闭。我猜这是因为创建的线程是在应用程序级别而不是请求级别创建的,并且不受 Tomcat 管理。当我在 Servlet.destroy()ServletContextListener.contextDestroyed(ServletContextEvent sce) 中设置断点时,它们没有到达,所以我看不到手动清理的方法。

备选

作为替代方案,我可以为每个 Web 请求使用一个新的回复队列(和简单的 QueueingConsumer)。我已经对此进行了测试,它可以正常工作并且 Tomcat 会正常关闭。但我想知道这是否是要走的路.. RabbitMQ 集群可以处理数千(甚至数百万)的短期生存队列/消费者吗?我可以想象队列不是那么大,但仍然......不断向所有集群节点广播......总内存占用......

问题

简而言之,为每个传入的 Web 请求创建一个队列是否明智,或者我应该如何使用一个队列和一个消费者设置 RabbitMQ,以便 Tomcat 可以正常关闭?

最佳答案

我找到了解决问题的办法:

Java 客户端正在创建自己的线程。创建新连接时,可以添加您自己的 ExecutorService。在 ServletContextListener.initialized() 方法中这样做,可以跟踪 ExecutorService 并在 ServletContextListener.destroyed() 中手动关闭它> 方法。

executorService.shutdown();
executorService.awaitTermination(20, TimeUnit.SECONDS);

我使用了 Executors.newCachedThreadPool(); 因为线程有很多短执行,当空闲超过 60 秒时它们会被清理。

这是 link到 RabbitMQ Google 组线程(感谢 Michael Klishin 向我展示了正确的方向)

关于java - 如何在 Web 上下文中设置 RabbitMQ RPC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17797357/

相关文章:

tomcat - 如何在 WAR 应用程序中为嵌入式 axis2 指定 axis2.xml 的相对路径

rabbitmq - 如何通过 RabbitMQ 发送类似 word 的文件

python - 如何查看rabbitmq队列中推送的所有celery任务

java - 尝试在 Raspberry Pi 上运行基于 SWT 的 GUI

java - 如何使用 EAR 中提供的依赖项取代 Glassfish 内置库?

java - JSF/莫贾拉 2.0.2 : ui:repeat is totally broken when updating via AJAX

java - Tomcat 不会从 HTTP 重定向到 HTTPS

android - 谷歌应用引擎,gradle,开放端口

windows - 新安装后 RabbitMQ 节点关闭

java - 如何制定 Hibernate 标准以仅引入需要的字段