案例|某城商行Zabbix 監控架構分享

AcidGo

  • 某城商行基礎架構運維工程師

  • 2018年開始使用並在公司內部普及Zabbix監控系統,在內部生產環境使用Zabbix監控了多款存儲設備、數千臺操作系統主機、各個數據庫產品等多維度的監控覆蓋,開發了多個自定義監控腳本、應用監控框架和前端頁面展示。

Zabbix 平臺概述

平臺介紹

Zabbix 是一個基於 Web 界面提供分佈式系統監視及網絡監視功能的企業級開源解決方案。它能監視各種網絡參數,保證服務器系統的安全運營,並提供靈活的通知機制以讓系統管理員快速定位、解決存在的各種問題,藉助Zabbix 可很輕鬆地減輕運維人員繁重的服務器管理任務,保證業務系統持續運行。其後端使用數據庫存儲監控配置和歷史數據,可以非常方便地對接數據分析、報表定製等渠道,在前端開放了豐富的 RESTful API 供第三方平臺調用,整體架構在當下的 DevOps 的趨勢下顯得非常亮眼。

選型過程

我們於 2017 年開始接觸 Zabbix,之前運維內主要使用的監控系統是 Nagios,但 Nagios 的頁面展示、監控配置、自動化等各項功能對基礎架構的運維人員來說不是特別友好,而風頭正勁的 Zabbix 正好引起了我們的注意。基礎架構的運維工作中,需要面對各種各樣的監控場景,例如 PC 服務器的故障燈巡檢、存儲設備的陣列健康判斷、小型機 LPAR 的資源監控、操作系統的多路徑檢查,等等。而 Zabbix 內置提供了 SNMP、IMPI、SSH、Agent 等多種監控途徑,在系統架構的各層場景下都能很好的適配,其中 Agent 還支持自定義工具,總體的表現非常靈活。在網頁前端管理上,Zabbix 可以滿足各個粒度的監控管理,從整個集羣到單獨一個監控項都能夠進行細分管控,自定義 dashboard 和歷史數據可視化功能也極大地方便運維人員對監控數據的審查。綜合以上的考慮因素,行內選擇了 Zabbix 作爲一個新的監控平臺試點,從基礎資源的監控出發,首先將大部分存儲、主機和操作系統接管到 Zabbix。

使用現狀

2017 年底在基礎架構範圍內試行的 Zabbix 系統,從 3.2 版本開始逐步演進到現在的 4.4 版本,其中經歷了各項監控系統的里程碑事件。目前的 Zabbix 系統也由原先的小範圍試用,逐步擴展到涵蓋硬件、應用、平臺、業務等更大範圍的場景,架構上也從單數據中心進化爲三中心的分佈式部署。除了逐漸替代舊的監控系統,越來越多的第三方系統也開始對接起了 Zabbix,例如自動化運維平臺、持續發佈平臺、運維可視化平臺等,通過 API 或者數據庫抽數的方式,使用海量的運維監控數據實現智能運維的工作模式。

在編寫此文前不久,我們也順利完成應用系統監控遷移到 Zabbix 平臺,作爲一名全程參與 Zabbix 系統推廣實施和自動化開發的運維人員,非常榮幸能夠見證我們運維力量的茁壯成長,在此,本人也將從架構部署、監控維度、自動化方案、運營管理層面,分享我們 Zabbix 系統發展壯大的經驗。

硬件監控

數據中心的運維管理中,系統架構的縱向深度是非常陡長的,包括最基礎的硬件設備也需要運維人員費盡心思地去巡檢排查,但隨着數據中心的設備數量呈爆發式增長,人工巡檢已不能滿足當下監控實時性、可靠性的要求。對於這種低層級的監控,Zabbix 的多維度特性就非常好的解決了這個問題,其內置的 SNMP/IPMI 協議能夠輕鬆對接相關硬件設備的帶外監控。

目前我們使用 SNMP Agent 的被動方式定期巡檢硬件設備的基礎指標,例如故障燈信號、電源功率、內存信息、磁盤陣列等,代替人工巡檢的方式來實現異常捕獲,並對數據中心內的所有設備做到硬件信息採集,定時更新至 CMDB。例如以下爲部分華爲 RH2288 V3 IBMC 監控模板中自動發現的配置:

Zabbix 配置硬件監控的操作過程也非常便捷,大部分都是在網頁界面配置,只需要定義好 SNMP Agent/Trap 的接口或 IPMI 傳感器目標端口後即可靈活定義監控項。對於 IPMI 監控的配置,主要是將傳感器的名稱填入即可,目前我們對 IPMI 的帶外監控使用的相對較少,主要是部分浪潮 PC 服務器在使用,對 IPMI 更多地考慮應用於在如 VMware vSphere 的 DPM 等帶外管理上。
在硬件監控選擇監控協議時,保持的一項原則是:能用 SNMP 就不用其他,能用 SNMPv3 就不用 SNMPv2。因爲 SNMP 在 Zabbix 中可以非常靈活的實現自動發現,而 SNMPv3 可以提供更健壯的認證機制,因爲在開放硬件監控的同時也必須考量網絡安全的風險。對單個 SNMPv3 的監控項配置如下,大部分參數都提供了輸入窗口:

