簡體   English   中英

在Java中實現異步消息隊列

[英]Implementing asynchronous message queue in java

我有一個Java服務器,可以處理來自多個客戶端的登錄。 服務器為每個tcp / ip套接字偵聽器創建一個線程。 數據庫訪問由服務器創建的另一個線程處理。

目前,我已連接到服務器的客戶端數量非常少(<100),因此我沒有真正的性能顧慮,但是我正在研究將來應該如何處理更多的客戶端。 我擔心的是,對於許多客戶端,我的服務器線程和數據庫線程將因不斷從客戶端線程對其方法的調用而陷入困境。

特別是與數據庫有關:目前,每個客戶端線程都在其服務器父級上訪問公共數據庫線程,並執行一種數據訪問方法。 我認為我應該做的是擁有某種消息隊列,客戶端線程可以將其數據請求發送到數據庫,而數據庫線程在處理該請求時將執行該消息隊列。 如果有從數據訪問調用返回的數據,則可以將其放在隊列中以供客戶端線程提取。 所有這些都不會影響主服務器代碼或任何其他客戶端線程。

因此,我認為我想實現一個異步消息隊列,客戶端線程可以在該消息隊列上發送消息,並且數據庫線程將從中提取消息。 那是正確的方法嗎? 任何有關我可以閱讀的關於實現的想法和鏈接都將不勝感激。

我不推薦這種方法。

JMS就是為此而生的。 它將比您從頭開始編寫的任何實現都要好。 我建議使用內置JMS的Java EE應用服務器,或者可以將ActiveMQ或RabbitMQ之類的東西添加到Tomcat之類的servlet引擎中。

我強烈建議您在撰寫自己的文章之前先進行調查。

您所描述的聽起來像ExecutorCompletionService 從本質上講,這是一個異步任務代理,它從一個線程接受請求( RunnableCallable ),並以Future的形式將“句柄”返回給即將出現的結果。 然后,在線程池 (可以是單線程線程池 )中執行請求,然后通過Future將請求的結果傳遞回調用線程。

在提交請求和提供響應之間,您的客戶端線程將僅等待Future(具有可選的超時)。

但是,我建議您,如果希望客戶機(以及客戶機線程)的數量大大增加,則應該評估其中的某些Java NIO Server框架。 這將使您避免為每個客戶端分配一個線程,尤其是因為您希望所有這些線程都花一些時間等待數據庫請求。 如果是這樣,我建議您看一下MINANetty

干杯。

//尼古拉斯

聽起來您想做的就是限制對您要允許的數據庫的並發請求數。 (以防止它過載)

我建議您使用有限的連接池。 當太多線程想要使用數據庫時,它們將不得不等待直到連接空閑為止。 一種簡單的方法是使用BlockingQueue並預先創建所有連接。

private final BlockingQueue<Connection> connections = new ArrayBlockingQueue<Connection>(40); {
   // create connections
}

// to perform a query.
Connection conn = connections.get();
try {
    // do something
} finally {
    connections.add(conn);
}

這樣,您可以使線程設計保持原樣,並限制對數據庫的並發查詢數。 通過一些調整,您可以根據需要創建連接,並在無法快速獲取數據庫連接時提供超時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM