5

我正在设计一个将在 OSGi 容器(目前是 Equinox)中运行的应用程序。它将通过 RabbitMQ 接收消息并在内部处理它们。该应用程序将作为服务器持续运行。我目前的计划是让 RabbitMQ 侦听器包配置其队列并在其上放置侦听器,使用QueueingConsumer并在它们自己的线程中运行。侦听器将调用一个或多个处理服务来处理消息。处理器需要进行 JDBC 调用才能访问数据库。我希望能够控制调用处理器的顺序。如果以后可以灵活地添加更多服务,而不必重新编码 RabbitMQ 侦听器,那就太好了。

我面临的问题是消息可能会以突发或缓慢的形式出现。我希望能够使用它PreparedStatement来加速数据库访问,但我也不想在没有任何事情发生的情况下长期保持连接打开。我曾考虑过DefaultConsumer直接子类化并让它在 RabbitMQ 的线程上运行Connection,但后来我失去了知道什么时候什么都没有发生的能力。我最初的想法是让消息处理器与 OSGi 服务完全分离,并在每次调用时都从池中获取数据库连接,但这失去了预准备语句的优势。我正在使用 Tomcat JDBC 池,它似乎没有准备好语句缓存。此外,我不确定为每次调用创建准备好的语句会有多昂贵,但这似乎很浪费。

到目前为止,我想出的最好的想法是让我的听众在一个双循环中处理。外部循环等待消息,然后调用内部循环建立数据库连接和准备好的语句并运行,直到在指定的超时时间内没有更多消息进入,然后关闭其连接并返回到外部循环。我让它可以进行一次处理,但是如果我有多个可能有不同准备好的语句的处理器,我很难想象如何管理这个。

也许我不得不放弃多个服务的想法,并将处理过程硬编码到我的听众中。

有什么建议么?谢谢!

4

1 回答 1

1

为什么不将服务用作侦听器并将它们应该使用的 JDBC 连接传递给它们呢?然后,一段代码将队列分派给您的服务。这个中央调度器可以轻松地维护一个准备好的 JDBC 连接池。如果您不想在 API 中看到 JDBC 连接,请使用 Coordinator 服务来保持连接。然后,“Aware”服务可以获得优化的 JDBC 连接。

或者,将 DataSource 注册为侦听器服务的服务并实施您自己的池策略。由于您知道 OSGi 服务调用中的调用者,因此您可以进行各种优化,例如从包的 jar 中读取准备好的语句并相应地缓存它们。

我不会放弃这里的服务,你得到的解耦很棒,我从经验中知道。由于在此模型中服务侦听器不依赖于 RabbitMQ,您可以轻松地测试它们和/或切换到另一种队列技术。

再说一次,在这些情况下,最好的办法是做你能想到的最简单的解决方案。如果您遇到性能问题,请测量并修复瓶颈。过早的解决方案浪费了大量的精力......我可以告诉你很多愚蠢的过早优化我已经浪费了我的时间。

于 2012-10-02T06:44:55.827 回答