對於上述提及的 SNMP 配置自動發現的靈活性,這也是依賴於 SNMP 設計的原理,藉助樹結構的索引方式,可以根據 index 字段枚舉現有元素的數量,然後再根據數量長度來遍歷下一層元素。對於這種遍歷,Zabbix 自身提供了友好的 discovery[{#SNMPVALUE},OID] 函數來完成,無縫對接到內部通用的自動發現數據結構。整個 SNMP 自動發現的機制原理如下由於我們 Zabbix 的起步試點是從基礎設施運維開始,加上 Zabbix 對 SNMP/IPMI 協議配置的操作非常方便,所以經常可以根據廠家提供的 mib 文件及 mib 文檔說明即可篩選出需要自定義的監控,這樣既可以通過減少採集來降低管理系統的繁忙度,又能優化監控質量。例如以下爲根據 Lenovo XCC 帶外管理系統的 mib 說明(http://www.circitor.fr/Mibs/Html/L/LENOVO-XCC-MIB.php)來自定義配置的 ThinkSystem SR650 的 SNMPv3 監控使用效果:

上圖中的電源、陣列、磁盤等均是通過自動發現的規則來生成的,這對擁有不同陣列卡數量、網卡數量、路數等的 XCC 帶外服務器,都可以使用同一個模板,設備變化完全交給 Zabbix 維護。另外,分享一個定製 SNMP 監控過程中的經驗,首先在 MIB 文件中收集所有需要監控的指標,對篩選的指標做分組,找到每個組的最高父級索引的 OID,然後在 Zabbix Proxy 上使用 snmpwalk 遍歷這個 OID 找到所有 OID 內容,區分出 Index 和 Detail 後,劃分常規監控和自動發現監控,最後使用 snmpget 來逐個獲取 OID 的值確定對應 Zabbix 上的數值類型。需要特別注意,snmpwalk 是遍歷,並不需要 OID 的完整值,而 snmpget 則是根據一個完整的 OID 來檢索,對應於 Zabbix 則是 snmpwalk 類似自動發現,snmpget 類似常規監控項。

存儲監控

在數據中心中,存儲設備是非常核心且關鍵的基礎設施,任何一個相關告警都會讓運維人員警覺。在推進 Zabbix 的存儲監控的過程中,體會到一個非常棘手的困難點,即存儲不單單是硬件設備,SNMP 的協議不能獲取到帶內的性能信息,但也不像主流操作系統那樣可以安裝 Zabbix Agent 來做數據採集。對於這種問題的處理,我們積累的經驗是,首選使用 RESTful 等外部接口來獲取監控數據,在不支持此條件的情況下,在 Zabbix Proxy 服務器上通過自定義監控封裝廠家推薦工具或方法來監控。

Zabbix Agent 支持運維人員自定義監控,將執行命令封裝成一個 Zabbix Item Key 來供 Zabbix 調用,也支持額外的安全策略,例如 AllowRoot 可以設置是否允許 root 來執行 agent,UnsafeUserParameters 參數能夠過濾特殊符號注入。我們對自定義配置的標準,以 RedHat 基線爲例,在 /etc/zabbix/zabbix_agentd.d 目錄一個監控類爲一份 conf 文件的形式保存,命名形式爲 ClassA_ClassB_Detail.conf,並且定義的執行文件均放置於 /usr/local/zbxexec/ClassA/ClassB/xxxx.xx。

對於自定義監控項的方法,能夠便捷地對接各個存儲廠家的產品監控方式,將廠家建議的監控命令封裝爲 Zabbix 的一個監控項。這類被封裝的方法主要是 CLI、RESTful 和 SSH,例如以下我們目前對各產品使用的監控方式:

方式 產品 工具
CLI unity uemcli
CLI vnx naviseccli
RESTful VMAX requests(Python)
SSH V7000 OpenSSH

除了跟廠家溝通對接 Zabbix 外,其實也可以藉助開源生態和 Zabbix 的合作推廣,也有很多企業與我們一樣會分享 Zabbix 的經驗、模板、工具到 Zabbix Share,可以斟酌篩選後使用。同時,Zabbix 也一直努力與其他廠家共同合作,共同推出每個廠家在 Zabbix 上的官方監控模板,例如 DELL EMC 在 Zabbix 中推出的各個產品的監控模板(https://www.zabbix.com/integrations/emc)。

通過上述的監控方式,Zabbix 對生產環境存儲設備的監控效果讓運維人員感到比較滿意,agentless 的架構避免對重要設備的侵入,同時相關的存儲告警也能夠及時觸發,並幫助存儲管理人員迅速發現問題、定位原因。

主機監控

我們目前的主機監控主要包含了 Power 的小型機和 x86 的 ESXi,這類對象有一非常明顯的特點,就是數量和信息不固定。一臺小型機可能需要爲新部署的數據庫劃分物理分區或虛擬分區,亦或者要調整某個數據庫的 CPU 分配;一個 vSphere 集羣可能會擴容 ESXi 主機數量或資源,亦或新建一個集羣。在這種多變的的環境裏,首先考慮的是使用 Zabbix 的自動發現來適配,並且此場景有一個非常明顯的相似特性,就是需要一個主控端來管理整個主機資源池。因此,我們對主機的監控常常採用的原則是,通過監控主控端來自動發現主機,讓被發現的主機自動使用對應模板

上述的監控流程主要是依賴 Zabbix 的自動註冊主機來實現,不同於硬件監控中提及的自動註冊監控項,這裏的自動註冊會直接根據主控端獲取的資源列表,自動註冊一個待監控的主機,相關的主機配置包括主機名、可見名稱、agent 接口等都會繼承主控,然後會爲每個主機都綁定一個預先配置的監控模板。如果主控端發現某一個主機不在上一次收集的資源列表中,會在超過資源保留策略時間後,自動刪除該主機。例如自動發現的 ESXi 主機:


操作系統監控

操作系統的監控是非常龐大的,除了操作系統種類多,每個操作系統內的監控項數量也是覆蓋面廣,再乘上物理機、虛擬機的數量,整個監控面積會非常之大。另外,將每一臺服務器納管至 Zabbix 中的操作也變得異常繁瑣。對此,我們保持的思路是,通過自動化手段讓服務器自動上報到 Zabbix,優化模板以減少重複監控,定製觸發器的依賴關係

操作系統的監控都是使用 Zabbix Agent 方案來實現的,Zabbix 也推出了各種操作系統的 agent,不需要編譯就能直接運行。對此,我們的所有虛擬機基線、小型機備份、物理機 Ansible 部署腳本里,都會事先準備好對應操作系統的 Agent 安裝和配置。其中,推薦使用被動方式,並且主要修改 agent 配置的如下內容:

# ...
# 衆多 Zabbix Proxy 中的兩個
ServerActive = 10.10.32.1,10.10.32.2
# 其中 10.10.32.0/24 爲當前機房的 Zabbix Proxy 節點網段
Server = 127.0.0.1,10.10.32.0/24
# Hostname 是這臺服務器的管理 IP
Hostname = 10.10.33.1

這種配置主要是方便於 agent 在多個 Proxy 中平移,在故障恢復、Zabbix 升級等場景下,可以非常便利的保證 agent 的持續有效。另外將本地迴環地址也寫入 Server 中,方便以後需要在此操作系統中通過 agent 調用本地腳本。Hostname 在被動模式下並不是必須的,配置管理 IP 可以保證主動模式和配置管理的便利。

以上僅是 agent 的配置標準,如果需要自動上報至 Zabbix,還需要其他步驟。目前我們對於物理機和虛擬機的 x86 操作系統實現了自動上報主機的機制,每天上午八點會做一次上報,然後對新增的主機自動加入維護模式,避免部署階段中各種不關鍵的異常帶來告警風暴,直至系統穩定纔會退出維護模式。在物理機的部署中,我們除了一套完善的自動化 RAID 配置PXE 安裝系統外,還有對操作系統配置基線的 Ansible 方案,每個操作系統的 roles 裏,都有一個 Install Zabbix Agent And Report 的 task,這樣通過實現配置的好的 vars 即可將此主機以標準命名添加到 Zabbix 中。而對於數量龐大的虛擬機,我們編寫了一套 Python 腳本,掃描各個機房 vCenter 中的虛擬機獲取到每日的虛擬機差異,再使用其在 CMDB 的屬性、vCenter 上的備註,來填充業務系統、應用集羣、服務器描述等,最後註冊到 Zabbix。這種機制除了極大程度地解放運維人員對新系統的主機監控註冊外,還可以在腳本中指定納管策略來實現各種額外的預期目標,列舉以下幾點:

  • 根據網段信息,將同機房的服務器接口對接同機房的 Proxy,避免機房流量交叉。

  • 通過判斷當前 Zabbix 各個 Proxy 的 vps,將新增主機接入到低負載的 Proxy。

  • 將 CMDB 中現有的信息填入到被註冊主機的標籤和資產信息中。

其架構上的拓撲簡化如下:

在這套自動化機制下,極大地減輕了運維人員對監控配置的厭惡,也加到了對我們 CMDB 的關聯,爲以後的工單系統打下架構基礎。但是,我們對監控系統的分析和探索沒有僅僅止步於此,考慮到操作系統監控中觸發器帶來的大量告警,我們也研究了一些額外的措施,避免太寬泛的告警湧現。

首先,將模板細分爲各個類別作爲基類的 template,然後根據應用場景來指定上層的模板由哪些基類組合,避免太多的定製模板中近似功能的監控帶來重複監控。然後,對每個模板中的觸發器指定嚴格的依賴關係,避免告警的連帶觸發導致風暴。例如 Linux 系統的分區容量監控觸發器,我們制定了幾個水位線之間的依賴:


數據庫監控

數據庫監控也是一條每個運維人員心中緊繃的弦,除了普通的表空間使用、會話數量、SGA 使用、ASM 使用、緩存命中、刷髒頻率等,還有宕機、切換等狀態檢查。加上我們近幾年分佈式數據庫落地,及嘗試國產數據庫的背景下,越來越多的數據庫產品需要對接至 Zabbix。目前我們對數據庫的監控,結合了多種監控思路,制定了各種數據庫產品的監控指標,在性能數據追溯與故障告警的場景下都體現出非常優秀的表現。

在金融行業的傳統架構中,Oracle 數據庫往往是不可或缺的一個基座,我們通過模板定製,提供了 Sinlge-Instance、RAC、DG、F5 等多種架構的模板,覆蓋了大部分 Oracle DBA 關心的監控項。在 Zabbix 中專門使用一臺高性能的 Proxy,通過自定義監控的方式來執行 Oracle 監控腳本。除了應急的故障告警外,現在 Zabbix 也成爲了 DBA 分析數據庫性能的工具,對比歷史數據排查數據庫問題,這也依賴於 Zabbix 保存的大量監控信息。如下爲其中有給數據庫的性能與 RAC 部分監控指標:

除了傳統架構的數據庫,我們對其他數據庫產品也提供了全面的監控,並且對此監控採用了主控服務(RootService)的思路,將數據庫更自動的納入監控中。這種方法的優點是可以完美展現 Zabbix 自動註冊主機的機制,將數據庫添加到監控中,並使用自動註冊監控原型的方式來識別數據庫開啓了哪些需要監控的細節。目前我們編寫了 OceanBase、巨杉數據庫、MySQL、DRDS 等數據庫產品的監控腳本,在 Zabbix 中以全新的數據庫監控架構運行自管理。此框架的工作流程如下。

以 MySQL 的監控爲例作爲詳細描述整個過程,參見下圖。

在 MySQL 實例的配置 zbx_mysql.py 文件中,新增一個 testenv_zabbix 的數據庫實例,這份文件是通過 acl 設置僅爲 zabbix 用戶讀取的。當作爲 MySQL RootService 的主機執行自動發現主機的監控時,會將新增的實例配置生成 Zabbix 自動發現的 json 規則,根據配置信息創建監控實例,並附加使用 MySQL 基礎模板。在 MySQL 基礎模板中,配置了一系列特殊的監控自動發現規則,例如 Discovery MySQL Replication Enable 會對發現的實例執行 show slave status 命令,這裏仍會調用 MySQL RootService 的腳本,如果發現目標實例開啓了主從,則會在自動發現返回 josn 中包含一個 {#REPLICATION}: "enabled" 的字段,從而觸發主從複製的監控項生效。

創建一臺邏輯主機作爲主控服務,以鏈式發散的傳播模式自動註冊主機,然後根據模板內的自動發現判斷是否需要附加額外的監控配置,這種在我們創新使用的監控方法,取到了非常好的成效,讓監控系統變得更加智能,也不用像某些數據庫監控還需要將連接的用戶與密碼寫入到 Zabbix 的宏,而只要保證讀取的配置文件在文件系統的 ACL 上是最小權限即可,提高了數據庫的訪問安全。另外一點,現在很多的分佈式數據庫也是採用 控制+計算+存儲 的架構,例如 TiDB 的 PD 負責元數據管理、DB 負責 SQL 解析與計算、KV 負責底層鍵值對存儲,面對衆多的分區也好,副本也罷,最有效的監控方式就是直接對接其管控部件,將 Zabbix 主控服務的起點映射至數據庫集羣的管控上,不斷順着架構分層,將各個組件之間的監控項固化成自動發現規則,實現精準有效的監控覆蓋。以目前我們的 OceanBase 分佈式數據庫監控爲例,以下從 OB RootService 自動發散出 OB Zone、OB Tenant、OB Server、OB Partition 等監控細節。

除了監控架構的不斷靈活,我們也在考慮更加深入的監控效果,對於數據庫的監控排查,DBA 更多地希望所有相關的告警都是同一個時間點的,這樣更加便於橫向參照。根據這個出發點,運維人員利用“監控快照”的思想,將監控項儘可能多地集中在同一個時間點上,這樣也能極大減少監控數據庫時頻繁交互帶來的性能損耗。實現這一點,主要藉助於自定義腳本規範和 Zabbix 監控項中的相關項目依賴特性。以巨杉數據庫的監控作爲例,也正好通過巨杉數據庫快照動作具有一定的性能消耗來說明減少交互頻率的重要性。

這臺測試環境的巨杉數據庫集羣的 Coord 主機,總共有 56 個監控項,如果每一個監控項都需要單獨連接到其中一個協調節點並做快照獲取對應的監控指標,那麼集羣對於這些頻繁的快照操作會付出非常大的性能成本。但實際上,這裏真實的監控項只有 3 個,也就是截圖中的 multi_snapshot_SDB_SNAP_* 開頭的,其餘的都是由這三個監控項派生出來的,也就表示交互次數可以從 56 次縮減到 3 次。我們對這種方案的實施,是通過自定義腳本或 LDD macros 來生成一個包含各個子監控項的 JSON,並設置爲不保存歷史記錄,這一點非常重要,因爲子監控項的生成是在父監控項轉儲前計算得到的,保存大量被拆分的冗餘 JSON 字符串也沒有實際意義。在子監控項的生成動作中,主要使用了 Zabbix 監控項的預處理操作,使用 JSONPath 將對應的 K/V 抽出,再通過倍數/每秒變更/正則等方式獲取到最終的子監控值。雖然預處理會消耗 Zabbix 的 CPU,但是實測調大 StartPreprocessors 參數後,CPU 沒有明顯的攀升,而且 Zabbix Proxy 是分佈式可擴展的,這種瓶頸也非常容易通過擴容來解決。綜合評估下來,這種方案帶來的回報是很可觀的,當出現數據庫問題時,或許更多的 DBA 希望回溯監控歷史,能夠看到的是這樣同一時間平面上的各項指標:


應用監控

當監控的考慮維度上升至應用組件時,我們依舊堅持使用自動化的方式去面對眼花繚亂的監控需求,思考如何讓應用的監控更加富有生命力,同時也分析了在過去使用 Nagios 進行應用監控時遇到的痛點,最終,編寫一個框架級別的工具,接管應用的監控生命週期。這個框架在我們內部稱爲 zbx_app,通過一個文件服務器和應用監控的準則來完成運行,可以自動完成自定義腳本拉取、版本迭代、自動註冊監控項等,運維人員僅需要編寫一份應用監控的聲明文件,其他工作完全交由框架執行。

此框架的內部原理,主要是通過 Zabbix 發送來特定的監控項和自動發現作爲更新配置與自動檢查基礎環境的信號,如果發現文件服務器的相關模塊版本更新則會主動拉取文件,從而實現自管理的操作。這個接收特定信號並管理自身的環境的模塊我們內部稱之爲基類,所有的模塊監控會有一個自動發現規則與基類交互,如果基類聲明文件裏包含了請求的自動發現模塊,那麼就會應答,讓 Zabbix 感知並利用返回的結果來生成此模塊的監控項。對應的監控項生成後,每個監控項會使用快照的方法去捕獲一次監控目標,然後再由監控相關項來拆分同一時間點上的各個子項。在這個調用的階段,也是與基類交互的,只不過基類會根據其模塊名來調用同步過來的模塊方法的固定接口,這些接口是編寫這類模塊的開發準則,目的是爲了保證基類能夠順利調用並解析。

把考慮對象限制在一臺主機上,簡化這個流程,可以有如下的時間線,由上至下是時間前進的方向。

  • Zabbix Proxy 會調用 Discovery APP 自動發現,觸發主機初始化一次當前的 zbx_app 基類,基類收到信號後也會掃描環境,主要是收集各目錄下的聲明文件(lps.cfg),並根據聲明文件做一次基礎環境配置拉取,然後返回 Zabbix Proxy 相關信息。

  • Zabbix Proxy 收到了基類生效,其他模塊的自動發現也會緊隨着對主機做一次探測,發送各自的自動發現信號。

  • 基類發現聲明文件裏存在 redis 的模塊聲明,那麼會把內部信息整合爲自動發現返回結構體,Zabbix Proxy 感知後會生成對應的監控項。

  • Redis 模塊持續發送監控快照請求至基類,基類收到後會調用已經從 HTTPFileServer 上拉取下來的 redis 模塊來執行監控請求,並返回結果集。

  • 如果過程中應用維護人員將 url 模塊的監控需求寫入聲明文件,下一次接收到 Discovery APP 信號時,基類會發現新增聲明,迅速前往 HTTPFileServer 拉取指定版本的 url 監控模塊。後續 URL 的監控也會與 Redis 一樣持續生效,直至聲明文件刪除或註釋了此模塊。

  • 如果過程中自動化開發人員對版本庫裏的 redis 模塊更新了代碼,基類也會在下一次接收到 Discovery APP 信號後對比 MD5 列別發現版本更新,從而拉取替換爲最新版本。

使用自管理的基類實現了應用監控的閉環納管,監控的操作上,細分了自動化開發人員開發模塊職能,也給應用維護人員更多的自由度去聲明自己需要的應用監控。而且,對基類的動作也納入一個監控項,能保證基類自己的穩定,不至於罷工後無人知曉。
通過這個框架,我們將應用監控從上一代的 Nagios 系統成功地遷移到了 Zabbix 系統,並且維護成本變得更低,運行模式更加穩定。

業務監控

當有了強大的應用監控框架支撐後,運維人員也開始更往上地關注更上層的業務監控,業務的特徵也是整套架構運行穩定的最直白表現。Zabbix 提供了數據庫的監控,直接在網頁界面直接編寫 SQL 語句,由 Proxy/Server 通過 unixodbc 加載對應驅動去連接目標數據庫,最終返回執行結果。目前我們利用這種方法,對業務的狀態信息、交易成功率、設備報活、跑批等進行數據庫查詢,再通過 Zabbix 的告警渠道發送告警信息給全行訂閱了這個業務系統的技術人員。直接在網頁界面編寫 SQL 能夠適應業務查詢的多變性,當受監控業務新增一個子系統時,僅需要在其監控項裏連接一個新表,不需要修改自定義腳本。另外,這種方法可以降低自定義腳本的維護成本,ODBC 提供了多種數據庫的驅動,在網頁端開來底層一切都是封裝好的,沒有必要去考慮連接如何初始化、怎麼建立遊標、合適釋放會話等。當獲取到各個業務的監控數據後,能夠平滑地對接到 Zabbix 的 dashboard,爲各個業務創建一個監控面板,實現大屏展示的效果。


在實踐過程中,對於這種便捷的監控方式,要特別注意幾點:

  • 在文件系統上縮小 odbc 連接配置文件 odbc.ini 的權限,僅保證 zabbix 用戶可訪問,修改由特殊用戶修改。

  • 規範 SQL 編寫規則,不允許出現執行成本較大的語句,這也需要跟 DBA 溝通好。

  • 儘可能地讓結果集返回一行甚至一行一列。

  • 把數據計算操作分攤給 Zabbix 預處理,不能把太多的計算操作下推至數據庫層面。

頁面監控

從上面討論的各個監控維度上看,在一個運維的縱向座標上,從硬件監控到業務監控,實現了最底層到最頂層的全方面的監控覆蓋,多個層面保證了監控系統能夠快速發現問題故障,進行準確的告警報送。但運維人員對監控的思考還沒有結束,進而思考一個問題,監控的點位夠否不單單在縱座標上移動,而是可以前移至“未來”的時間點。例如不僅僅是用戶登錄系統進行交易後才觸發一次失敗才產生數據被監控,而是週期性地去探測一次交易前置條件,即便在沒有客戶進行交易時,也會有 Zabbix 在交易頁面上探測需要資源是否具備。這樣能夠保證比真實客戶更早的發現一些交易平臺的頁面異常,在邏輯上實現了”預知“的效果。另外,可以通過多個運營商線路去做頁面監控,更加全面地覆蓋客戶案例,在發現異常時,也能夠對比其他線路是否存在運行商的網絡問題,例如 CDN、黑名單等。

我們使用 Zabbix Web 的監控方式,通過防火牆和 NAT 的網絡隔離,使用 Squid 實現線路選擇,以及運用 selenium 等自動化工具進行頁面動作模擬,實現了網銀系統的內外網、運營商線路層面的監控。


平臺監控

除了上面提到的監控以外,有一個特殊場景,是運維人員難以迴避的,那就是某一些系統自帶了一套監控平臺,但目前使用的主流監控卻無法兼容或替換掉它,當引入組件、產品逐漸增多時,這種問題就越發明顯。例如移動開發平臺 mPaaS 中自帶了例如 monitorkernel、corewatch、monitorguard 等監控組件,對整個 mPaaS 平臺運行具有非常重要的作用,如果考慮使用其他監控系統將其替換,技術磨合的成本也會非常巨大,而且也丟失了平臺自身的穩定性。對此,我們決定使用自建外部渠道加 Zabbix Sender 實現外部平臺以監控流的方式對接至 Zabbix,這樣既能既能避免對原有第三方監控系統的侵入,也能讓其監控數據匯聚到 Zabbix。
首先,這裏介紹一下 Zabbix Sender 的原理。當受監控的主機在 Zabbix 中是處於主動模式的話(大部分主機是被動模式),該主機可以自行構建一個已存在的監控項數據發送給 Zabbix,而 Zabbix 收到數據進行驗證後,也會作爲該主機的監控項數據,這樣也可以實現監控的實時性。當對接主機的上游是第三方監控平臺時,整個流程看起來就像動態的數據流一樣,從上游不斷流入至 Zabbix。對接上游第三方平臺的實現,我們目前有如下方案:

  • 當外部平臺支持 HTTP RESTful 的監控對接時,將其對接至一個專門負責接受此類告警的 HTTP 服務器,併爲其設置一個獨立的資源路徑的 handler。

  • 當外部平臺不支持監控對接,但支持告警推送,可以將接受的告警級別調至最低或全量,將其發送給 HTTP 服務器、TCP/UDP 服務器或郵件服務器。

  • 當外部平臺沒有任何渠道外送信息時,會選擇網頁爬蟲、數據庫監控等方式,當這樣也會丟失監控流式的特性。

以目前遇到的情況,幾乎沒有第三種情況,一般都是提供 HTTP 外推監控或告警的,所以這類都會接入到我們一個使用 Golang 編寫的專用 HTTP 服務器,在每次新增對接平臺時,增加對應的 handler 中的 OtherReaderZBXSender 接口實現即可。但需要注意對於這種方式的觸發器,需要着重關心 change()/diff() 函數的依賴,因爲有時候同一個監控項推送頻率會非常高。
還是以上面提到的 mPaaS 爲例,通過這種方式對接其核心監控平臺 corewathc,能夠獲取到此平臺的所有告警監控。


告警通知

監控覆蓋的話題,到此也算是結束了,下面進而討論下一個環節,那就是監控觸發的告警需要如何才能推送到需要接收的技術人員。其實,Zabbix 自身也提供了非常多樣的告警推送渠道,也可以自定義腳本來處理告警內容再推送給至渠道。但我們選擇將這個推送的渠道稍微拉長,讓告警發揮出更多的作用。
如果告警無法推送,那麼監控的意義就少了一大半,但推送的太多,告警也就沒有價值可言。Zabbix 的告警消息結構體只是一個字符串,有些特殊符號混雜會對後面的序列化動作觸發異常,抑或發送告警的 Proxy 宕機了,而大量告警卻發不出來。由此種種產生的困擾,想必每一個接觸過告警的技術人員,都會深有感觸。爲了解決這些最後一百米的問題,我們也不斷地嘗試各種方法,目前也依舊在努力尋求突破。
我們編寫了一個內部命名爲 Zabbxi Robot 的工具,可以按照預定的 Zabbix 告警字符串進行 JSON 解析,並在預處理完後,會判斷此告警是否需要抑制,是否屬於一次需要收斂的抖動,然後才把告警推送至下游。另外,在 Zabbix 的架構設計上,將一個負責主要告警推送的 Proxy 與 Server 配置爲互相監控,而 Server 會有兩個推送渠道在主渠道失效後進行通知,進而避免告警空白。

這裏的短息貓通過 gnokii 調用串行接口實現的短信發送,發送效率非常低,僅當探測發現 Zabbix 架構出現重大故障時,會應急發送給幾位負責監控系統的運維人員。而備用渠道與主要驅動實現方法都是把告警信息以 curl POST 的方式傳送給 Zabbix Robot,不同點在於兩者使用了不同的 Header,從而在 Zabbix Robot 中區分出具體的渠道,也會對此過濾。Zabbix Robot 是我們使用 Golang 開發的 HTTP 服務器,目前具備兩個模塊,先觸發抑制模塊,後觸發收斂模塊。這裏的抑制操作是以 LimitUnitGroup 來生效的,當期觸發條件滿足每一個 gorup 的三元組({flag, number, second},當判斷爲 flag 的告警,在 second 秒內收到了超過 number 數量)時,則會使用 flag 派生出一個 InhibitionUnit 的 goroutine,而這個 flag 如果存在 InhibitionUnit,那麼就可以判斷處於抑制狀態,不會發送出去。
InhibitionUnit 也是一個三元組({flag, number, second}),當判斷爲 flag 的告警,在收到 number 數量後或超過 second 秒後退出此次抑制。而在 Zabbix-Robot 的配置文件裏,細分了每個 flag 和其屬性。一般而言,目前常用的 flag 就是 Zabbix 的 TRIGGER.SEVERITY,即告警級別。
收斂模塊是目前在測試階段的一個功能,優先實現了 Weights 的方法,即判斷收到告警與過去三十分鐘(可調)樣本中的 hostid*X+itemid*Y+triggerid*Z 總分,如果超過預定值 K,則會被判定爲抖動進而收斂。這裏的 X/Y/Z 是可自定義的權重,比如可以通過提高 X 來把收斂權重傾向於主機,那麼同一臺主機發送的告警數則會被優先收斂。另外還有其他收斂的方法,比如字符串特徵和機器學習,這兩個也是我們嘗試的方向。
當走完抑制和收斂,告警會流向我們的自動化平臺,並由平臺判斷是否派生工單,然後再經訂閱系統把告警發送給指定負責人後,負責人將在工單系統反饋處理情況。這裏的訂閱系統也對接了 Zabbix 的一些元數據,Zabbix 在 4.0 後推出的標籤功能(tags)非常便利與做告警篩選,如果使用過 K8S,那麼可以將這種篩選過程理解爲 Labels 和 Selectors。

目前這套告警推送流程,解決了原先的大部分問題,也能讓 Zabbix 爲工單系統、訂閱系統提供有力支持,Golang 天生強大的併發能力也能非常有效的抵抗告警泛洪,而且其也是無狀態的,在未來甚至可以部署雙節點來實現高可用。

報表生成

爲了讓 Zabbix 具備更多的報表展示能力,我們也對其前端進行了一定的定製開發,將常用的一些報表對接至 Zabbix。同時,Zabbix 也提供了資產清單、自定義拓撲、dashboard 等功能,具備了一定的報表生成能力。
像上面提到的頁面監控,其實也是一個內外網的流向拓撲,可以將各個層面的頁面分別前後對接,那麼就可以提供非常優秀的問題定位能力。

除此,還有每日一更的容量清單、硬件信息、巡檢報告等。就如其中一個 VMware 虛擬機互斥檢查爲例,其通過樹形圖的形式,展示出每個業務系統的應用模塊中,判斷冗餘節點是否部署在相錯的資源(ESXi 或 LUN 或 Cluster)上的,這樣方便虛擬機管理員分離關聯虛擬機,降低發生 HA 時受影響的系統模塊,也能夠保應用證同城災備的建設是否符合預期。


高可用

在 5.0 之前,並沒有官方的 Zabbix 高可用方案,我們採用的是數據庫級別的恢復方案。通過定時腳本,每日凌晨(注意,這裏要儘可能錯開 Housekeeping)將 Zabbix 中排除 history* 的表和 zabbix web 前端文件備份到災備機房。如果發生不可恢復的故障,可以重新部署 Zabbix Server,並恢復數據庫,這樣的代價僅會丟失歷史數據和趨勢,但能夠快速恢復監控運行的狀態。
此外,建議 Zabbix Agent 的被動模式 Server 的地址配置爲 Proxy 的網段,這樣當 Proxy 出現故障時,也能夠快速平移至其他 Proxy。

未來規劃

在我們使用 Zabbix 的兩年裏,運維也開始了全面的自動化,在這個背景下,我們越來越多地認識到監控的價值,監控也不單純是告警廣播,需要有更多智能的方式去挖掘監控的潛能。在這兩年多的時間裏,我們對 Zabbix 系統進行了各方面的功能擴展,也期待未來會有更多的發展可能。現在,對未來的規劃,細數下來,有如下幾點。

Zabbix 數據庫選型

目前生產使用的 Zabbix 數據庫架構是 Zabbix 4.4 + Percona 8.0 + TokuDB,TokuDB 主要是用於 history* 表,並且對 history* 表都進行了分區,而其他的配置表仍是使用 Innodb,TokuDB 使用 QUICKLZ 的壓縮算法。另外,對數據庫的配置進行了優化,例如雙 1 這類需要性能成本的設置也統統改爲性能爲主。在剛遷移到這個架構時,壓縮率和歷史數據 QPS 都有非常顯著的提升,但是隨着監控項數量的增加,也開始慢慢感受到了瓶頸與壓力。歷史數據即便開了壓縮也不能抑制上漲的趨勢,而開啓管家後每次刪除過期數據帶來的 CPU iowait 也令人煩惱,當查詢大量冷的歷史數據時,漫長的加載時間也讓人崩潰。
我們在測試環境的 Zabbix 平臺,納管了幾倍於生產環境的主機數量,可以當成是一個實打實的壓測場景。爲了尋求最佳實踐,我們在測試環境先後測試了 TokuDB、RocksDB、TiDB、Elasticsearch、TimescaleDB 等數據庫產品,其中我們基於 4.8 版本的 Zabbix 稍微改造了一個兼容 TiDB 3.0 的版本(https://github.com/AcidGo/zabbix_tidb),但無奈於 TiDB 對外鍵的支持並沒有符合使用的預期,不過對於歸檔歷史庫也許是不錯的選擇。在測試後,發現 Zabbix 5.0 + PostgreSQL TimescaleDB 12 的效果較爲理想,作爲時序數據庫解決方案,對於 history* 表的追加與範圍查找都非常適合應用場景,而且也支持指定天數外的壓縮,整體對比起來優於目前使用的 TokuDB 方案。此外,我們也會考慮使用一個數據庫作爲歸檔歷史數據,開啓更高的壓縮率,然後單獨部署一個只讀的 Zabbix Server 來進行訪問,從而把溫熱數據分離開來。

Oracle 數據庫監控改造

不同於 MySQL 或其他輕量一些的數據庫,Oracle 的連接需要耗費巨大的成本,不單單是龐大的外部驅動,還有 F5 架構下的擇路,加上龐大的監控項,經常會出現部分監控擠在任務隊列裏。目前已經實現了應用監控的改造,對 MySQL、OceanBase、巨杉數據庫等的監控也更換爲更輕便、更自動化的方案,因此也計劃着對 Oracle 數據庫監控方法的改造。首先是編寫一個連接池中間件,管理每個庫的連接會話,Zabbix Agent 對數據庫的檢測將通過 RPC 來調用中間件並返回結果,減少會話創建與銷燬的開銷。然後,規劃一次查詢儘可能多地獲取批量數據,例如可一次獲取所有表的當前表空間使用率,依靠 Zabbix 的監控項相關項和預處理,獲取一個時間點上的多項監控,從而減少 RPC 調用頻率。

告警自愈

目前我們的自動化成效顯著,自動化工具庫裏提供了多種解決方案的處理操作,我們預計未來低級別的告警,可以藉助這種強大的自動化能力,來實現自動痊癒的機制。

嵌套主機自動發現

在一些鏈式架構的場景,我們非常希望可以藉助 Zabbix 的自動發現主機的功能不斷沿着架構分層往下分岔衍生新的主機或主機羣組,例如巨杉數據庫中 Domain -> Database -> CollectionSpace -> Collection 的鏈式發現機制。但是在實際測試中,自動發現主機的功能僅能觸發一次,下一層的自動發現會丟失已經選中的模板。相關問題也反饋在了 Zabbix Forum(https://www.zabbix.com/forum/zabbix-help/404802-how-to-nesting-automatically-discovers-hosts-did-i-encounter-a-bug)。期待以後有類似的靈活方案可以實現這種順延架構脈絡的方式創建各個層面的主機監控。

容器平臺與分佈式應用的監控

容器的發展在近幾年突飛猛進,各種編排平臺也層出不窮,從 Swarm 到 Kubernetes,容器監控的演進也循循漸進。Zabbix 在 4.0 之後支持了 Prometheus 數據採集,對容器監控踏出了堅定的一步,加上結合 LDD macros 可以更靈活地對接 JSON 格式,未來可以將兩者結合起來,實現自動化的、容器級別的智能監控。

agent2 的使用

從我們在編寫其他運維工具的經驗來看,Golang 非常適合運維管理的二進制工具開發,強大的併發能力、靜態語言的穩定可靠和較低的學習成本,都讓工具的質量得到顯著提升。Zabbix 近期推出的 agent2 也由 Golang 開發,並且提供了接口規範,讓運維人員可以定製最合適的 Zabbix Agent。這一點,我們也在測試環境中探索,逐漸瞭解開發流程,相信不久後會隨着生產環境 Zabbix 升級至 5.0 時同時推廣強大的 agent2。

Zabbix 系統的推廣、配套工具的開發、監控依賴的細分、從舊監控系統進行遷移的推進,都是我們衆多運維人員在這兩年多的時間裏,不斷積累和創新出來的成果,在此由衷地感謝我們每一位運維人員的努力,也寄予堅定的自信去實現未來規劃的監控系統願景。


延伸閱讀


雲原生時代下如何打造開源監控體系.pdf

案例|太平洋保險基於Zabbix的智能監控體系

案例|上海銀行數據中心智能運維建設實踐

案例|九江銀行Zabbix監控系統實踐


掃一掃|加入技術交流羣

微信號|17502189550

備註“使用Zabbix年限+企業+姓名”

5000+用戶已加入!

一個人走得快,一羣人走得遠!

本文分享自微信公衆號 - Zabbix開源社區(china_zabbix)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章