在分散式系統中,訊息佇列扮演著關鍵角色,其效能直接影響整體系統的穩定性。監控訊息佇列的生產者和消費者指標,例如訊息發布數量、處理數量、佇列時間和處理時間,對於掌握系統執行狀況至關重要。此外,計算訊息延遲、定義健康指標閾值以及利用 FMEA 分析預防潛在故障,都有助於提升系統可靠性。除了指標監控,結構化的日誌記錄也是不可或缺的環節。透過集中式的日誌彙總系統,可以整合來自不同系統的日誌,便於查詢、分析和建立警示。然而,實施日誌彙總也面臨成本和資料量增長等挑戰,需要仔細評估自建或採購方案,並制定合理的日誌保留策略。
3.4 提升維運可見度:監控與指標定義
在現代化的軟體系統中,監控扮演著至關重要的角色。適當的監控不僅能夠幫助團隊快速定位問題,還能提供對系統健康狀態的深入洞察。本文將重點探討如何透過訊息佇列系統的監控來提升維運可見度,並介紹定義健康指標的重要性。
3.4.1 訊息佇列監控的關鍵指標
訊息佇列系統是許多現代應用程式的核心組成部分,其效能直接影響到整體系統的穩定性。監控訊息佇列時,以下指標至關重要:
生產者指標
生產者負責將訊息傳送到佇列。關鍵指標包括:
messages.published.count:已發布的訊息數量message.queue.time:訊息在佇列中等待的時間message.processing.time:處理訊息所需的時間
消費者指標
消費者負責從佇列中檢索並處理訊息。相關指標包括:
messages.processed.count:已處理的訊息數量- 消費速率:透過頻繁取樣
messages.processed.count來計算
額外重要指標
- 系統中未確認的訊息數量
- 當前連線到訊息匯流排的消費者數量
- 當前連線到訊息匯流排的生產者數量
這些指標共同提供了對訊息佇列系統健康狀態的全面視角。
3.4.2 計算訊息延遲
訊息延遲是衡量訊息佇列效能的重要指標之一。計算延遲的方法是在訊息發布時新增時間戳,然後在消費者端計算當前時間與該時間戳之間的差值。例如:
import datetime
# 生產者端
current_timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
message = f"DATE:{current_timestamp}"
# 消費者端
def calculate_latency(message):
msg_timestamp = datetime.datetime.strptime(message.split(':')[1], '%Y%m%d%H%M%S')
current_time = datetime.datetime.now()
latency = (current_time - msg_timestamp).total_seconds()
return latency
latency = calculate_latency(message)
print(f"訊息延遲:{latency} 秒")
內容解密:
- 時間戳生成:生產者在發布訊息時新增當前時間的時間戳,格式為
YYYYMMDDHHMMSS。 - 延遲計算:消費者接收到訊息後,解析出時間戳並與當前時間比較,計算出延遲時間(以秒為單位)。
- 效能監控:將計算出的延遲作為指標(例如
message.queue.latency)傳送到監控系統,以便進行進一步的分析和預警。
這種方法不僅適用於訊息佇列系統,也可用於其他類別似的非同步處理場景。
3.4.3 定義健康的指標
定義什麼是「健康」的指標對於有效的監控至關重要。這不僅涉及到設定閾值觸發警示,還需要了解何時指標的變化代表著系統效能的根本性改變。
健康指標的重要性
- 及時發現問題:例如監控資料函式庫的平行查詢數量,當超過閾值時立即發出警示。
- 容量規劃:隨著網站活躍度增加,平行查詢數量會增長。定義健康的指標可以作為擴充的觸發點。
- 跨團隊協作:開發團隊、維運團隊和產品團隊應共同參與健康指標的定義,確保大家對系統效能的要求保持一致。
3.4.4 故障模式與影響分析(FMEA)
FMEA是一種源自製造業和安全領域的分析方法,用於識別流程中的潛在故障點。在軟體開發中,FMEA可以幫助團隊預測和預防系統故障。
FMEA流程
- 定義範圍:確定要分析的流程或系統元件。
- 識別故障模式:列出所有可能的故障場景。
- 評估風險優先序號(RPN):為每個故障模式評分,包括嚴重性、發生頻率和檢測難度。
- 制定改進措施:根據RPN優先排序,並實施措施降低高風險項的風險。
FMEA有助於團隊深入理解系統行為,並在問題發生前採取預防措施。
建立營運可視性:透過FMEA提升系統監控與錯誤檢測
在現代化的技術營運中,建立營運可視性(operational visibility)是確保系統穩定性和可靠性的關鍵步驟。這涉及到組建跨功能團隊,利用FMEA(Failure Mode and Effects Analysis)流程來識別潛在的錯誤點並制定相應的監控和預警措施。
組建跨功能團隊與流程圖建模
首先,需要組建一個由維運人員、開發人員、業務使用者和其他相關利益者組成的跨功能團隊。這個團隊的多樣化背景能夠提供不同的視角和思維模式,從而更全面地識別流程中可能出現的問題。例如,開發人員可能會關註失敗的HTTP呼叫及其技術影響,而客戶支援代表則可能更關心部分失敗對使用者造成的混淆。
圖示解說:
此圖示展示了Webshopper.com結帳流程的主要步驟,包括庫存檢查、支付授權請求和訂單確認等關鍵環節。
在進行FMEA之前,由領域專家組成的小團隊會先將流程詳細地繪製成泳道圖(swim-lane diagram),以展示系統、流程和團隊之間的互動作用。以Webshopper.com為例,該公司近期經歷了多次結帳流程中的訂單失敗問題,因此長官層決定進行FMEA分析。
識別錯誤點與風險評估
在繪製出結帳流程的泳道圖後,團隊開始集思廣益,識別潛在的錯誤點。例如,支付處理器離線可能導致支付流程失敗,從而使訂單被系統拒絕。團隊對此風險進行評估:
- 嚴重性(Severity):10(因直接導致收入損失)
- 發生頻率(Occurrence):6(支付處理器歷史上可用性良好,但仍有可能失敗)
- 檢測難度(Detection):10(目前未監控支付端點的健康狀態)
計算出來的RPN(Risk Priority Number)為600(10 × 6 × 10)。為了降低這個風險,團隊提出了多種解決方案,包括修改系統以暫存支付處理、增加備用支付處理器,或是加強對支付處理器的監控。
實施監控與降低風險
透過實施以下監控措施,可以提高對支付處理器問題的檢測能力:
- 建立支付提供者呼叫延遲的指標
- 建立支付提供者失敗呼叫比例的錯誤率指標
- 對支付提供者進行健康檢查
這些措施能夠幫助團隊提前發現問題並採取相應行動,從而降低檢測難度,將RPN降至360(10 × 6 × 6)。這使得原本的高風險問題得到一定程度的緩解。
從事件和故障中取得指標
除了FMEA之外,每次系統故障後進行的事後分析(postmortem)也是取得重要指標的來源。在事後分析過程中,團隊應該不斷問自己「當時有哪些關於系統狀態的問題無法回答?」這有助於發現監控解決方案的不足之處,並據此制定新的指標來填補這些空白。
對於需要更詳細資訊的場景,僅靠指標可能不夠,這時就需要依賴日誌基礎設施來提供細粒度資訊。隨著可觀測性(observability)的發展,將指標的視覺化能力與日誌的詳細資訊相結合,能夠進一步提升對系統問題的診斷和隔離能力。
使日誌記錄變得有用
日誌記錄是監控工具箱中最古老且仍然非常有用的工具之一。然而,它經常被濫用。
日誌彙總
首先要注意的是,結構化日誌記錄是必不可少的。結構化日誌以機器可讀的格式放置,具有明確定義和可解析的欄位和值。最廣泛使用的日誌格式是JavaScript Object Notation(JSON),大多數語言和框架都有一個函式庫,可以輕鬆地以JSON格式生成日誌。
機器可讀格式的好處在於,您可以將日誌傳輸並匯入日誌彙總系統。日誌彙總系統允許您將來自不同系統的日誌合併,並建立一個單一的位置進行搜尋。許多日誌彙總系統可供選擇,從付費軟體即服務(SaaS)解決方案,如Splunk或Sumo Logic,到免費的開源解決方案,如流行的Elasticsearch、Logstash和Kibana堆積疊(通常稱為ELK)和Graylog。使用結構化日誌格式,將日誌匯入任何系統都變得更加容易,因為它消除了對複雜且通常脆弱的正規表示式來解釋欄位和值的需求。相反,眾所周知的格式可以輕鬆地被日誌傳輸器或彙總伺服器解釋。
內容解密:
此段落闡述了結構化日誌的重要性及其優點。結構化日誌使用JSON等機器可讀格式,使得日誌可以輕鬆地被匯入日誌彙總系統。這種格式消除了對複雜正規表示式的需求,使得日誌處理更加容易。結構化日誌還允許不同的團隊分享和民主化資訊,從而提高協作效率。
日誌彙總的文化影響
日誌彙總的需求既是技術上的,也是文化上的。首先,請記住DevOps的一個核心原則是賦予團隊權力,並盡可能多地分享和民主化資訊。在沒有日誌彙總的世界中,日誌的存取許可權要麼僅限於維運支援人員,要麼成為開發團隊的沉重負擔,因為他們需要將日誌複製到其他容易存取的位置。日誌彙總工具可以完全重新思考和消除這種門檻功能,將資料從生成的伺服器上取出,並將其傳輸到日誌彙總系統。這開啟了一個新的可能性世界,因為多個學科現在可以存取日誌,並幾乎實時地瞭解應用程式的效能。
內容解密:
此段落討論了日誌彙總的文化影響。日誌彙總不僅是技術上的需求,也是文化上的需求。它使得不同的團隊可以分享和存取日誌,從而提高協作效率。日誌彙總工具可以消除門檻功能,使得資料可以被多個學科存取和使用。
日誌彙總的新商用案例
日誌彙總還開啟了新的商用案例,這些案例在以前是無法實作的。日誌中傳達的資訊量通常可以講述整個流程的故事,而無需您意識到這一點。當流程中的每個功能或步驟記錄有關其效能的資訊時,它也在無意中為您提供了對業務流程的洞察。例如,如果生產者程式記錄了它已發布訂單115的訊息,消費者程式記錄了它已消費訂單115的訊息,支付處理器記錄了它已確認訂單115的付款,那麼透過一些聰明的搜尋條件,您可以在實時中觀察整個訂單流程。這不僅為技術團隊提供了價值,也為工程以外的業務部門提供了價值。
內容解密:
此段落闡述了日誌彙總如何開啟新的商用案例。日誌中包含了豐富的資訊,可以用於瞭解業務流程和應用程式的效能。透過日誌彙總,可以實作對整個流程的實時監控和分析。
集中式日誌記錄的好處
集中式日誌記錄提供了許多好處,特別是在應用程式堆積疊的監控方面。傳統上,日誌作為警示來源是無用的,因為在大規模系統中,檢查、解析和警示這些日誌是一項繁重的任務。使用集中式日誌記錄,可以建立根據多個興趣點的警示和監控。例如,可以將大量的失敗網頁請求與大量的失敗資料函式庫登入相關聯,因為您的日誌都位於一個地方。許多日誌彙總工具具有先進的計算能力,允許您跨欄位解析日誌,並對其進行數學公式和轉換,以用於繪圖和製圖。
內容解密:
此段落討論了集中式日誌記錄的好處。它使得建立根據多個興趣點的警示和監控成為可能,並且可以實作對應用程式堆積疊的監控和分析。
此圖示展示了一個簡單的訊息處理流程,包括生產者程式、訊息佇列、消費者程式、支付處理器和資料函式庫。每個元件都記錄有關其效能的資訊,從而提供對整個流程的洞察。
內容解密:
此圖示展示了一個簡單的訊息處理流程,包括生產者程式、訊息佇列、消費者程式、支付處理器和資料函式庫。每個元件都記錄有關其效能的資訊,從而提供對整個流程的洞察。這種結構化的日誌記錄方式使得我們可以輕鬆地瞭解整個流程的運作情況。
讓紀錄變得有用
3.5.2 我應該記錄什麼?
在確定要記錄什麼之前,您應該先了解可以使用的各種記錄層級。有一種廣為人知的記錄層級模式,您應該遵循。最常見的層級包括 DEBUG、INFO、WARN、ERROR 和 FATAL。每個錯誤層級都有預期在該類別中的特定資訊型別:
- DEBUG:與程式中正在發生的事情相關的任何資訊。這些通常是程式設計師為除錯目的而寫的訊息。
- INFO:任何使用者啟動的操作或任何系統操作,例如排程任務執行,或系統啟動和關閉。
- WARN:任何可能在未來變成錯誤狀態的情況。函式庫棄用警告、可用資源不足或效能緩慢都是適合放在這個層級的例子。
- ERROR:任何和每個錯誤條件都應該放在這個層級。
- FATAL:任何導致系統關閉的錯誤條件。例如,如果系統在啟動時需要 32 GB 的記憶體,但只有 16 GB 可用,程式應該記錄一個 FATAL 錯誤訊息並立即離開。
不幸的是,這些層級定義無法以程式設計方式強制執行。這取決於工程師在適當的層級進行記錄。這很重要,因為人們在搜尋資訊時會解析日誌。如果您正在尋找錯誤,您很可能會根據具有 ERROR 狀態的日誌條目進行篩選。但是,如果您要尋找的錯誤訊息實際上是在 INFO 層級記錄的,那麼它就會陷入與無關訊息的大海中。
將日誌訊息放在正確的類別中幾乎與首先記錄訊息一樣重要。太多的下游操作,如搜尋、篩選,甚至監控,都取決於日誌訊息的分類別正確。但現在您知道了您的日誌訊息應該放在哪個類別,接下來要考慮的是您希望在日誌中看到什麼?
什麼是好的日誌訊息
好的日誌訊息的關鍵是上下文。每個日誌訊息都應該從它是與被記錄的事情相關的唯一日誌訊息的角度來寫。例如,“交易完成”訊息是無用的。這樣的訊息可能依賴於之前的訊息,而交易的詳細資訊要從之前的日誌訊息中推斷出來。但是,由於有多個伺服器發出的日誌訊息被彙總到一個例項中,將這兩個獨立的日誌訊息聯絡起來可能會很困難。更不用說,如果您的其中一個日誌訊息是在 INFO 層級記錄的,但後續的錯誤訊息是在 ERROR 層級記錄的,那麼前面的訊息甚至可能不會到達閱讀日誌的人手中。
我們的目標是為日誌讀取者提供足夠的上下文,以便他們能夠理解正在發生的事情。不僅如此,還要繼續以結構化的欄位格式進行。如果您正在處理訂單,您可能會得到一個結構如下所示的檔案:
{
"timestamp": "2019-08-01:23:52:44",
"level": "INFO",
"order_id": 25521,
"state": "IN PROCESS",
"message": "Payment verified",
"subsystem": "payments.processors.credit_card"
}
內容解密:
此 JSON 結構化日誌訊息提供了豐富的上下文,包含了時間戳記(timestamp)、記錄層級(level)、訂單ID(order_id)、訂單狀態(state)、具體訊息(message)以及所屬子系統(subsystem)。每個欄位都有其特定意義:
- timestamp:標示日誌記錄的時間點,有助於事件的時間順序分析。
- level:表示日誌的嚴重程度,協助篩選和定位問題。
- order_id:與特定訂單相關聯,使得追蹤和查詢訂單相關的日誌變得容易。
- state:顯示訂單當前的處理狀態,有助於瞭解訂單處理進度。
- message:具體的日誌訊息,描述了事件或操作的詳細資訊。
- subsystem:指出該日誌所屬的子系統,便於區分不同模組或元件的日誌。
這個日誌訊息包含了上下文。您可以將訊息與特定的訂單 ID 相關聯。根據您的程式語言,您可能可以新增其他有用的屬性,以便為所顯示的訊息提供更多的上下文。現在,看到這個日誌訊息並希望瞭解更多資訊的工程師可以根據 order_id 篩選日誌訊息,並獲得圍繞該特定訂單的上下文。
這個例子引出了另一個觀點。您不應該只為了故障排除而記錄日誌。您還可以考慮為了稽核和效能分析的目的而進行日誌記錄。例如,您可能會在每次特定呼叫超過某個閾值時記錄一條訊息。或者,您可以在整個訂單處理過程中記錄狀態變更,註明哪個子系統更改了它以及為什麼更改。使用者密碼重設、登入失敗嘗試等,都可以被記錄。透過日誌記錄,您可以圍繞系統中發生的許多操作建立一個詳細的故事。只要特別注意將它們記錄在正確的日誌層級,這使得稍後篩選和識別變得容易。
在記錄錯誤訊息時,開發人員應該格外小心地解釋有關錯誤訊息的一些資訊。以下是一些關鍵資訊:
- 正在執行的操作是什麼?
- 該操作的預期結果是什麼?
- 該操作的實際結果是什麼?
- 一些可能的補救措施是什麼?
- 此錯誤的潛在後果是什麼(如果有的話)?
最後一點需要更多的解釋。沒有比看到類別似“無法完成信用卡授權”的錯誤訊息更糟糕的事情了。這是什麼意思?訂單是否被拒絕?它是否處於不確定狀態?使用者是否會收到通知?是否有營運商需要執行的清理活動?該錯誤缺乏使事件變得有用的資訊。請記住,日誌相對於指標的好處是您能夠提供更多關於錯誤的詳細資訊。如果您只是要記錄事件發生的事實,那麼它可能是一個指標,而不是日誌條目。
試想一下將閱讀這些日誌的人,並嘗試預測他們在閱讀錯誤訊息時會提出的問題。該訊息的一個更好的例子可能是“無法完成信用卡授權。訂單將被拒絕,並通知客戶。”現在,您對正在發生的事情有了更完整的瞭解。
此圖示展示了訂單處理流程,包括信用卡授權檢查。如果授權成功,則繼續處理訂單;如果授權失敗,則記錄錯誤並通知客戶,最終完成訂單處理。
圖表內容解密:
圖表中展示了從開始處理訂單到最終完成訂單的流程,主要步驟包括檢查信用卡授權、處理訂單以及錯誤處理和通知客戶。每一步驟都與實際業務邏輯相關,有助於理解整個訂單處理流程中的關鍵節點和決策點。
3.5 記錄彙總的挑戰與效益分析
在 DevOps 環境中,記錄彙總(log aggregation)是一項至關重要的技術實踐,它能夠大幅提升系統的可觀察性和問題排查效率。然而,儘管其效益顯著,實施記錄彙總仍然面臨諸多挑戰。
3.5.1 記錄彙總的效益
記錄彙總能夠將分散在不同系統和服務的日誌集中管理,提供統一的查詢和分析介面。這不僅有助於快速定位問題,還能透過日誌分析發現潛在的系統瓶頸和安全威脅。例如,當系統出現錯誤時,彙總日誌可以提供完整的事件序列,幫助技術人員瞭解錯誤發生的前因後果。如果系統採取了不同的糾正措施,日誌訊息也可以相應調整,以反映特定的處理結果。
3.5.2 記錄彙總的挑戰
儘管記錄彙總的優勢顯而易見,但其實施仍面臨諸多挑戰。首先,日誌彙總工具的採購成本可能相當高昂。大多數日誌彙總工具根據資料量、資料吞吐量或事件數量收費。即使採用開源軟體自建日誌彙總系統,也需要考慮硬體成本和人員資源投入。此外,日誌量的增長對容量規劃提出了更高要求。
更重要的是,日誌彙總可能導致「反向激勵」(perverse incentives),即為了降低日誌彙總服務的成本而減少日誌記錄的數量或詳細程度。這種做法可能會影響日誌的有用性,因為某些重要的日誌訊息可能會被省略。
3.5.3 爭取預算支援
在進行「自建 vs. 採購」決策時,需要仔細評估業務需求和成本效益。如果日誌彙總服務不是核心技術解決方案,且沒有涉及專有技術,通常採購現成的服務是更合理的選擇。
為了爭取預算支援,需要將日誌彙總解決方案的效益以業務語言呈現給管理階層。例如,可以透過計算因缺乏日誌存取而導致的開發延誤和客戶滿意度下降等成本,來說服管理階層批准預算。
如何獲得預算批准
- 提前規劃: 瞭解部門的預算週期,並在預算審核期間提出申請。
- 從小處開始: 先匯總最常被請求的日誌,逐步擴充套件服務範圍。
- 控制成本: 實施不同的日誌保留策略,以降低儲存和 SaaS 成本。
3.5.4 自建 vs. 採購
在日誌彙總領域,「自建 vs. 採購」的討論非常普遍。有些公司選擇自行託管日誌彙總服務,尤其是當有嚴格的資料隱私要求時。然而,對於大多數企業來說,採購成熟的日誌彙總服務可能是更經濟高效的選擇。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 訊息佇列監控與日誌記錄最佳實務
package "系統架構" {
package "前端層" {
component [使用者介面] as ui
component [API 客戶端] as client
}
package "後端層" {
component [API 服務] as api
component [業務邏輯] as logic
component [資料存取] as dao
}
package "資料層" {
database [主資料庫] as db
database [快取] as cache
}
}
ui --> client : 使用者操作
client --> api : HTTP 請求
api --> logic : 處理邏輯
logic --> dao : 資料操作
dao --> db : 持久化
dao --> cache : 快取
note right of api
RESTful API
或 GraphQL
end note
@enduml
此圖示展示了在決定自建或採購日誌彙總服務時的決策流程。
自建或採購的考量
- 如果日誌資料涉及敏感資訊,可能需要自建服務以滿足安全和合規要求。
- 對於大多數企業來說,採購現成的日誌彙總服務可以節省開發和維護成本。
- 需要根據業務需求和預算限制進行仔細評估。
內容解密:
此段落詳細分析了記錄彙總在 DevOps 環境中的重要性和實施挑戰。首先介紹了記錄彙總的效益,包括提升系統可觀察性和問題排查效率。接著討論了實施記錄彙總面臨的挑戰,如成本問題和容量規劃。然後提供了爭取預算支援的策略,包括提前規劃、從小處開始和控制成本。最後探討了自建與採購日誌彙總服務的利弊,並給出了相關的決策流程圖。整體而言,本文內容強調了在 DevOps 環境中有效實施記錄彙總的關鍵要素和決策考量。
透過上述分析,我們可以看出,在 DevOps 環境中實施記錄彙總既能提升技術效率,也能帶來諸多挑戰。企業需要根據自身需求和資源狀況,選擇合適的日誌彙總策略,並有效地爭取預算支援,以實作最佳的業務成果。