一般zabbix告警主要能夠經過三種方式python
1. 自帶的直接調用消息接口服務 2. 執行自定義腳本發送消息 3. 經過send remote commend 的方式經過執行腳本發送
2和3的本質都只經過zabbix的action去調用執行服務器上的腳原本發送,報警信息經過在執行腳本後帶參數傳進去。
這個流程很容易跑通, 也很是的簡單可靠。 可是,規模稍大報警量一多,問題立馬就顯現出來了。mysql
* 報警阻塞,發送效率低下 * 這種狀況下, 報警是根據用戶一個個用戶發送。 也就是說, 若是這個報警有十個收件人,那要分到觸發十次發送腳原本實現發送。 * 而且這個發送仍是線性的不是多線程的, 要等上一個發送完了, 再接着發送下一個。報警稍微多一點或者收件人稍微多一點, 這個報警的延遲就很大了。 * 風暴控制 * 網絡抖動是個大坑, 經過proxy的能夠經過依賴來實現必定的風暴控制, 可是直接經過服務器監控的就很難作了 * 一旦風暴, 很難退出。 若是sever到某個直連的idc 間網絡一抖動, 觸發大量報警,只能等action 執行完 * action 維護麻煩, 這種模式下, 報警匹配發送給誰有 action來決定,有多少種組合就會有多少個action, 會致使 action的數量不少維護起來至關麻煩 * 報警配置維度單一: 例如 業務dba 僅只想接受業務相關報警, 不想接受機器層面的報警, 看似簡單的需求配置起來會很麻煩甚至難以實現 * 報警信息單一: 好比要給報警內容里加上一個負責人,方便escalation後直接聯繫直接負責人都挺麻煩。
爲了解決以上問題, 我設計了smail 1.0來解決
正則表達式
smail 有規則解析和風暴控制兩個模塊組成sql
規則引擎: * 規則引擎直接定了一個規則語法, 主要實現支持從 設備名字和觸發器名字兩個維度來匹配報警, 對於符合匹配規則的報警則發給對應規則的收件人, 匹配規則支持正則: * 匹配規則支持正則表達式 * 判斷故障級別, 根據級別確認發送短信微信仍是郵件
風暴控制: * 風暴控制經過報警發送數量計數,對單位時間內發送數量超過必定數量則觸發風暴控制, 中止發送報警。
效果:服務器
1. 極大的簡化了報警配置, 僅配置了兩個action。 規則引擎直接使用yaml 配置文件和正則配置方法, 對於 python棧的維護人來很是順手。 2. 發送效率提升,對於一個報警, 不管發送人數多少, 都只須要觸發執行一次腳本。 3. 報警的可追溯,日誌詳細的記錄了報警的發送狀況 4. 同時,對報警也加入了更多的信息, 更加方便接受者判斷
這時報警郵件就變成了這個樣子
微信
但是依舊存在的問題:網絡
1. 發送效率依舊不高, 經過 os.fork action 依舊要等執行完後再執行下一個未能實現異步。 2. 經過簡單計數的風暴控制機制基本沒用
2.0 版:
主要以解決發送效果爲目標。 主要是引入異步任務隊列來實現發送的異步,分離action 觸發腳本加快 action的執行速度。
多線程
實際動手過程當中發現, 若是要引入mp或者 celery這樣的 task queue會新增兩個damon,這樣反而增長了複雜度。異步
後面直接使用了下圖這樣的簡單粗暴的方法來實現
spa
triggers action 執行的腳本直接插入的zabbix mysql (單獨建了一張表);而後經過crontab定時讀取(一分鐘)mysql獲取報警。
風暴控制經過判斷這一分鐘裏的報警同類的條數來判斷
效果:
1. 極大的提升了action的執行效率, 實際應用過程當中, 即便出現報警風暴, 發送依舊沒有什麼問題。 2. 由於action的執行效率的提升, 風暴控制有了必定的效果。
TODO:
1. 報警信息跟cmdb裏的信息關係, 實現無配置或者少許配置 2. 更有效的風暴控制方式