首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實作 LRWP 協議超越 C 語言:GlassFish 上的高效能 Web 處理實戰

     編輯:Java 相關知識

背景與動機

多執行緒應用滿足業務增長並減少系統數量,但不可並發的串行代碼限制擴展性(參見阿姆達爾定律與 I/O 問題)。先前嘗試用 Solaris Zones 運行多副本 Xitami/NexSRS 提升效能,但非根治。決定在 Java 中實作 LRWP (Long Running Web Process) 協議並部署於 GlassFish,目標:小系統效能逼近 C 語言寫的 Xitami/NexSRS,大系統擴展性更優。

成果亮眼:Java 反超 C

圖 1:Xitami/C 與 GlassFish/Java 的可伸縮性比較

  • 單核系統:Java 實作具 23% 效能優勢
  • 4 核系統:Java 實作具 78% 效能優勢
  • Xitami 擴展至 4 核僅達 ~15K CPM,GlassFish/Java 達 27K+ CPM

展現從單核到多核的優異擴展性。

LRWP 協議解析

Xitami 用 LRWP 與對等體通訊。類似 CGI:Web 客戶請求 `cgi-bin/context`,容器調用可執行程式傳入輸入、回傳輸出。LRWP 中,對等體與代理建立 TCP 連線,對等體註冊感興趣的 Web Context(如 `/osp`、`/tep`)。請求命中該 Context 時代理轉發輸入給對等體,將回應返回客戶。代理可同時支援多對等體(多執行緒或多進程)。

Java 實作架構

使用 Java 實現 LRWP

  • 選擇 GlassFish(開源 Java EE 應用伺服器,基於 Tomcat)處理 HTTP。
  • Servlet 監聽請求,轉給容器內 LRWP 代理。
  • 代理註冊對等體 Context,匹配請求時:Servlet 執行緒進入 Context 鎖定休眠,代理轉發請求給對等體,等待回應,喚醒 Servlet 執行緒返回客戶。

實作為監聽 `/*` 的 Web 應用:註冊 Context 的請求轉發給對等體;未註冊的交給預設 Servlet 處理。對等體透過 LRWP 協議向代理註冊,建立 `LRWP RequestHandler` 連線,可註冊多 Context、建立多連線實現負載平衡。

整合 NexSRS (OSP 伺服器)

圖 2:UsageConfirmation 消息

OSP (Open Settlements Protocol) 為 VoIP 國際標準,提供 IP 通訊安全機制。NexSRS 為多執行緒 OSP 伺服器兼 LRWP 對等體。流程:

  1. 源閘道發送授權請求給 OSP 伺服器獲取目標 IP 與數位簽章令牌。
  2. 目標閘道驗證令牌建立呼叫。
  3. 呼叫結束雙方發送 `UsageIndication`,OSP 回覆 `UsageConfirmation`。

NexSRS 連接 LRWP 代理 (`HOSTNAME:1081`),註冊 `/osp`、`/tep`、`/cgi-bin` 等 Context,各 Context 獨立執行緒處理。代理匹配 URL 如 `https://hostname:1080/osp` 轉發給對應對等體。

效能優化實戰

1. LRWP 代理代碼優化

  • 採用容器執行緒模型:捨棄多執行緒伺服器設計,改用 Servlet 執行緒直接轉發請求、等待回應、返回客戶。代理僅維護單一接受連線執行緒建立 `RequestHandler`。
  • 替換 Vector 為 ContextAssistantManager:原用 `Vector` 同步列表迭代查找 Handler 成瓶頸。新管理器追蹤使用中 Handler,相同 Context 請求讓 Servlet 執行緒休眠,避免增刪 Handler 開銷。
  • 避免多副本:函數回傳值直接賦值給變數判斷,避免重複呼叫產生多物件。
  • 避免位元組陣列分配:網路傳輸改用 `ByteBuffer` 直接映射緩衝區,配合 `CharBuffer` 建立視圖,取代 `StringBuffer`/`String` 轉換開銷。

2. GlassFish 調優

  • Grizzly HTTP Connector:預設非阻塞 NIO,2-5 執行緒。調整為 10 執行緒達最佳效能。增加連線池容量、Keep-Alive 連線數 (`max-connections=10000000`)。解決 Keep-Alive 問題:設 `TCP_TIME_WAIT_INTERVAL=1000`、增加檔案描述符限制。
  • GC 調優:採用 Parallel GC (`-XX:+UseParallelGC`),Heap 設 3400MB (`-Xms3400m -Xmx3400m`),Young Generation 256MB (`-Xmn256m`)。Parallel GC 消除預設 GC 暫停,效能達 27K CPM。Heap 增至 7GB 可進一步提升(未測 64 位 JVM 組合)。

3. Solaris 核心參數調優

$ndd -set /dev/tcp tcp_time_wait_interval 1000
$ndd -set /dev/tcp tcp_conn_req_max_q 10000
$ndd -set /dev/tcp tcp_conn_req_max_q0 10000
/etc/system 新增:
set ip:ipcl_conn_hash_sizes=10000
set tcp_ip_abort_interval=500

這些調整將效能從 4500 CPM 大幅提升,解決 Keep-Alive 相關問題。

效能測試環境與數據

  • 負載生成:Sun Fire V280 (2 CPU) + ApacheBench 三實例並發測試。
  • 測量:修改 `nexus.log` 獲取 CPM 轉 CPS,ApacheBench 輸出對照驗證。
  • 系統:x4100 (雙核雙插槽, 8GB, 2.6GHz) + Solaris 10,用 `psradm` 控制核心數。
核心數Xitami/NexSRS CPMCPU% (nexus/Xitami)GlassFish/NexSRS CPMCPU% (nexus/GlassFish)
18,57553 / 4510,56968 / 28
212,88044 / 3420,57866 / 26
415,47031 / 2127,24643 / 21

結論:GlassFish/Java 全面超越 Xitami/C(單核 23%、四核 76% 優勢)。GlassFish 平均 CPU 使用率從單核 68% 降至四核 43%,Xitami 從 45% 降至 21%。NIO 支援讓 GlassFish 使用更少 CPU 時間,賦予 NexSRS 更佳擴展性。增加 Heap 仍可在 64 位 JVM 獲更大提升空間。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved