解題記事 | 系統主機 thread 數量暴增

解題記事 | 系統主機 thread 數量暴增
Photo by Tim Mossholder / Unsplash

狀況描述

前段時間,一個系統進行版更,版更後隔天監控系統 (Checkmk) 發出了 AP 主機 thread 數量過多 (Number of threads) 的告警。

版更前的 thread 數量在上班時間大約落在 400 至 600 間,版更後相同時間卻落在 4000 至 6000 之間,甚至更多,系統的反應也比以往要慢上許多。

釐清原因

版更後有狀況,通常第一時間都會回頭檢視這次版更了哪些東西,這次的版更有幾個項目:

  1. 修正 1 個 Defect
  2. AP 主機作業系統升級
  3. 為開放外網改變系統佈署架構
    在 DMZ 1 中增設一台 Web Server,透過轉發到特定服務的方式指向真正的 AP 主機。
  4. 改變驗證機制
    為了提升安全性與可維護性,登入驗證機制改用 OAuth 2.0 的認證授權方式。

逐一釐清每一項調整的嫌疑 (好像偵探)
第 1、2 項因為掌握度算高,很快被排除在外,第 3 項的釐清是先觀察監控系統,發現放在 DMZ 的 Web Server thread 數量很穩定的少,相比於 AP 主機的數量,由此可推斷造成 thread 飆高的原因不在外部了,那麼,就只剩第 4 項了,使用者在系統的請求,應該會觸發驗證 Token 有效的檢查機制,而驗證是否有效需連線到身份證別主機,觀察網路連接應該可以發現一些端倪。

主機是 Linux 主機,透過幾個指令判斷兇手應該就是它

    1. 查出 tomcat 的網路連接
    2. 過濾出包含 https 關鍵字的結果
    3. 印出前一個輸出結果的指定欄位值
    4. 去除重複列並標示出現次數
    5. 依照指定欄位倒序排序

觀察 tomcat 的網路連接狀況

netstat -p | grep $pid

得到的 output 結果是 tomcat 當下所有的網路連接狀況,從輸出結果中觀察到有不少連接到身份識別主機的連線

 
為了有更切確的數據能驗證想法,利用指令將輸出結果作個 summary
 

netstat -p | grep $pid | grep 'https' | awk '[print $5 "\t" $6}' | uniq -c | sort -nk1 -r

 
從輸出結果發現連接身份識別主機有 3000 多個連線

上述的指令使用到 pipe (|),簡單理解就是將 pipe 前指令的輸出扔給 pipe 後的指令當作輸入,主要目的是為了將前一個指令的輸出整理一番:

找出 AP Server 的 process
系統用的是 tomcat,習慣上我會直接下指令尋找 tomcat 的 process id

ps aux | grep tomcat

從前述指令得到的 output 結果,第 2 個欄位就是 process id,以下將得到的結果以 $pid 表示

當時站台線上人數只有 95 人左右,但是有這麼多與身份識別主機的連線,大致可以推測每個 request 都去跟身份識別主機驗證 token 是否有效,但是數量多到讓人覺得怪,難道每個使用者手速飛快?

該系統是使用 Java 開發的系統,要驗證 token 是否有效應該會經過驗證的 Filter 2 進行檢查,針對這個驗證的 Filter 也會設定有哪些類型的資源需要檢查,實際檢查該系統的 web.xml 檔案

