2012-10-01 61 views
5

我正在設計一個將在OSGi容器(當前是Equinox)中運行的應用程序。它將通過RabbitMQ接收消息並在內部處理它們。該應用程序將作爲服務器不斷運行。我目前的計劃是讓RabbitMQ監聽器軟件包使用QueueingConsumer並在自己的線程中運行,配置其隊列並將監聽器放置在其上。監聽器會調用一個或多個處理服務來處理這些消息。處理器需要進行JDBC調用來訪問數據庫。我希望能夠控制處理器的調用順序。如果能夠靈活地在稍後添加更多服務而不必重新編碼RabbitMQ監聽器,那將是非常好的。在使用PreparedStatement時使用RabbitMQ設計Java OSGi應用程序

我面臨的問題是消息可能會以突發或緩慢的方式出現。我希望能夠使用PreparedStatement來加速數據庫訪問,但我也不想長時間保持連接,而沒有任何事情發生。我曾考慮直接對DefaultConsumer進行子類化,並讓它在RabbitMQ Connection的線程上運行,但後來我失去了知道什麼時候什麼事情都沒有的能力。我最初的想法是保持消息處理器與OSGi服務完全分離,並且每次調用時都從池中獲取數據庫連接,但是失去了預準備語句的優勢。我正在使用Tomcat JDBC池,它似乎沒有準備好語句緩存。另外,我不確定爲每次電話會議創建一個準備好的聲明有多昂貴,但這似乎很浪費。

到目前爲止我想到的最好的想法是讓我的偵聽器在雙循環中進行處理。外層循環等待消息,然後調用建立數據庫連接和準備語句的內部循環,並運行直到沒有更多消息進入指定的超時,然後關閉其連接並返回到外部循環。我得到了這個工作的一點點處理,但如果我有多個處理器可能有不同的預處理語句,我可以想象如何管理這個。

也許我必須放棄多種服務的想法,並將處理硬編碼到聽衆中。

有什麼建議嗎?謝謝!

回答

1

爲什麼不使用服務作爲偵聽器並將它們傳遞給它們應該使用的JDBC連接?一段代碼然後將隊列分派給您的服務。這個中央調度程序可以簡單地維護一個準備好的JDBC連接池。如果您不想在API中看到JDBC連接,請使用協調器服務來保持連接。然後,「感知」服務可以獲得優化的JDBC連接。

或者,將DataSource註冊爲偵聽器服務的服務並實施您自己的池策略。由於您在OSGi服務調用中知道調用者,因此可以進行各種優化,例如從bundle的jar中讀取準備好的語句並相應地緩存它們。

我不會放棄在這裏的服務,你得到的解耦是偉大的,我從經驗中知道。由於在這個模型中,服務監聽器不依賴於RabbitMQ,所以你可以很容易地測試它們和/或切換到另一種隊列技術。

然後再次,在這些情況下,最好的辦法是做最簡單的解決方案,你可以想出。如果您遇到性能問題,請評估並修復瓶頸。一個瘋狂的努力浪費在過早的解決方案上......我可以告訴你,我浪費了我的時間,有一些愚蠢的過早優化。

+0

謝謝。我幾乎是一個OSGi新手​​,在嚴重敲門的學校學習。我對Coordinator服務不熟悉,但我會檢查它。自從我發佈這篇文章以來,我已經有了註冊服務創建者而不是服務的想法。調用者可以使用它們來創建真實的服務,使他們能夠「及時」創建準備好的語句,在活動爆發期間使用它們,並在發生暫停時關閉它們。 –

+0

我檢查了我運行的Equinox版本,但沒有看到協調器服務。有什麼特別的,我必須做,讓它運行?我想我正在使用版本4版本4.3。 –

+0

我相信*協調器服務*是指*「單個代碼[派遣隊列到您的服務」*。我從來沒有聽說過任何稱爲* Coordinator *的標準OSGi服務。 –