2009-10-10 158 views
2

請稍等。無狀態阻塞服務器設計

我設計,將具備以下功能的無狀態服務器:

  1. 客戶端作業提交給服務器。
  2. 客戶端在服務器嘗試執行作業時被阻止。
  3. 服務器會產生一個或多個線程來執行作業。
  4. 作業完成,超時或失敗。
  5. 創建適當的響應(基於結果),客戶端被解鎖並且響應被交給客戶端。

這是我到目前爲止想到的。

  1. 客戶端提交作業到服務器。
  2. 服務器爲作業分配一個ID,將作業放在一個隊列上,然後將客戶端放在另一個隊列上(它將被阻塞)。
  3. 有一個將執行作業的線程池,獲取結果並適當地創建響應。
  4. 根據ID,將客戶端從隊列中取出(從而解除阻塞),給出響應並將其發送出去。

步驟1,3,4看起來很直接,但有關如何將客戶端放入隊列然後將其阻止的任何想法。此外,任何可以幫助我設計這隻小狗的指針將不勝感激。

乾杯

回答

2

爲什麼你需要阻止客戶端?似乎更容易立即返回(幾乎)(執行初始驗證後,如果有的話),併爲客戶提供給定作業的唯一ID。客戶端然後可以使用所述ID進行輪詢,或者可以提供回調。

阻塞意味着你堅持套接字,這明顯限制了你可以同時服務的客戶端的數量上限。如果這不是您的場景所關心的問題,並且您絕對需要阻止(也許您無法控制客戶端代碼並且無法進行輪詢?),則除非您真的能夠將它分離爲並行任務。在這種情況下,唯一的「隊列」就是普通線程池所擁有的隊列。工作流將主要是:

  1. 創建一個線程池(如ThreadPoolExecutor
  2. 對於每個客戶端請求:
    1. 如果你有,你可以並行執行任務的任何部分,代表他們去游泳池。
    2. 和/或在當前線程中執行它們。
    3. 等待,直到合併的作業部分完成(如果適用)。
    4. 將結果返回給客戶端。
  3. 關閉線程池。

本身不需要ID;儘管您可能需要使用某種latch以上2.1/2.3。

超時可能有點棘手。如果你需要他們精確或多或少,你必須保持你的主線程(接收到客戶端請求的線程)不工作,並在超時達到時立即返回信號提交作業部分(通過翻轉標誌)並立即返回。您必須定期檢查該標誌,並在翻轉後終止執行;游泳池將回收線程。

+0

感謝ChssPly76。 到目前爲止,我只知道服務器的功能是什麼。客戶端如何連接到服務器仍然在爭論中(在工作上通過我的權力)。如果他們選擇Web服務,我不會感到驚訝。 – CaptainHastings 2009-10-10 02:37:02

0

您如何與客戶溝通?

我建議您創建一個對象來表示包含作業參數以及到達客戶端的套接字(或其他通信機制)的每個作業。線程池隨後將發送響應以在作業處理結束時解除對客戶端的阻止。

0

超時會有點棘手,並且會有隱藏的陷阱,但基本設計似乎很簡單,編寫一個在構造函數中使用Socket的類。在socket.accept上,我們只是做了一個新的套接字處理實例化,具有高瞻遠矚和可擴展性的規劃,或者如果這是一個實驗臺測試實驗,那麼套接字處理類就會轉到數據處理的東西上,當它返回時,排序布爾或數字的狀態或東西,方便的地方爲null順便說一句,乙醚寫入成功的輸出流從套接字或通知客戶端超時或任何您的業務需求是

如果你必須有對於長時間運行的重型卡車來說是一個可擴展的,有效的設計,直接轉向nio ......像我描述的手工編碼的一次性解決方案可能不會很好地擴展,但會爲nio設計的代碼正確的工作提供基本的概念化基礎。

(對不起鄉親,我想直接在代碼中 - 然後設計模式應用到它的代碼是工作之後有什麼不託起被返工的話,不是之前)

+0

@ ChssPly76 - 是的,棘手,而不僅僅是一點點。聽起來像op有一個自定義的「for nio」問題。 – 2009-10-10 01:44:55