gpt4 book ai didi

java - 如何从 JMS 读取和收集响应消息并使它们可供正确的 servlet 线程使用?

转载 作者:行者123 更新时间:2023-12-01 14:48:06 25 4
gpt4 key购买 nike

我们为异步 JMS 消息传递系统提供了同步 HTTP 请求响应前端。

每个 HTTPRequest 的 HTTP 查询 Servlet 在查询队列中创建相应的 JMS 消息。该查询由后端处理,并为此查询创建一些响应消息。在 JMS 中组织响应消息的接收并确保它们到达正确的 servlet 线程以便它可以制定 HTTPResponse 的好方法是什么?

查询和响应是非事务性的,不需要持久化。其中大多数是读取查询。如果 45 秒内没有读取到响应,servlet 将生成超时响应。然而,吞吐量很重要。我们需要处理越来越多的查询。该系统已有大约十年的历史,还必须保持运行两年左右。

我们正在使用 SonicMQ。我们为所有响应创建了一个队列。 servlet 容器与代理有一个连接,用于读取和写入。我们为每个登录用户生成一个监听器线程(大约 1500 个并发)。该线程有一个带有消息选择器的接收器,仅选择该特定用户的响应消息。一旦 Servlet 线程发送了查询消息,它就会等待用户的监听器线程通知它已读取响应。

我们曾经有一个由所有发送者和所有接收者共享的 QueueSession。这实际上有效(!),尽管 session 正式不是线程安全的。为每个线程(servlet 线程和监听器线程)创建一个 QueueSession 在一定程度上提高了性能,但情况仍然不太稳定,我们希望更好地组织事情。

我尝试为每个用户 session 创建一个临时队列,而不是使用消息选择器创建一个队列,但这大大减慢了速度。

更好/正确的组织方式是什么?

最佳答案

我一开始是作为评论,但它的规模有所增长。

根据您的描述,听起来每个请求都需要至少两个线程,甚至可能更多。如果您已经有 1500 个并发用户,并且您的查询已经足够工作,您需要将它们分派(dispatch)给其他节点,那么我想说,就在一个节点中有效运行多少个 Activity 线程而言,您已经进入了危险的境地。 JVM 没有大量的 CPU/内存分配和一些严重的设置调整。

我关于删除 JMS 的评论是因为从应用程序的 servlet 端来看,您只是做了很多额外的工作来使 JMS 成为同步请求/响应机制,而一个简单的线程池也可以作为能够运行多个并发查询来响应 HTTP 请求。不过,听起来 JMS 是后端接收工作请求的一种不错的方式,因此可能不值得进行重大重写。

我认为更好的组织方法是每个 tomcat 实例一组消费者,而不是每个请求线程一个消费者。每个网络头可以有自己的响应队列,或者在单个队列上使用 MessageSelector。然后,当请求到来时,发送请求 JMS 消息,并为消费者留出回调调用线程的方式,例如 SynchronousQueue调用者正在等待 take()从。如果您必须等待多条消息才能处理单个请求,则可以组合 ConcurrentLinkedQueue将响应放在 CountdownLatch 上当收到所有响应时向请求线程发出信号。这样,您就可以拥有一个相对较小的线程池,负责在消息传入时接收消息。我觉得应该有一些东西可以帮助您解决这个问题,但我想不出任何即兴的东西。

之后,如果您仍然发现性能问题,您可以通过添加 tomcat 实例进行扩展,或者研究非阻塞 IO 来处理 HTTP 请求,对前门应用与后门相同的策略:使用小线程池来处理大请求量,其中等待会在每个请求线程模型中占用大量线程。

关于java - 如何从 JMS 读取和收集响应消息并使它们可供正确的 servlet 线程使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15191416/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com