| 方案 | 優點 | 缺點 | 適用性 |
| IOCP 完成埠 | 單執行緒處理萬級連線、系統級高效能 | 程式複雜度極高、除錯困難 | 高效能伺服器、專業團隊 |
| Indy 短連線 | 程式簡單、無長連線壓力 | 500ms 頻率下頻繁建立/斷開連線極耗資源、延遲高 | 低頻率、非即時場景 |
| 多進程架構 (本文方案) | 繼承阻塞式簡單模型、線性擴展連線數、程式碼變動最小 | 進程間通訊 (IPC) 複雜度、資源總消耗較高 | 現有 Indy 專案快速擴容、團隊熟悉阻塞模型 |
多進程架構設計
核心概念
- 主進程 (Manager):監聽埠口、接受連線、負載均衡分派
- 工作進程 (Worker):實際處理客戶端連線、業務邏輯、DataSnap 服務
- 進程間通訊:Named Pipe / Shared Memory / Local TCP / WM_COPYDATA
架構圖解
[Client 1] [Client 2] ... [Client 5000]
| | |
+---------------+--------------------+
|
[主進程: Listener + Dispatcher]
|
+-----------+-----------+-----------+
| | | |
[Worker 1] [Worker 2] [Worker 3] [Worker N]
(~800連線) (~800連線) (~800連線) (~800連線)
| | | |
[DataSnap] [DataSnap] [DataSnap] [DataSnap]
關鍵實作細節
主進程:連線分派策略
// 輪詢 / 最少連線 / IP 雜湊分派
function DispatchToWorker(ClientSocket: TSocket): Integer;
var
MinConnections: Integer;
i: Integer;
begin
MinConnections := MaxInt;
Result := 0;
for i := 1 to WorkerCount do begin
if WorkerConnections[i] < MinConnections then begin
MinConnections := WorkerConnections[i];
Result := i;
end;
end;
// 透過 IPC 通知對應 Worker 接手 Socket
NotifyWorkerAccept(Result, ClientSocket);
end;
Socket 傳遞機制 (Windows)
- WSADuplicateSocket + IPC 傳遞 Socket 資訊:主進程 Accept 後,複製 Socket 描述符傳給 Worker
- AcceptEx / IOCP:進階做法,Worker 直接 Accept
- 簡化版:主進程維持連線,轉發資料 (Proxy 模式) — 開發最快但效能較低
Worker 進程:DataSnap 服務啟動
// Worker 進程啟動參數指定監聽埠口範圍或由主進程指派
// 每個 Worker 獨立運行 DataSnap 伺服器元件
procedure TWorkerProcess.Execute;
begin
// 初始化 DataSnap 元件
DSServer1.Start;
// 進入訊息迴圈處理 IPC 指令
while not Terminated do begin
ProcessIPCMessages;
Sleep(10);
end;
DSServer1.Stop;
end;
部署與運維考量
- 進程數量規劃:單機 CPU 核心數 × 2-4,每進程 600-800 連線
- 健康檢查:主進程定期檢查 Worker 存活,自動重啟異常進程
- 優雅關閉:訊號通知 Worker 停止接受新連線、處理完現有請求再退出
- 日誌聚合:多進程日誌集中收集 (如 Log4D + UDP/Appender)
- 設定外部化:連線數限制、埠口範圍、IPC 方式皆可配置化
遷移路徑建議
- 現有單進程 Indy DataSnap 專案
- 抽離業務邏輯為共用單元 (Business Logic Layer)
- 建立 Worker 進程專案,引用共用邏輯
- 建立 Manager 進程,實作 Accept + 分派
- 實作 Socket 傳遞 (WSADuplicateSocket + Named Pipe)
- 壓力測試驗證 5,000 連線穩定性
- 生產環境灰度發布
結語
多進程架構以最小代碼變更、繼承既有阻塞模型優勢,線性解決 TCP 長連線數量瓶頸。適合團隊熟悉 Indy/DataSnap、需快速擴容的專案。長期演進建議評估 IOCP 或遷移至支援原生非同步的框架 (如 mORMot、Node.js、Go、.NET Core Kestrel)。
- 上一篇文章: Delphi XE3 程式碼自動提示失效問題解決方案
- 下一篇文章: Windows 進程最大執行緒數限制深度解析
Copyright ©
程式碼之家 All Rights Reserved