前言
共用伺服器透過**連線池機制**支援大量並發連線。理解調度器、請求/回應佇列、共用伺服器池的交互流程,是配置 `DISPATCHERS`/`SHARED_SERVERS` 參數、診斷佇列等待的前提。
一、核心組件與職責
| 組件 | 進程名稱 | 職責 | 關鍵參數 |
| Listener | tnslsnr | 接收連線請求,轉派至調度器 | listener.ora |
| 調度器 | D000, D001... | 接收客戶請求 → 放入請求佇列 → 從回應佇列取結果 → 回傳客戶 | DISPATCHERS |
| 請求佇列 | SGA 內 | 存放待處理的客戶請求 (SQL 文本、綁定變數等) | - |
| 共用伺服器 | S000, S001... | 從請求佇列取請求 → 執行 SQL → 結果放入回應佇列 | SHARED_SERVERS, MAX_SHARED_SERVERS |
| 回應佇列 | SGA 內 | 存放共用伺服器處理結果 (結果集、狀態碼) | - |
二、請求處理完整流程
┌─────────────┐ 1. 發送請求 ┌─────────────┐
│ Client │ ──────────────────► │ Dispatcher │
└─────────────┘ └──────┬──────┘
│
▼ 2. 放入請求佇列 (SGA)
┌─────────────────┐
│ Request Queue │ ◄─── 共用伺服器池
└────────┬────────┘
│
3. 空閒共用伺服器取出請求
│
▼
┌─────────────────┐
│ Shared Server │
│ - 解析/執行 SQL │
│ - 存取 SGA/磁碟 │
└────────┬────────┘
│
▼ 4. 結果放入回應佇列
┌─────────────────┐
│ Response Queue │
└────────┬────────┘
│
5. 調度器取出結果
│
▼
┌─────────────────┐
│ Dispatcher │
└────────┬────────┘
│
6. 透過網路回傳客戶
│
▼
┌─────────────┐
│ Client │
└─────────────┘
三、關鍵差異:專用 vs 共用
| 層面 | 專用伺服器 | 共用伺服器 |
| 客戶通訊對象 | 直接與專用伺服器進程 | 與調度器通訊,**不直接**接觸共用伺服器 |
| 進程/執行緒模型 | 一 Session 一進程 | 多 Session 共用固定進程池 |
| UGA 位置 | PGA 內 | SGA Large Pool 內 |
| 記憶體效率 | 低 (N × PGA) | 高 (共用 PGA + SGA UGA) |
| 擴展性 | 受限於 OS 進程上限 | 支援萬級並發連線 |
| 適用場景 | 長連線、批次、複雜操作 | Web 應用、短連線、連線池 |
四、參數配置指南
1. 啟用共用伺服器 (最小配置)
ALTER SYSTEM SET shared_servers = 5 SCOPE=BOTH; -- 初始共用伺服器數
ALTER SYSTEM SET max_shared_servers = 50 SCOPE=BOTH; -- 最大共用伺服器數
ALTER SYSTEM SET dispatchers = '(PROTOCOL=TCP)(DISPATCHERS=3)' SCOPE=BOTH;
-- 或完整語法:
ALTER SYSTEM SET dispatchers =
'(PROTOCOL=TCP)(DISPATCHERS=3)(CONNECTIONS=1000)(SESSIONS=4000)(TICKS=10)(POOL=ON)'
SCOPE=BOTH;
2. DISPATCHERS 參數詳細語法
dispatchers = '(PROTOCOL=tcp|tcps|ipc|sdps)
(DISPATCHERS=初始數)
(MAX_DISPATCHERS=最大數)
(CONNECTIONS=每調度器最大連線)
(SESSIONS=每調度器最大 Session)
(TICKS=網路事件檢查間隔)
(POOL=ON|OFF 連線池)
(MULTIPLEX=ON|OFF 會話多工)
(LISTENER=Listener 別名清單)
(SERVICE=服務名清單)
(PRESENTATION=RO|TTS 表示協議)'
3. 常見配置範例
-- 僅 TCP 協議,3 個調度器,各支援 1000 連線
dispatchers = '(PROTOCOL=TCP)(DISPATCHERS=3)(CONNECTIONS=1000)'
-- 支援 TCP + SSL,分別配置
dispatchers = '(PROTOCOL=TCP)(DISPATCHERS=2)',
'(PROTOCOL=TCPS)(DISPATCHERS=1)(CONNECTIONS=500)'
-- 高並發 Web 應用
dispatchers = '(PROTOCOL=TCP)(DISPATCHERS=10)(CONNECTIONS=2000)(SESSIONS=8000)(POOL=ON)'
shared_servers = 20
max_shared_servers = 200
五、監控與診斷
1. 調度器負載
SELECT name, network, status, accepted, refused, current_connections, max_connections
FROM v$dispatcher;
2. 共用伺服器負載
SELECT name, status, requests, busy, idle, messages
FROM v$shared_server;
3. 佇列等待分析 (關鍵指標)
SELECT * FROM v$queue WHERE type = 'COMMON'; -- 請求佇列
SELECT * FROM v$queue WHERE type = 'DISPATCHER'; -- 回應佇列
-- 關鍵欄位:
-- WAIT: 平均等待時間 (百分之一秒)
-- TOTALQ: 總請求數
-- 如果 WAIT 持續 > 100 (1秒),表示共用伺服器不足
4. 當前連線模式統計
SELECT server, COUNT(*) AS session_count
FROM v$session
WHERE type = 'USER'
GROUP BY server;
-- SERVER = 'SHARED' / 'DEDICATED' / 'NONE'
六、常見問題與調優
| 問題 | 現象 | 解決 |
| 請求佇列等待高 | V$QUEUE WAIT 大、TOTALQ 增長快 | 增加 SHARED_SERVERS、MAX_SHARED_SERVERS |
| 回應佇列等待高 | Dispatcher 忙於網路傳輸 | 增加 DISPATCHERS、檢查網路頻寬/延遲 |
| UGA 記憶體不足 | ORA-04031 in Large Pool | 增加 LARGE_POOL_SIZE、調整 SESSIONS/CONNECTIONS |
| 長查詢佔用共用伺服器 | 其他請求排隊 | 改用專用伺服器服務長查詢、或增加 MAX_SHARED_SERVERS |
| 會話多工問題 | MULTIPLEX=ON 導致封包交錯 | 關閉 MULTIPLEX 或升級驅動程式 |
七、Windows vs UNIX 實作差異
- UNIX:調度器、共用伺服器皆為獨立進程,透過 `shmat()` 附掛 SGA
- Windows:皆為 `oracle.exe` 內執行緒,共享虛擬記憶體空間
- 佇列機制相同:SGA 內環狀緩衝區,受 `LARGE_POOL_SIZE` 限制
結語
共用伺服器以 **調度器 + 請求/回應佇列 + 共用伺服器池** 架構,實現「少量進程服務大量連線」。核心調優點在於:**平衡 DISPATCHERS 與 SHARED_SERVERS 比例、監控 V$QUEUE 等待時間、確保 Large Pool 足夠承載 UGA**。現代 Web 應用建議:應用層連線池 + 專用伺服器,或 DRCP (Database Resident Connection Pool),往往比傳統共用伺服器更靈活高效。