使用PreparedStatement时使用RabbitMQ设计Java OSGi应用程序

时间:2012-10-01 22:10:21

标签: java jdbc osgi rabbitmq

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

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

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

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

有什么建议吗?谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

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

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