《輕松籌監控系統實現方案》要點:
本文介紹了輕松籌監控系統實現方案,希望對您有用。如果有疑問,可以聯系我們。
監控系統是服務管理最重要的組成部分之一,可以幫助開發人員更好的了解服務的運行狀況,及時發現異常情況.雖然阿里提供收費的業務監控服務,但是監控有很多開源的解決方案,可以嘗試自建監控系統,滿足基本的監控需求,以后逐步完善優化.這樣既可以更靈活的滿足自身業務的監控需求,也可以為以后自建機房提供技術積累.通過以下7個方面來建設監控系統.
完善的日志是實現監控的基礎,如何打印日志關系到之后的日志過濾、存儲以及分析.除了選擇合適的日志庫,還要滿足一些日志打印的要求:
日志切分是運維層面的東西,不應該由日志庫來承擔日志切分的事情,因為Linux在日志切分上有很成熟的工具,不需要自己寫碼去重復實現.
目前對日志切分的需求只有2個:按天切分和刪除切出來的多余日志.logrotate就能很好的滿足這些需求,logrotate是基于cron來運行的,其腳本是/etc/cron.daily/logrotate,默認放在/etc/cron.daily下,每天執行一次.
有的時候程序異常或者請求激增會導致日志量暴增,有可能在短時間內打滿整個磁盤.可以在logrotate的配置文件里加上maxsize來限制日志文件的大小,并且將logrotate的執行頻率調高至每小時甚至每分鐘,及時切分并刪除超過rotate數量的日志,來防止異常情況下磁盤被打滿的情況發生.
// logrotate config of sample
// rotate every day, and keep for 3 days
/var/log/sample.log {
daily
rotate 3
maxsize 1G
missingok
sharedscripts
postrotate
# 在切分時向程序發送SIGHUP信號
killall -SIGHUP bin_sample
endscript
}
缺點:日志收集需要依賴額外的采集服務,過濾和存儲可能還需要額外配置.
被動接收
優點:業務程序直接將日志發送至存儲,靈活性強,存儲內容可在業務代碼里控制.
缺點:日志存儲不穩定的話會影響業務程序的正常運行;反之,日志量大的話也會壓垮日志存儲.
但是在建設監控系統初期,日志存儲還不是很穩定的情況下,還是用主動采集的方式比較穩妥,不影響服務穩定性為主.
Collectd功能確實很強大,它的tail插件也能滿足從文件收集日志,但是tail插件配置比較復雜而且說明文檔相較于Filebeat來說不是很詳細.
Collectd的其他插件可以采集的數據確實很多,而且也有插件支持將數據發送到Logstash和InfluxDB,但是多數插件的功能我們用不到,而且Elastic Stack中的Beats也能夠很好的收集系統參數等數據,而且跟ELK能很好的兼容.
所以在分別試用了Filebeat和Collectd這2個采集服務后,綜合上述分析決定采用Filebeat來負責從日志文件中采集日志.如下所示,Filebeat的配置簡單易懂:
filebeat:
spool_size:?1024????????????????????????????????????#?最大可以攢夠?1024?條數據一起發送出去
idle_timeout:?“5s”??????????????????????????????????#?否則每?5?秒鐘也得發送一次
registry_file:?“registry”???????????????????????????#?文件讀取位置記錄文件,會放在當前工作目錄下.
config_dir:?“path/to/configs/contains/many/yaml”????#?如果配置過長,可以通過目錄加載方式拆分配置
prospectors:????????????????????????????????????????#?有相同配置參數的可以歸類為一個?prospector
–
fields:
log_source:?“sample”????????????????????#?類似?logstash?的?add_fields,此處的”log_source”用來標識該日志來源于哪個項目
paths:
–?/var/log/system.log???????????????????#?指明讀取文件的位置
–?/var/log/wifi.log
include_lines:?[“^ERR”,?“^WARN”]????????????#?只發送包含這些字樣的日志
exclude_lines:?[“^OK”]??????????????????????#?不發送包含這些字樣的日志
–
document_type:?“apache”?????????????????????#?定義寫入?ES?時的?_type?值
ignore_older:?“24h”?????????????????????????#?超過?24?小時沒更新內容的文件不再監聽.
scan_frequency:?“10s”???????????????????????#?每?10?秒鐘掃描一次目錄,更新通配符匹配上的文件列表
tail_files:?false???????????????????????????#?是否從文件末尾開始讀取
harvester_buffer_size:?16384????????????????#?實際讀取文件時,每次讀取?16384?字節
backoff:?“1s”???????????????????????????????#?每?1?秒檢測一次文件是否有新的一行內容需要讀取
paths:
–?“/var/log/apache/*”???????????????????#?可以使用通配符
exclude_files:?[“/var/log/apache/error.log”]
–
input_type:?“stdin”?????????????????????????#?除了?“log”,還有?“stdin”
multiline:??????????????????????????????????#?多行合并
pattern:?‘^[[:space:]]’
negate:?false
match:?after
output:
logstash:
hosts:?[“localhost:5044”]??????????????????????????#?The?Logstash?hosts
Logstash 自2009年誕生經過多年發展,已經是很成熟并且流行的日志處理框架.Logstash使用管道方式進行日志的搜集處理和輸出.有點類似*NIX系統的管道命令 input | filter | output,input 執行完了會執行 filter,然后執行 output.在 Logstash 中,包括了三個階段:輸入input → 處理filter(不是必須的)→ 輸出output.每個階段都由很多的插件配合工作,比如 file、elasticsearch、redis 等等.每個階段也可以指定多種方式,比如輸出既可以輸出到elasticsearch中,也可以指定到stdout在控制臺打印.
Codec 是 Logstash 從 1.3.0 版開始新引入的概念(Codec 來自 Coder/decoder兩個單詞的首字母縮寫).在此之前,Logstash 只支持純文本形式輸入,然后以過濾器處理它.但現在,我們可以在輸入 期處理不同類型的數據,這全是因為有 Codec 設置.所以,這里需要糾正之前的一個概念.Logstash 不只是一個 input | filter | output 的數據流,而是一個 input | decode | filter | encode | output 的數據流!Codec 就是用來 decode、encode 事件的.Codec 的引入,使得 Logstash 可以更好更方便的與其他有自定義數據格式的運維產品共存,比如 graphite、fluent、netflow、collectd,以及使用msgpack、json、edn 等通用數據格式的其他產品等.
Logstash 提供了非常多的插件(Input plugins、Output plugins、Filter plugins、Codec plugins),可以根據需求自行組合.其中 Filter 插件 Grok 是 Logstash 最重要的插件.Grok 通過正則表達式匹配日志內容,并將日志結構化,所以理論上只要正則掌握的夠嫻熟,就能解析任何形式的日志,非常適合用來解析第三方服務產生的非結構化日志.但是如果是自己寫的服務,就沒必要將日志輸出成非結構的,增加寫正則的負擔,所以在上述日志打印一節中才規定線上的日志輸出成json形式,方便 Logstash 解析,Logstash 提供 json 的 Filter 插件.
Logstash 的配置文件默認放在 /etc/logstash/conf.d 目錄下,如果需要采集多個項目的日志,每個項目的 Logstash 配置可能不一樣,那就會在 conf.d 里存放多個配置文件,以每個項目命名方便管理.但是這樣會帶來一個問題,因為 Logstash 會將所有配置文件合并為一個,即一條日志通過input進入到Logstash后,會經過每個配置文件里的filter和output插件,造成對日志錯誤的處理和輸出.解決方式是在Filebeat的fileds配置項里增加區分不同項目的field,如果日志路徑就能區分不同項目的話也可以不用額外加field,用 Filebeat 自帶的source字段就可以,然后在每個項目對應的 Logstash 配置文件里通過IF標識項目,項目各自的日志進各自的配置,互不干擾.
input {
beats {
port => “5044”
}
}
// The filter part of this file is commented out to indicate that it is
// optional.
filter {
if [beat] and [source] =~ “sample” {
json {
source => “message”
}
ruby {
code => “event.set(‘time’,(Time.parse(event.get(‘time’)).to_f*1000000).to_i)”
}
}
}
output {
if [beat] and [source] =~ “sample” {
stdout { codec => rubydebug }
}
}
根據 DB-ENGINES 的排名,InfluxDB和Elasticsearch在各自專攻的領域都是NO.1,InfluxDB統治Time Series DBMS,Elasticsearch制霸Search engine,關于它們的原理和使用,各自都有非常詳細的文檔和資料,這里就不再贅述.
在時序數據方面,InfluxDB表現強勁,Elasticsearch在主要的指標上均遠落于下風:
數據寫入:同時起4個進程寫入8百64萬條數據,Elasticsearch平均為 115,422 條/秒,InfluxDB平均 926,389 條/秒,寫入速度是Elasticsearch的8倍.這種寫入速度的差距隨著數據量的增大保持相對一致.
磁盤存儲:存儲相同的8百64萬條數據,使用默認配置的Elasticsearch需要2.1G,使用針對時序數據配置的Elasticsearch需要517MB,而InfluxDB只需要127MB,壓縮率分別是前兩者的16倍和4倍.
數據查詢:在24h的數據集(8百64萬條數據)里隨機查詢1個小時內的數據,按1分鐘的時間間隔聚合,Elasticsearch和InfluxDB分別單進程執行1000次這種查詢,算耗時的平均值.Elasticsearch耗時4.98ms(201次查詢/秒),InfluxDB耗時1.26ms(794次查詢/秒),查詢速度是Elasticsearch的4倍.隨著數據集的增大,查詢速度之間的差距逐漸拉大,最大相差10倍之多.而且隨著執行查詢的進程數增加,InfluxDB的查詢速度增幅顯著,而且在不同數據集之間的查詢速度基本一致,但是Elasticsearch增幅就不大,而且隨著數據集的增大查詢速度是遞減的.
詳細的比較說明參見:InfluxDB Markedly Outperforms Elasticsearch in Time-Series Data & Metrics Benchmark(http://t.cn/RS1S4ih).
Elasticsearch強在全文搜索,InfluxDB擅長時序數據,所以還是具體需求具體分析.如果需要保存日志并經常查詢的,Elasticsearch比較合適;如果只依賴日志做狀態展示,偶爾查詢,InfluxDB比較合適.
輕松籌的業務各有特點,單一選擇Elasticsearch或者InfluxDB都不能很好的查詢日志和指標展示,所以有必要InfluxDB和Elasticsearch共存.在 Logstash 里配置2個輸出,同一條日志輸出2份,一份保留全部字段輸出至 Elasticsearch;另一份過濾文本性的字段保留指標性的字段,然后輸出至 InfluxDB.
//?業務日志輸出時時間戳格式化到微秒:2006-01-02T15:04:05.999999Z07:00
//?Logstash的filter根據時間戳轉換
filter?{
ruby?{
code?=>?“event.set(‘time’,(Time.parse(event.get(‘time’)).to_f*1000000).to_i)”
}
}
比較Kibana和Grafana,Kibana在圖表展示上沒有Grafana美觀,而且Grafana的配置更加簡單靈活.既然在日志存儲中決定InfluxDB和Elasticsearch共存,展示上就也需要Kibana和Grafana共同協作,Kibana從Elasticsearch中檢索日志,Grafana從InfluxDB和Elasticsearch中獲取展示數據.下面2張圖片展示了Grafana在輕松籌業務監控上的應用:
即使上述6個環節都建立了,如果沒有報警一切都是沒有意義的,因為不可能每時每刻都盯著曲線看,所以需要設置異常閾值,讓監控系統定時檢查,發現異常立即發送報警通知.
報警的服務有很多,但是數據展示的Grafana自帶報警功能,功能也能滿足我們的報警需求,而且配置簡單,所以規則簡單的報警可以采用Grafana的報警服務.不過Grafana的報警只支持部分數據庫,分別是Graphite, Prometheus, InfluxDB 和 OpenTSDB,所以在Elasticsearch中的日志報警還需要Elastic Stack的X-Pack.
Condition
如上圖所示,可以設置報警檢查的頻率,報警條件是最近的5分鐘內指定指標的平均值是否大于70,如果這個條件為True則觸發報警.這種報警條件還比較單一,像錯誤數在十分鐘內超過幾次才報警,當前訂單數與昨天同一時間的訂單數比較跌了超過百分之幾就報警,控制報警通知發送的頻率,等等,Grafana就不能滿足了,針對這種報警規則我們自己實現了一個報警引擎,用來滿足這些比較復雜的報警規則.
Notification
Grafana的報警通知只有在狀態轉換時才會觸發,即報警狀態的時候會發送告警通知,如果到恢復之前的一段時間里條件一直是滿足報警條件的,Grafana不會一直發送通知,直到恢復的時候再發送一次恢復的通知.如果觸發報警,Grafana支持4中通知方式:Email、Slack、Webhook 和 PagerDuty.其中Slack是國外的一種協作工具,類似釘釘,PagerDuty是一個收費的告警平臺,所以可選的只剩下Email和Webhook了.下面簡單的介紹如何配置Email和Webhook.
Grafana的郵件配置很簡單,可以利用QQ企業郵箱的smtp服務來發送報警郵件,郵件內容是配置的報警,配置比較簡單:
[smtp]
enabled?=?true
host?=?smtp.exmail.qq.com:465
user?=?alert@qingsongchou.com
password?=?********
from_address?=?alert@qingsongchou.com
from_user?=?Grafana
Webhook 就是在觸發報警時,Grafana主動調用配置的http服務,以POST或者PUT方式傳遞json數據.這樣就可以在我們自己開發的http服務里增加額外的通知方式,例如短信、微信甚至電話.
Reception
配置了報警通知,不接收不去看也是白搭.一方面我們盡量實現多種通知途徑,比如郵件、微信和短信.另一方面需要項目負責人接到報警及時響應,查看問題.
Q&A
Q:如果類似于Nginx、MySQL這種日志,類型增加需要解析每增加一個就要去改Logstash的grok嗎?
Q:這個lostash日志格式轉換怎么學習?
Q:據說Logstash比較吃內存,fluentd作為EFK組合也經常出現,請問你們有沒有做過選型呢?
Q:日志的完整性怎么保證的?怎么知道沒丟日志,或丟失了多少日志?
Q:請問監控系統需要考慮高可用嗎?
輕松籌,一億用戶信賴的全民眾籌平臺!(https://m2.qschou.com)
文章來自微信公眾號:Docker
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/2719.html