<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

 
確實有一個驗證的 Filter,名為 AuthenticationFilter,而底下的那行 url-pattern 設置為 /*,這代表所有的資源 都要經過驗證,包含圖檔、載入的 js 與 css,想像一下,使用者開啟一個畫面,背後代表的可能是 request 20-30 個資源,每個資源都會去跟身份識別系統確認一次。

查到這個階段,大約已可以確定問題就在這個設定了,那麼,該怎麼解決這個問題呢? 

解決方法

解決的方式其實不難,主要是把應該經過驗證的資源明確下來,將 url-pattern 的 /* 調整為明確的資源類型,那麼,需要經過驗證的資源是什麼呢?

一般來說程式類的檔案會有商業邏輯、資料庫存取等處理,大多是需要經過驗證的,再者可能是一些需要登入狀態才能存取的附加檔案,實際的設定需要和該系統負責人員討論。

<filter-mapping>
<filter-name>AuthenticationFilter</filter-name>
<url-pattern>/*.jsp,/files/*</url-pattern>
</filter-mapping>

 
調整後重啟服務,觀察一陣子,thread 數下降許多且穩定 

後記

工作中多少會遇上一些系統問題需要排除,往往解決問題後,以口頭或訊息的方式經驗分享,花愈多時間,留在心裡 (腦裡) 的時間愈長,但其實時間久了還是會忘記,更不用說只是聽分享但沒有實際操作的人了,也因此觸發了寫這篇筆記的開關,將釐清問題的思路和手法記錄下來。

解決技術問題後,更需要做個整理,對外,將問題排除前後的狀況作個對比,將相關的資訊傳達給提報問題的人;對內,分享釐清問題、找出根因的手法,與開發團隊復盤檢視有沒有可以優化的點,發起改善計畫與執行,形成團隊好的循環。


  1. 工作單位網路架構有設置 DMZ 區,政策上希望放在 DMZ 區的只有純前端,即便被駭入破壞了也不要緊。 
  2. Filter 是 Java 的一個元件,用來管理 web 資源,當有實作 Filter 並設定要對哪個類型的資源進行攔截,在 request 目標資源前會先經過該 Filter 程式 (可能是權限、加工等),決定是否可請求目標資源。 

Read more

Data Platform 筆記#02:從可行到可承接

Data Platform 筆記#02:從可行到可承接

在初版架構逐漸成形後,時間也差不多過了一年。 架構可以跑、資料可以流動,但我仍然不確定它能不能真正落地。這條路必須要團隊可以承接、可以擴展,數據才有機會真正發揮價值。 很慶幸的是,我的主管願意投資時間,讓這個方向能繼續推進。也正是在那段時間,我的思考開始出現轉變... 前一篇的重點,是讓流程從「能跑」走向「能持續」。 而接下來我開始思考:如果這件事要由團隊一起做下去,現在的做法夠不夠讓人接手? 轉變的核心 回頭看那一年,大多數時間其實是在解問題。 但接下來,我該解的是另一個問題:怎麼讓別人不用再解一次同樣的問題? 於是投入了約莫三個月、壓力值很高的一段時間,開始把原本依賴個人經驗與記憶的做法,收斂成可以被團隊理解與複製的形式。 這個收斂,後來具體落在幾個方向上: * 把 Data Center 的部署方式收斂成一致做法,降低環境轉換成本 * 把資料整理作業轉變為配置驅動,讓流程與部署有規則可循 * 整理 DDL 轉換規則與範本,讓團隊能共用同一套方法 * 把知識系統化交付出去 這些事情的唯一核心是 讓方法大於個人。 從個人經驗,到規則明確 第一個改變:

By Jo
Data Platform 筆記#01:初版技術架構成形

Data Platform 筆記#01:初版技術架構成形

在上篇的 POC 之後,我們整理了一份內部報告,將問題拆成資料蒐集、基礎資料定義、資料量與查詢效能、資料治理、技術架構等幾個面向。 這份整理的目的是先建立邊界,讓我們從發散與模糊,逐步走向具體且聚焦。 在這個基礎上,我開始把關注重點轉向資料流: 如何讓資料自動、穩定、乾淨地進到分析效能較好的資料庫? 同時,也剛好迎來一個契機:與技術能量較高的團隊合作發展數據中台。這讓 Data Center 的推進獲得更多資源與支援,讓我們能更系統化地思考架構問題。 思考階段 這個階段,我們主要思考幾個問題: * 不同來源的資料,能不能用相對一致的方法接進來? * 資料會持續累積,是否有合適的儲存與管理方案? * 資料進來後,分層應該怎麼定義? * 查詢分析時,是否有更適合的查詢引擎? 各資料源的特性不同,接收方式很難完全一致。但若每種來源都設計一套專屬流程,維運成本會快速上升。因此初步的想法是先用一種主要方式處理大多數的情境,讓資料流先跑起來,再逐步優化。 過去常見的分層方式,是將資料分成: * 可追溯的原始資料(Stage) * 清洗整理後的乾淨資料(Data) *

By Jo
Data Platform 筆記#00:在變得具體之前

Data Platform 筆記#00:在變得具體之前

目標要做資料平台(Data Platform) 一開始我不是很能夠想像這件事該長成什麼樣子,既有的認知只有前期參與的團隊有實作過 HR 資料中心,顧問曾指導資料分層為 Stage、Data、Mart,除此之外,我沒有更多掌握,有很多疑問需要找到答案。 做到什麼程度算是Data Platform? 我們期待它能解決什麼、幫助到誰? 它是不是應該包含一套接收資料的方法、能儲存大量資料的資料庫、提供資料服務的能力?   那麼,它是一個平台嗎?該用什麼技術?有哪些其實現在不需要?又該怎麼做,才能保留未來需要的彈性? 這些問題在當下其實都沒有辦法很快有肯定又具體的答案。好像每一個點都應該被考慮到,但同時又覺得過於理想。那段時間,我甚至開始嘗試透過與 AI 的對話,把模糊的想法拆解成可以被檢視的問題。它沒有辦法替我做決定,但確實加速我釐清問題。 只是,在理解問題的過程,即使把想法轉化輸出成一張張架構圖,進展卻不是太明顯,反而有一種無法落地的感覺,沒有讓事情真正往前走,我們仍然缺少可以被驗證的起點。 開始有切入點的時機,是我們在尋找能夠讓用戶自助調整所需報表的工具,剛好從前的工作曾小量接觸

By Jo
筆記 | 自架 Ghost 的 SMTP 設定

筆記 | 自架 Ghost 的 SMTP 設定

部落格荒廢了好一段時間,近期終於想用手機登入管理介面留下些草稿,突然發現無法登入,登入鈕下方出現了如下的一段訊息 EmailError: Failed to send email. Please check your site configuration and try again. 結論先行,原因是我安裝的 ghost 版本,在首次使用新裝置登入時需要 2FA (二階段驗證),也就是說,除了帳號密碼登入之外,還會有一層驗證機制,而這層驗證機制需要輸入 6 碼驗證碼 (Ghost 站台發給登入者註冊信箱的 mail 會提供)。我當時建置 Ghost 時認為自己不會發送電子報,就忽略了 SMTP 的設定,導致 Ghost 站台不能正常發信,在配置好 SMTP 設定後,從新裝置就能正常登入了。 前一篇文章提到我的 Ghost 是架設在

By Jo