某客戶將 WebLogic Server 從 8.1 SP1 升級至 8.1 SP4,同步進行大規模證書更新(數量龐大、構建流程複雜、簽名流程漫長)。升級初期測試通過,但尖峰負載下出現**負載均衡失效**:部分節點承擔全部流量,其餘節點幾乎空閒。標準故障排查無果,緊急重啟全叢集暫時緩解。數日後再次重啟兩節點,次日全環境爆發核心錯誤:
<DECRYPT_ERROR> A decryption error occurred during the SSL handshake.
Received alert from x.x.x.x: DECRYPT_ERROR
BEA-000112 (節點加入) 與 BEA-000113 (節點離開),立即下線異常節點。對比 8.1 SP1 與 8.1 SP4 預設配置,發現 SSL 屬性 TwoWaySSLEnabled 預設值發生變更:
| 版本 | TwoWaySSLEnabled 預設值 | 管理控制台顯示 |
|---|---|---|
| 8.1 SP1 | false | Client Certificate Not Requested |
| 8.1 SP4 | true (但不強制) | Client Certificate Requested But Not Enforced |
文檔陷阱:config.xml 文檔聲稱該屬性僅支援 true/false,實際控制台提供第三種語義「請求但不強制」,導致遷移腳本未同步此隱性變更。
CertificateRequest 訊息,Client 可選發送證書;若 Client 發送證書但驗證失敗,握手繼續(不強制)。升級後 Server 主動請求 Client 證書,但舊版 Client (或 Apache 插件) 未配置 Client 證書或信任鏈不全,導致握手過程中產生無效加密參數,觸發 DECRYPT_ERROR。
<!-- config.xml 显式設定回單向 SSL -->
<Server ...>
<SSL>
<TwoWaySSLEnabled>false</TwoWaySSLEnabled>
</SSL>
</Server>
重啟受影響節點,叢集恢復正常負載均衡。
config.xml 納入 Git 管理,升級前導出基線,升級後 Diff 對比所有屬性變更。SSLVerifyClient optional/require 配置、測試環境全鏈路驗證。中間件升級不是單純二進制替換,**預設值漂移** 是最隱蔽、破壞力最強的風險源。建立「配置即代碼、遷移必審、灰度驗證、可觀測先行」的升級工程化體系,才能將風險控制在可接受範圍內。本案中,一個 TwoWaySSLEnabled 的靜默翻轉,差點癱瘓核心業務叢集——這就是細節決定成敗的經典註腳。