2010-02-24 50 views
10

我的應用程序發出Web服務請求;有一個供應商將處理的請求的最大速度,所以我需要扼殺他們。我可以限制分佈式應用程序提出的請求嗎?

當應用程序在一臺服務器上運行,我用在應用層面做到這一點:持續跟蹤多少請求迄今取得的對象,並等待如果當前的請求使得它超過了允許的最大值加載。

現在,我們正在從一個單一的服務器羣集遷移,所以有運行應用程序的兩個副本。

  • 我無法繼續檢查應用程序代碼處的最大負載,因爲兩個節點的組合可能會超過允許的負載。
  • 我不能簡單地減少每個服務器上的負載,因爲如果其他節點空閒,第一個節點可以發出更多請求。

這是一個JavaEE的5環境。抑制應用程序發出請求的最佳方式是什麼?

+2

只是好奇,你使用像Terracota這樣的特殊框架嗎? – 2010-02-24 21:21:21

+0

@Pablo:不。我們正在從專用服務器上的單個JBoss服務器遷移到配置了兩個節點的託管WebLogic 10.3。 – Leonel 2010-02-25 01:28:07

回答

5

由於您已經在Java EE環境中,因此您可以創建一個MDB,該MDB根據JMS隊列處理所有對webservice的請求。應用程序的實例可以簡單地將其請求發佈到隊列中,MDB將接收它們並調用web服務。

該隊列實際上可以配置適當數量的會話,這會限制併發訪問您的webservice,因此您的限制通過隊列配置來處理。

結果可以通過另一個隊列(或者每個應用程序實例的一個隊列)返回。

+0

是的,因爲我已經在JavaEE環境中,所以JavaEE隊列是最直接的解決方案,我不需要添加任何其他依賴項。 – Leonel 2010-03-08 13:52:01

1

許多這樣做的方法:你可能有一個「協調代理」,這是負責的移交「令牌」的服務器。每個「令牌」表示執行任務等的權限。每個應用程序需要請求「令牌」以發出呼叫。

一旦應用程序耗盡它的令牌時,必須在繼續又打了Web服務之前要求更多一些。

當然,這一切又當有與問候每個應用使得對,因爲Web服務的併發調用每一個的時序要求複雜。

您可以依賴於RabbitMQ作爲消息傳遞框架:Java綁定可用。

+0

+1,因爲我不知道也有.net綁定的RabbitMQ。 – tobsen 2010-02-24 22:35:04

1

N個節點需要通信。有各種策略:

  • 廣播:每個節點將廣播給其他人,它正在呼叫一個電話,所有其他節點將考慮到這一點。節點是相等的並且保持個別的全局計數(每個節點知道每個其他節點的呼叫)。
  • 主節點:一個節點是特殊的,其主節點和所有其他節點在進行呼叫前向主節點請求許可。主人是唯一知道全球人數的人。
  • 專用主:同主人,但「主」的itslef沒有做電話,僅僅是跟蹤電話的服務。

根據您預計稍後放大多少,一個或另一個策略可能是最好的。對於2個節點,最簡單的節點是廣播節目,但隨着節點數量的增加,問題開始出現(你將花費更多的時間來廣播和響應廣播,而不是實際執行WS請求)。

節點之間的溝通方式取決於你。你可以打開一個TCP管道,你可以廣播UDP,你可以單獨爲這個目的做一個完全成熟的WS,你可以使用文件共享協議。無論您做什麼,您現在都不再處於流程中,因此所有fallacies of distributed computing都適用。

1

這是一個有趣的問題,解決方案的難度取決於您希望節流的程度。

我通常的解決方案是JBossCache,部分原因是它與JBoss AppServer打包在一起,但也因爲它處理任務相當好。您可以將其用作一種分佈式哈希映射,以不同程度的粒度記錄使用情況統計信息。對它的更新可以異步完成,所以它不會減慢速度。

JBossCache通常用於重型分佈式緩存,但我更喜歡這些輕量級作業。它是純Java的,並且不需要使用JVM(與Terracotta不同)。

2

我建議使用beanstalkd定期將一系列請求(作業)抽成管(隊列),每個請求(作業)都有適當的延遲。任何數量的「工人」線程或進程都會等待下一個請求可用,並且如果工作者提前結束,它可以接收下一個請求。不利的一面是工人之間沒有任何明確的負載平衡,但我發現請求的隊列分配非常均衡。

0

Hystrix專爲您描述的確切場景設計。您可以爲每個服務定義一個線程池大小,以便設置最大數量的併發請求,並在池滿時對請求進行排隊。您還可以爲每個服務定義一個超時,並且當服務開始超過超時時間時,Hystrix會在短時間內拒絕對該服務的更多請求,以便讓服務有機會恢復原狀。還有通過Turbine實時監控整個羣集。

相關問題