本文示範如何在 Xray 設定本機 gRPC API,透過 StatsService 讀取使用者或出站流量計數,再由腳本依健康檢查結果管理指定出站。適合已有 Xray 設定與節點管理經驗、希望自動化切換流程的讀者。請先注意:StatsService 回報的是統計值,不會替你判定最佳節點;HandlerService 可管理入站與出站,但不能直接改寫路由規則。把兩者的職責分清楚,才能設計可回復、可驗證的切換流程。
先釐清 API 能做什麼:統計與出站管理是兩件事
Xray 的 gRPC API 是核心提供的管理介面,可讓本機程式呼叫服務,而不是供瀏覽器或一般代理應用程式使用的代理入口。本文聚焦兩項服務:StatsService 用來查詢流量統計,HandlerService 用來管理執行中的入站與出站。要讓服務可用,必須在 Xray 設定中啟用 API,並透過路由規則將 API 入站的流量送往標籤為 api 的出站。
StatsService 回傳的是累積計數,不是即時速度,也不會附上節點延遲、丟包率或伺服器負載。腳本要估算傳輸速率,需讀取兩次計數並計算差值,再除以取樣間隔。例如,兩次讀取相隔 10 秒,計數增加 5,000,000 bytes,平均速率約為 500,000 bytes/s;這是該計數器在此區間的平均值,不代表之後的可用頻寬。
HandlerService 的出站操作也不等於修改 routing。若多條路由規則仍指向舊的 outboundTag,只新增另一個出站不會令流量自動改走新節點。較容易控制的做法,是讓一條指定路由固定指向單一的出站標籤,再由控制程式依目前 Xray 版本支援的 HandlerService 操作更新該出站設定;操作前先確認請求格式、目標標籤和更新方式,並準備可回復的舊設定。
- StatsService:讀取已啟用的計數器;是否能取得使用者或出站統計,取決於對應的 policy 設定。
- HandlerService:管理核心中的入站與出站;不負責選擇路由規則,也不應被當成通用的路由編輯介面。
- 健康檢查:由腳本另行執行,例如測試候選節點的連線與目標服務回應;API 統計不能單獨證明節點可用。
設定 Xray API:啟用服務並限制在本機
以下是可供參考的最小化設定範例,包含本機 API 入站、API 路由、統計項目,以及示範用的直連出站。若要套用到現有設定,請合併相應欄位,不要直接以這份示範覆蓋訂閱產生的設定。特別是 inbounds、outbounds、routing.rules、api 與 policy 都可能已有內容,重複定義或替換原有規則會使既有代理行為改變。
{
"api": {
"tag": "api",
"services": [
"HandlerService",
"StatsService"
]
},
"inbounds": [
{
"tag": "api-in",
"listen": "127.0.0.1",
"port": 10085,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1"
}
}
],
"outbounds": [
{
"tag": "api",
"protocol": "freedom",
"settings": {}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
],
"routing": {
"rules": [
{
"type": "field",
"inboundTag": [
"api-in"
],
"outboundTag": "api"
}
]
},
"stats": {},
"policy": {
"levels": {
"0": {
"statsUserUplink": true,
"statsUserDownlink": true
}
},
"system": {
"statsOutboundUplink": true,
"statsOutboundDownlink": true
}
}
}
API 服務名稱、入站標籤與 API 出站標籤各有用途:api.services 列出要啟用的服務;inboundTag 指向接收本機管理連線的入站;outboundTag 必須對應到設定中的 api 出站。這個管理出站不應拿來當一般瀏覽流量的代理出口。範例使用 127.0.0.1:10085,只能由本機連線;若需要從另一部管理主機操作,應透過具存取控制的安全通道,不要將 gRPC 連接埠直接暴露至公網。
API 管理入口
- 監聽位址
127.0.0.1- 示範連接埠
10085- 服務
HandlerService、StatsService- 路由標籤
api-in→api
連接埠可自行調整,但 Xray 設定與控制程式必須使用相同值。
流量統計開關
- 使用者上行
statsUserUplink- 使用者下行
statsUserDownlink- 出站上行
statsOutboundUplink- 出站下行
statsOutboundDownlink
只啟用系統或使用者所需的計數器;使用者統計還須符合對應帳戶層級設定。
使用者統計與出站統計的查詢名稱不同。使用者計數通常以設定中的使用者 email 為識別,例如 user>>>[email protected]>>>traffic>>>uplink;出站計數則可依出站標籤查詢,例如 outbound>>>node-a>>>traffic>>>downlink。這些名稱的前提是對應計數器已啟用,且標籤、帳戶識別資料與執行中的設定一致。更改設定後,先確認核心已載入新設定,再進行查詢。
實作切換流程:先取樣,再操作出站
開始寫控制程式前,先定義節點候選清單、健康檢查目標與失敗處理方式。腳本不宜只依照某一個流量計數器挑選節點:流量增加表示該計數器有資料經過,不代表節點延遲較低或仍能穩定連線。較穩健的判斷會結合連線測試、必要的服務回應檢查,以及固定期間內的上下載變化;當所有候選都不合格時,保留原節點通常比切換到未驗證節點安全。
-
檢查核心與連接埠
確認執行中的 Xray 設定已啟用
HandlerService與StatsService,API 入站只監聽127.0.0.1:10085。在控制程式中設定相同的主機與連接埠,並先確認連線可建立。 -
讀取流量計數
呼叫 StatsService 的統計查詢介面,依已啟用的名稱篩選所需項目。先以不重設計數器的方式讀取,將每個名稱、數值與時間存檔,避免把一次查詢結果誤當成速率。
-
計算區間變化
間隔一段時間再查一次,使用新值減去舊值並除以實際經過的秒數。若 Xray 重啟、計數器被重設或新值小於舊值,將該區間標記為無效,重新建立基準值,而不是把負數當成流量。
-
驗證候選節點
對候選節點執行獨立連線測試,確認 DNS、傳輸連線及預期服務回應。依相同測試目標與逾時設定比較結果;不要只使用 TCP 連線成功或節點名稱中的地區標示作為選擇依據。
-
更新並確認出站
依目前 Xray 版本支援的 HandlerService 請求更新指定出站,並確認回應成功。接著檢查核心記錄與實際連線,確定新設定已生效;失敗時恢復先前保存的出站設定並記錄原因。
切換策略應避免短時間內來回震盪。可採用連續多次檢查合格才切換、設定最短停留時間,以及為切換設定冷卻期。這些是控制程式的判斷邏輯,不是 Xray API 自動提供的能力。假設每 30 秒取樣一次,可要求連續 3 次健康檢查失敗才離開目前節點,並在切換後至少觀察數分鐘;這只是可調整的範例,應依服務的延遲需求和容錯目標設定。
結論:將「挑選」與「切換」分成兩個可驗證步驟
先由健康檢查選出候選,再透過 HandlerService 更新預先指定的出站,最後以實際流量與連線結果確認。若控制程式無法證明路由仍指向預期標籤,便不應宣稱節點已成功切換。
HandlerService 的請求格式屬於 gRPC protobuf,而不是把一段 JSON 直接送到連接埠就能完成操作。控制程式應使用與 Xray API 定義相容的 gRPC 用戶端及訊息型別,並針對正在執行的核心版本測試。除非已確認該版本的操作語意,不要假定新增出站、替換出站與修改出站是同一種行為;也不要在執行中刪除目前仍被路由引用的標籤。若自動化流程需要改動 routing 規則,應採用明確支援該流程的設定部署與重載方式,而非把它說成 HandlerService 的功能。
維運與安全:控制權限、保留紀錄、準備復原
能讀取統計或變更出站的 API 是管理介面,應按管理憑證看待。一般使用情境下,將 API 限制在回環位址,並確保作業系統防火牆不允許外部主機連入該管理連接埠。如果控制程式與核心不在同一主機,先規劃安全的管理通道與主機存取權限;不要為了方便將監聽位址改為所有網路介面。若 API 流量可能經過其他主機,還要檢查通道的加密、驗證與記錄方式。
- 限制操作範圍:控制程式只允許操作預先列出的出站標籤,不接受未驗證的外部輸入作為標籤或設定內容。
- 保留切換前狀態:保存目前出站設定、候選名稱、操作時間與 API 回應摘要;記錄中不要寫入訂閱網址、密碼或完整使用者識別資料。
- 設定失敗保護:遇到逾時、回應錯誤或設定驗證失敗時停止後續操作,保留原出站並告警,不要不斷重試可能造成重複變更的請求。
- 監看核心狀態:切換後檢查 Xray 記錄與實際連線。只看到 API 回應成功,不代表新出口一定能連到目標服務。
- 控制統計粒度:只查詢決策所需的計數器,設定合理取樣間隔,避免將高頻輪詢、過度記錄與不必要的計數器一併加入常態維運。
若使用 StatsService 的查詢功能重設計數器,必須先確認其他監控程式是否共用同一組計數值。重設會影響後續差值計算,也可能使不同時間段的紀錄無法比較。常見做法是保留累積計數,由控制程式保存上一次的數值與時間戳;遇到核心重啟或計數回退時,再重新初始化基準。
此外,流量統計值是用於觀察資料量,不是帳單或服務商用量的權威憑證。核心統計的範圍、協定開銷與遠端計費方式可能不同;若要核對服務商用量,應以服務商提供的計費資料為準。需要對外分享排查記錄時,先遮蔽使用者 email、伺服器位址與訂閱憑證。
常見問題
查詢不到出站流量,是 API 壞了嗎?
先確認 policy.system.statsOutboundUplink 與 statsOutboundDownlink 已啟用,再比對查詢名稱中的出站標籤是否與目前設定一致。重新載入設定後,產生該出站流量,再查詢計數器;沒有流量時,數值維持不變可能是正常現象。
StatsService 能直接告訴我哪個節點最快嗎?
不能。它提供已啟用的流量計數,不提供完整速度測試或節點健康評分。請另外以一致的目標與逾時條件測試候選節點,再將結果交由腳本評估。
新增出站後,流量為什麼還走舊節點?
檢查 routing 規則的 outboundTag。HandlerService 管理出站不會自動把其他路由改指向新標籤;要使用新節點,必須確保路由與出站操作的設計相符,並以實際連線驗證。
可以把 API 連接埠開放給外部監控主機嗎?
不要直接暴露管理連接埠。優先讓控制程式在核心所在主機執行;若確實需要遠端管理,應使用受控的安全通道、來源限制與最小權限,並在變更前測試復原流程。