2013-03-03 46 views
0

我們有一個異步JMS消息傳遞系統的同步HTTP請求 - 響應前端。如何從JMS中讀取和收集響應消息,並使它們可用於正確的servlet線程?

每個HTTPRequest的HTTP查詢servlet在查詢隊列中創建相應的JMS消息。該查詢由後端處理,併爲此查詢創建一對應答消息。在JMS中組織接收響應消息並確保他們到達正確的servlet線程以便能夠制定HTTPResponse的好方法是什麼?

查詢和響應是非事務性的,不需要持久化。他們大多數是閱讀查詢。如果在45秒內沒有讀取響應,則servlet會生成超時響應。吞吐量很重要,但是。我們需要處理越來越多的查詢。這個系統已經有十年的歷史了,而且還需要再維持兩年左右的時間。

我們正在使用SonicMQ。我們爲所有回覆創建了一個隊列。 servlet容器有一個連接到它用於讀寫的代理。我們爲每個登錄用戶生成一個監聽器線程(大約1500個併發)此線程有一個接收器和一個消息選擇器,該選擇器僅爲該特定用戶選擇響應消息。一旦servlet線程發送了它的查詢消息,它就會等待用戶的偵聽器線程通知它它已經讀取了一個響應。

我們曾經有一個由所有發送者和所有接收者共享的QueueSession。這實際上工作(!),雖然會議正式不是線程安全的。每個線程(servlet線程和偵聽器線程)創建一個QueueSession可以在一定程度上提高性能,但事情仍然不太穩定,我們希望更好地組織。

我試過每個用戶會話創建一個臨時隊列,而不是使用消息選擇器的單個隊列,但這會顯着減慢事物的速度。

什麼會更好/正確的方式來組織這個?

+0

將JMS從等式中移除選項,還是您必須與此後端系統交互的「途徑」? – 2013-03-03 22:47:24

+0

@RyanStewart後端當前由單獨的JVM組成,這些JVM從查詢隊列中讀取,執行查詢並將響應消息發佈到客戶端隊列。這確實有一定的優勢,這是一個微型巴士。系統需要運行2年左右。所以極端的改變是不可能的。將查詢執行移入tomcat(servlet容器)是我們已經討論過的,但並不是非常有信心。你認爲我們應該? – flup 2013-03-03 23:31:10

回答

1

我開始這個評論,但它增長。

從您的描述來看,聽起來每個請求都需要至少兩個線程,可能更多。如果你已經有1500個併發用戶,並且你的查詢有足夠的工作需要將它們傳播到其他節點,那麼我認爲你已經進入了危險的領域,只要有多少活動線程能夠有效地運行JVM沒有太多的CPU /內存分配和一些嚴重的設置調整。

我對移除JMS的評論是因爲從你的應用程序的servlet一方,你只是做了很多額外的工作,使JMS成爲一個同步的請求/響應機制,當一個簡單的線程池也可以爲能夠響應HTTP請求運行多個併發查詢。這聽起來像JMS是後端接收工作請求的一種體面的方式,但是,重要的重寫可能並不值得。

我認爲一個更好的方法來組織這將是一組每個tomcat實例的消費者,而不是每個請求線程的消費者。每個Webhead可以有自己的響應隊列,或者在一個隊列上使用MessageSelectors。然後,當請求進入時,發送一個請求JMS消息,並讓消費者回調到調用線程,如SynchronousQueue,調用者正在等待take()。如果您必須等待多條消息才能提供單個請求,則可能需要合併ConcurrentLinkedQueue,以便在響應全部收到時使用CountdownLatch放棄響應,以發出請求線程的信號。這樣,你可以有一小部分線程負責接收消息。我覺得應該有些東西可以幫助你解決這個問題,但我想不到任何東西。

之後,如果您仍然發現性能問題,可以通過添加tomcat實例或查看非阻塞IO進行HTTP請求處理,將相同的策略應用於前門和後端:使用一個小的線程池來處理一個大的請求量,在這個線程中,等待正在按線程請求模式捆綁很多線程。

+0

我們的系統管理員報告說服務器不是太忙。這是將工作分配給傾斜的線程並且他們餓死了。我們可以得到第二臺服務器,如果這是絕對必要的,我懷疑,但是如果我們能夠重新組織那些更好的線程。所以調整就是我們正在碰到的事實。我同意,每個用戶一個線程是愚蠢和浪費的,這需要減少。我注意到每個聲音連接都有一個發送者和監聽者線程,所以也許我可以建立單個tomcat實例的連接? – flup 2013-03-04 07:13:39

+1

不知道我是否完全理解你在說什麼聲波線程,但我肯定會使用[spring-jms](http://static.springsource.org/spring/docs/current/spring- framework-reference/html/jms.html),這使得JMS能夠以一種有效的方式工作非常簡單,例如爲生產者和消費者緩存連接和會話,以及在隊列上運行多個併發使用者與專用的線程池。當Spring可以在十幾行XML中完成時,手動完成所有這些工作只是太多工作。 – 2013-03-04 15:26:05

+0

建立連接 - >添加更多連接。我看到每個sonicmq連接都由sonicmq內部的一個線程管理。感謝spring-jms的提示! – flup 2013-03-04 18:34:04

相關問題