【问题标题】:How to setup RabbitMQ RPC in a web context如何在 Web 上下文中设置 RabbitMQ RPC
【发布时间】:2013-07-21 18:22:09
【问题描述】:

RabbitMQ RPC

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

我的设置

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

问题

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

另类

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

问题

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

【问题讨论】:

  • 我刚刚在 Java RabbitMQ jar 中发现了提供的 RpcClientRpcServer。即使使用这些,Tomcat 也无法正常关闭。

标签: java tomcat rabbitmq rpc


【解决方案1】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    相关资源
    最近更新 更多