2011-04-01 33 views
5

我將胖客戶端代碼移植到具有精簡客戶端的服務器體系結構中。多個JVM與併發任務

服務器需要爲每個客戶端運行一個代碼實例。代碼是多線程的,運行很長時間(幾周),但只與客戶端偶爾交互。客戶數量將達到數千人。每個客戶端需要〜20MB的堆。

我現在有兩個選擇,讓所有請求,並計算在共享空間完成每個客戶端(如在

  1. 在服務器上啓動一個單獨的JVM爲每個客戶端
  2. 修改我的代碼網絡應用程序)

我可以看到每個優點和缺點。對於多個JVM:

優點:

  • 進程是分開的,如果一個掛起只是殺死它,然後重新啓動。所有其他人都不會在意。
  • 資源是有限的,這樣一個客戶端不能吃了所有的CPU /內存
  • 在幾臺機器

缺點容易分佈:

  • 完整的JRE類庫被加載多次
  • 不是Java EE的服務方式
  • 每個客戶端都需要通過一個單獨的端口進行通信嗎?

是否有您推薦的最佳實踐?

你知道關於這個主題的任何好的參考書/文章嗎?

是否有一個框架只使用一個JVM,但運行代碼的幾個副本就好像它是單獨的進程空間(資源有限等)?

回答

1

您可以創建一個Web服務/代理服務,爲每個客戶端啓動一個JVM,關閉它們。這將使您能夠從長時間運行的客戶端中終止請求/ JVM。

當服務器將請求轉發給正在運行的該客戶端的JVM時,代理服務器可以爲客戶端提供一個需要與之通話的端口。

順便說一句:如果你有很多運行CPU密集型作業的客戶端,那麼你只有很多內核可以運行。您可能會發現JVM需要跨多臺機器運行以支持所有客戶端。

3

很遺憾,不可能在單個JVM中以線程爲基礎限制資源。不過,我會nontheless嘗試端口您的應用程序到單個JVM,由於以下原因:

  • 如果一個線程使用的CPU,你仍然可以殺死它(中斷()是你的朋友),如果你正確編碼任務。
  • 如果不止一個客戶端與其他客戶端同時工作,我認爲他們必須共享CPU。
  • 線程運行數週?您應該將任務分解爲子任務,以便您可以從重新啓動中恢復並繼續工作。
  • 只有在單個應用程序中,客戶端才能共享通信服務器端口。
  • 內存消耗必須以某種方式程序化地受到限制。對於數據庫來說,這意味着查詢必須限制在固定數量的結果或類似的地方。
  • 如果每個進程只需要20MB堆,那麼單個應用程序所需的資源就會少得多。我相信每個JVM的開銷約爲30MB,調度1000個線程可能比操作系統調度1000個進程的性能更高。
  • 如果您將應用程序編碼爲通過JMX提供信息,您將免費爲您的流程提供一個監控控制檯。如果您爲每項任務啓動一個單獨的流程,則難以監控。

除非您確實無法控制用戶可以啓動哪些任務,否則請使用單一應用程序方法。