Open-Falcon簡介
介紹
- 監控系統是整個運維環節,乃至整個產品生命周期中最重要的一環,事前及時預警發現故障,事后提供翔實的數據用於追查定位問題。
- 監控系統作為一個成熟的運維產品,業界有很多開源的實現可供選擇。當公司剛剛起步,業務規模較小,運維團隊也剛剛建立的初期,選擇一款開源的監控系統,是一個省時省力,效率最高的方案。
- 之后,隨着業務規模的持續快速增長,監控的對象也越來越多,越來越復雜,監控系統的使用對象也從最初少數的幾個SRE,擴大為更多的DEVS,SRE。
這時候,監控系統的容量和用戶的“使用效率”成了最為突出的問題。 - 監控系統業界有很多傑出的開源監控系統。我們在早期,一直在用zabbix,不過隨着業務的快速發展,以及互聯網公司特有的一些需求,現有的開源的監控系統在性能、擴展性、和用戶的使用效率方面,已經無法支撐了。
- 因此,我們在過去的一年里,從互聯網公司的一些需求出發,從各位SRE、SA、DEVS的使用經驗和反饋出發,結合業界的一些大的互聯網公司做監控,用監控的一些思考出發,設計開發了小米的監控系統:open-falcon。
Open-Falcon特點
- 強大靈活的數據采集: 自動發現,支持falcon-agent、snmp、支持用戶主動push、用戶自定義插件支持,opentsdb data model like (timestamp、endpoint、metric、key-value tags)
- 水平擴展能力: 支持每個周期上億次的數據采集、告警判定、歷史數據存儲和查詢.
- 高效率的告警策略管理: 高效的portal、支持策略模板、模板集成和覆蓋、多種告警方式、支持callback調用.
- 人性化的告警設置: 最大告警次數、告警級別、告警恢復通知、告警暫停、不同時段不同閾值、支持維護周期.
- 高效的graph組件: 單機支撐200萬metric的上報、歸檔、存儲(周期為1分鍾)
- 高效的歷史數據query組件: 采用rrdtool的數據歸檔策略,秒級返回上百個metric一年的歷史數據.
- dashboard: 多維度的數據展示、用戶自定義Screen。
- 高可用: 整個系統無核心單點,易運維,易部署,可水平擴展.
- 開發語言: 整個系統的后端全部采用golang編寫,portal和dashboard使用Python編寫.
缺點:
- 每個Graph(數據存儲)實例均是單點. (這點很大程度上解決了,Transfer中可以配置Graph雙寫,手工維護雙寫列表麻煩,但這個列表基本不怎么變)
- Graph擴容有損,
- 報警沒有入庫,當前未恢復的報警是存在Alarm內存中的,重啟就丟了,歷史報警也沒入庫,無法追溯.
- 報警現場沒有保存: 因為使用rrd存儲歷史數據,一天后數據就被做了歸檔處理,查看歷史報警時刻趨勢圖,無法查看當前准確值.
- 前端展示功能很雞肋,哪怕有grafana,沒有現成的grafana頁面,需要自己編輯.
架構
相關服務組件詳解
繪圖組件
1.Falcon-Agent http:1998
數據采集組件: 部署到目標機器采集機器監控項:
agent內置了一個http接口,會自動采集預先定義的各種采集項,每隔60秒,push到transfer。
2.Transfer http:6060 rpc:8433 socket:4444
agent與transfer建立長連接,將數據匯報給tarnsfer
transfer默認監聽在:8433端口上,agent會通過jsonrpc的方式來push數據上來
transfer將數據發送給judge和graph
3.Graph http:6070 rpc:6071
graph組件是存儲繪圖數據、歷史數據的組件。transfer會把接收到的數據,轉發給graph。
監聽端口為6071,校驗方法如下,返回ok表示服務正常。
curl -s "http://127.0.0.1:6071/health"
4.Query http:9966
繪圖數據的查詢接口,因為graph是分片存儲的,如果要傳輸給dashboard,就需要query組件收集用戶的數據進行聚合再返回給用戶。
5.Dashboard http:8081
Dashboard是面向用戶的查詢界面,在這里,用戶可以看到push到graph中的所有數據,並查看其趨勢圖。
6.Task http:8002
負責一些定時任務,索引全量更新,垃圾索引清理,自身組件監控等
報警組件
1.Sender
調用各個公司提供的mail-privider和sms-privider,按照某個並發度,從redis讀取郵件,短信並發送,
alarm生成的報警短信和報警郵件是直接寫入redis即可,由sender來發送。
2.UIC http:80
用戶組管理,單點登錄
3.Portal http:5050
配置報警策略,管理機器分組的web端
4.HBS http:6031 rpc:6030
Heartbeat Server心跳服務,只依賴Protal的DB
5.Judge http:6081 rpm:6080
告警判斷模塊
6.Links http:6090
報警合並依賴的web端,存放報警詳情
7.Alarm http:9912
報警時間處理器: 處理報警事件,judge的報警事件寫入到redis,alarm從redis讀取數據
8.Mail-privider&&sms-provider http:4000
發送郵件http api
9.Nodata http:6090
檢測監控數據的上報異常
Aggregator http:6055
集群聚合模塊: 聚合某集群下所有機器某個指標的值,提供一種集群視覺的監控體驗
Falcon-Agent監控項
每台服務器,都有安裝falcon-agent,falcon-agent是一個golang開發的daemon程序,用於自發現的采集單機的各種數據和指標,這些指標包括不限於以下幾個方面,共計200多項指標:
* CPU相關
* 磁盤相關
* IO
* Load
* 內存相關
* 網絡相關
* 端口存活、進程存活
* ntp offset(插件)
* 某個進程資源消耗(插件)
* netstat.ss等相關統計項采集
* 機器內核配置參數
只要安裝了falcon-agent的機器,就會自動開始采集各項指標,主動上報,不需要用戶在server做任何配置(這和zabbix有很大的不同),這樣做的好處,就是用戶維護方便,覆蓋率高.
當然這樣做也會給server造成較大的壓力,不過open-falcon的服務端單機性能足夠高,同時可以水平擴展,所以自動采集足夠多的數據,反而是一件好的事情,對於SRE和DEV來講,事后追查問題,不再是難題.
另外,falcon-agent提供了一個proxy-gateway,用戶可以方便的通過http接口,push數據到本機的gateway,gateway會幫忙高效率的轉發給server端.
數據模型
Data Mode是否強大,是否靈活,對於監控系統用戶的“使用效率”至關重要,比如以zabbix為例,上報的數據為hostname(或者ip)、metric,那么用戶添加告警策略,管理告警策略的時候,就只能以這兩個維度進行。舉一個常見的場景:
hostA的磁盤空間,小於5%,就告警,一般的服務器上,都會有兩個主要的分區,根分區和home分區,在zabbix里面,就得加兩條規則: 如果是hadoop的機器,一般都還會有十幾塊的數據盤,還得多加10多條規則,這樣就很痛苦,不幸福,不利於自動化(當然zabbix可以通過配置一些自動發現策略來搞定這個,不過比較麻煩)
數據收集
transfer: 接收客戶端發送的數據,做一些數據規整,檢查之后,轉發到多個后端系統去處理,在轉發到每個后端業務系統的時候,transfer會根據一致性hash算法,進行數據分片,來達到后端業務系統的水平擴展.
transfer提供jsonRpc接口和telnet接口兩種方式,judge,graph,opentsdb,judge是我們開發的高性能告警判定組件,graph使我們開發的高性能數據存儲、歸檔查詢組件,opentsdb是開源的時間序列數據存儲服務,可以通過transfer的配置文件來開啟.
transfer的數據來源,一般有三種
- falcon-agent采集的基礎監控數據
- falcon-agent執行用戶自定義的插件返回的數據
- client library: 線上的業務系統,都嵌入使用了統一的perfcounter.jar,對於業務系統中每個RPC接口的qps、latency都會主動采集並上報.
說明: 上面這三種數據,都會先發送給本機的proxy-gateway,再由gateway轉發給transfer.
基礎監控是指只要是個機器(或容器)就能監控,比如cpu,mem,net,io,disk等,這些監控項采集的方式固定,不需要配置,也不需要用戶提供額外的參數指定,只要agent跑起來就可以直接采集數據上報上去,非基礎監控則相反.比如端口監控,你不給我端口就不行,不然我上報所有65535個端口的監聽服務你也用不了,這類監控需要用戶配置后才會開始采集上報的監控(包括類似於端口監控的配置觸發類監控,以及類似於mysql的插件腳本類監控),一般就不算基礎監控的范疇了.
報警
報警判定,是由judge組件來完成。用戶在web portal來配置相關的報警策略,存儲在Mysql中,hearbeat server會定期加載Mysql中的內容,judge也會定期和hearbeat server保持溝通,來獲取相關的報警策略.
heartbeat server不僅僅單純的加載Mysql中的內容,根據模板繼承、模板項覆蓋、報警動作覆蓋、模板和hostGroup綁定,計算出最終關聯到endpoint的告警策略,提供給judge組件來使用.
transfer轉發給judge的每條數據,都會觸發相關策略的判定,來決定是否滿足報警條件,如果滿足條件,則會發送給alarm,alarm再以郵件、短信、米聊等形式通知相關用戶,也可以執行用戶預先配置好的callback地址.
用戶可以很靈活的來配置告警判定策略,比如連續n次滿足條件,連續n次的最大值滿足條件、不同時間段不同的閾值,如果出於維護周期內則忽略等等.
另外也支持突升突降類的判定和告警.
API
到這里,數據已經成功的存儲在了graph里,如何快速的讀出來,讀過去1小時的,過去一個月的,過去一年的都需要1秒之內返回.
這些都是靠graph和API組件來實現的,transfer會將數據往graph組件轉發一份,graph收到數據以后,會以rdtool的數據歸檔方式來存儲,同時提供查詢的RPC接口.
API面向終端用戶,收到查詢請求后,會去多個graph里面,查詢不同metric的數據,匯總后統一返回給用戶.
存儲
對於監控系統來講,歷史數據的存儲和高效率查詢,永遠是一個很難的問題!
數據量大,目前我們的監控系統,每個周期,大概有2000萬次數據上報(上報周期為1分鍾和5分鍾兩種,各占50%),一天24小時內,從來不會有業務低峰,不管是白天還是夜晚,每個周期,總會有那么多數據要更新.
寫操作多,一般的業務系統,通常是讀多寫少,可以方便的使用各種緩存技術,再者各類數據庫,對於查詢操作的處理效率遠遠高於寫操作,而監控系統恰恰相反,寫操作遠遠高於讀,每個周期幾千萬次的更新操作,對於常用數據庫(Mysql,Postgresql,MongoDB)都是無法完成的.
高效率的查,我們說的監控系統操作少,是相對於寫入來講,監控系統本身對於讀的要求很高,用戶經常會有查詢上百個meitric,在過去一天、一周、一月、一年的數據,如何在一秒內返回給用戶並繪圖,這是個不小的挑戰.
open-falcon在這塊,投入了較大的精力,我們把數據按照用途分成兩類,一類是用來繪圖的,一類是用戶做數據挖掘的.
對於繪圖的數據來講,查詢要快是關鍵,同時不能丟失信息量,對於用戶要查詢100個metric,在過去一年里的數據里,數據量本身就在那里了,很那1秒之類返回,另外就算返回了,前端也無法渲染這么多的數據,還得采樣,造成很多無畏的消耗和浪費。我們參考rrdtool的理念。數據每次存入的時候,會自動進行采樣,存檔.
我們歸檔策略如下: 歷史數據保存5年 。同時為了不丟失信息量,數據歸檔的時候,會按照平均值采樣、最大值采樣、最小值采樣.
滴滴雲基於OpenFalcon的二次開發
Open-Falcon 二進制部署
# Open-Falcon,為前后端分離的架構,包含 backend 和 frontend 兩部分.
# 部署有三種方式:
# 1. 源碼安裝(當中有一步需要編譯)
# 2. 二進制包安裝:(官方已經編譯好的,其余跟源碼安裝一樣)
# 3. docker 安裝
List:
Package:
mysql5.7
redis3.2
go1.13.4.linux-amd64.tar.gz
open-falcon-v0.2.1.tar.gz
python-virtualenv
python-devel
openldap-devel
mysql-devel
節點名 | IP | 軟件版本 | 硬件 | 網絡 | 說明 |
---|---|---|---|---|---|
falcon-binary | 172.19.0.6 | list 里面都有 | 2C4G | Nat,內網 | 測試環境 |
注意事項
跟傳統服務修改配置文件數據庫密碼不一樣,因為 open-falcon 是前后端分離,需要給前端也授權數據庫權限,否則部分前端功能報錯 500
准備系統環境
# 1.初始化
init_security() {
systemctl stop firewalld
systemctl disable firewalld &>/dev/null
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/' /etc/selinux/config
sed -i '/^GSSAPIAu/ s/yes/no/' /etc/ssh/sshd_config
sed -i '/^#UseDNS/ {s/^#//;s/yes/no/}' /etc/ssh/sshd_config
systemctl enable sshd crond &> /dev/null
rpm -e postfix --nodeps
echo -e "\033[32m [安全配置] ==> OK \033[0m"
}
init_security
init_yumsource() {
if [ ! -d /etc/yum.repos.d/backup ];then
mkdir /etc/yum.repos.d/backup
fi
mv /etc/yum.repos.d/* /etc/yum.repos.d/backup 2>/dev/null
if ! ping -c2 www.baidu.com &>/dev/null
then
echo "您無法上外網,不能配置yum源"
exit
fi
curl -o /etc/yum.repos.d/163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo &>/dev/null
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo &>/dev/null
yum clean all
timedatectl set-timezone Asia/Shanghai
echo "nameserver 114.114.114.114" > /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
chattr +i /etc/resolv.conf
yum -y install ntpdate
ntpdate -b ntp1.aliyun.com
echo -e "\033[32m [YUM Source] ==> OK \033[0m"
}
init_yumsource
安裝 Open-Falcon 的 Database 組件服務
init_redis() {
yum -y install redis git
sed -i 's/bind 127.0.0.1/bind 172.19.0.6/' /etc/redis.conf # 此處IP為你自己的主機IP
systemctl start redis && systemctl enable redis
if [ $? -eq 0 ] ;then
echo -e "\033[32m [ Redis server ] ==> OK \033[0m";
fi
}
init_redis
init_mysql() {
rpm -e mariadb-libs --nodeps
rm -rf /var/lib/mysql
rm -rf /etc/my.cnf
tar xvf /root/mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar -C /usr/local/
cd /usr/local
rpm -ivh mysql-community-server-5.7.23-1.el7.x86_64.rpm \
mysql-community-client-5.7.23-1.el7.x86_64.rpm mysql-community-common-5.7.23-1.el7.x86_64.rpm \
mysql-community-libs-5.7.23-1.el7.x86_64.rpm mysql-community-devel-5.7.23-1.el7.x86_64.rpm
rm -rf mysql-community-*
}
changepass() {
sed -i '/\[mysqld]/ a skip-grant-tables' /etc/my.cnf
systemctl restart mysqld
mysql <<EOF
update mysql.user set authentication_string='' where user='root' and Host='localhost';
flush privileges;
EOF
sed -i '/skip-grant/d' /etc/my.cnf
systemctl restart mysqld
yum -y install expect
systemctl start ntpd && systemctl enable ntpd
expect <<-EOF
spawn mysqladmin -uroot -p password "ZHOUjian.20"
expect {
"password" { send "\r" }
}
expect eof
EOF
systemctl restart mysqld
}
main() {
init_redis
init_mysql
changepass
}
main
准備 Open-Falcon 數據目錄,並下載 Open-Falcon 的 Git 倉庫
init_falcon_data_directory() {
mkdir -pv /home/open-falcon && cd /home/open-falcon
git clone https://github.com/open-falcon/falcon-plus.git
cd /home/open-falcon/falcon-plus/scripts/mysql/db_schema/ #初始化mysql的表結構,必須取保mysql服務是正常啟動的。
mysql -uroot -pZHOUjian.20 < 1_uic-db-schema.sql
mysql -uroot -pZHOUjian.20 < 2_portal-db-schema.sql
mysql -uroot -pZHOUjian.20 < 3_dashboard-db-schema.sql
mysql -uroot -pZHOUjian.20 < 4_graph-db-schema.sql
mysql -uroot -pZHOUjian.20 < 5_alarms-db-schema.sql
}
init_falcon_data_directory
安裝后端並啟動
export FALCON_HOME=/home/work
export WORKSPACE=$FALCON_HOME/open-falcon
mkdir -p $WORKSPACE
tar xvf open-falcon-v0.2.1.tar.gz -C $WORKSPACE
cd $WORKSPACE`
grep -Ilr 3306 ./ | xargs -n1 -- sed -i 's/root:/root:ZHOUjian.20/g'
cd $WORKSPACE
# 啟動
./open-falcon start
# 檢查所有模塊的啟動狀況
./open-falcon check
部署前端
# 創建工作目錄
export HOME=/home/work
export WORKSPACE=$HOME/open-falcon
mkdir -p $WORKSPACE
cd $WORKSPACE
# 克隆前端代碼
cd $WORKSPACE
git clone https://github.com/open-falcon/dashboard.git
# 安裝依賴包
yum install -y python-virtualenv python-devel openldap-devel
yum groupinstall "Development tools"
cd $WORKSPACE/dashboard/
virtualenv ./env
./env/bin/pip install -r pip_requirements.txt -i https://pypi.douban.com/simple
# 修改配置
dashboard的配置文件為: 'rrd/config.py',請根據實際情況修改
# API_ADDR 表示后端api組件的地址
API_ADDR = "http://127.0.0.1:8080/api/v1"
# 根據實際情況,修改PORTAL_DB_*, 默認用戶名為root,默認密碼為""
# 根據實際情況,修改ALARM_DB_*, 默認用戶名為root,默認密碼為""
# 以開發者模式啟動
./env/bin/python wsgi.py
# 使用瀏覽器訪問IP:8081即可
# 以生產模式啟動
bash control start
# 停止dashboard運行
bash control stop
# 查看日志
bash control tail
# 可以修改一下wsgi.py配置文件,指定IP和端口,默認是0.0.0.0
Dashbord 用戶管理
dashbord 沒有默認創建任何賬號包括管理賬號,需要你通過頁面進行注冊賬號。
想擁有管理全局的超級管理員賬號,需要手動注冊用戶名為 root 的賬號(第一個帳號名稱為 root 的用戶會被自動設置為超級管理員)。
超級管理員可以給普通用戶分配權限管理。
小提示:注冊賬號能夠被任何打開 dashboard 頁面的人注冊,所以當給相關的人注冊完賬號后,需要去關閉注冊賬號功能。只需要去修改 API 組件的配置文件 cfg.json,將 signup_disable 配置項修改為 true,重啟 API 即可。當需要給人開賬號的時候,再將配置選項改回去,用完再關掉即可。
Open-Falcon 容器部署
# 注意事項:
# 1:初始化環境跟上面一樣,此處就不重復了,請執行上面兩個初始化環境函數,再執行下面命令;
# 2:如果docker啟動容器不小心弄錯了,記得刪除容器再run;
准備 docker 依賴包和 docker 的 yum 源並安裝
# 安裝需要的軟件包,yum-util 提供yum-config-manager功能,另外兩個是devicemapper驅動依賴的
yum install -y yum-utils device-mapper-persistent-data lvm2
# 准備yum源
# docker 官方源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里雲源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 由於repo中默認只開啟stable倉庫,所以這里安裝的是最新穩定版
yum install docker-ce
# Docker鏡像加速
# 沒有啟動/etc/docker 目錄不存在,需要自己建立,啟動會自己創建;
mkdir /etc/docker
# 為了期望我們鏡像下載快一點,應該定義一個鏡像加速器,加速器在國內
vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
# 啟動docker
systemctl start docker && systemctl enable docker && systemctl daemon-reload
注意
啟動docker前清理一下環境,防止目錄沖突
# 防止環境有之前裝過的mysql,做一下清理
# yum方式安裝的mysql
yum -y remove mysql mysql-server mysql-libs compat-mysql51
rm -rf /var/lib/mysql
rm -rf /etc/my.cnf # 有可能my.cnf改名為my.cnf.rpmsave
# 查看是否還有mysql軟件
rpm -qa|grep mysql
rpm方式安裝的mysql
# 查看系統中是否以rpm包安裝的mysql:
rpm -qa | grep -i mysql
MySQL-server-5.6.17-1.el6.i686
MySQL-client-5.6.17-1.el6.i686
# 卸載mysql:
rpm -e MySQL-server-5.6.17-1.el6.i686
rpm -e MySQL-client-5.6.17-1.el6.i686
# 刪除mysql服務
chkconfig --list | grep -i mysql
chkconfig --del mysql
# 刪除分散mysql文件夾
whereis mysql 或者 find / -name mysql
mysql: /usr/lib/mysql /usr/share/mysql
mysql的所有目錄以及文件:
rm -rf /usr/lib/mysql
rm -rf /usr/share/mysql
安裝mysql容器
docker run -itd \
--name falcon-mysql \
-v /home/work/mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=test123456 \
-p 3306:3306 \
mysql:5.7
# 安裝的版本為mysql:5.7 默認用戶名root 密碼 test123456
初始化mysql表結構
# cd /tmp && \
git clone --depth=1 https://github.com/open-falcon/falcon-plus && \
cd /tmp/falcon-plus/ && \
for x in `ls ./scripts/mysql/db_schema/*.sql`; do
echo init mysql table $x ...;
docker exec -i falcon-mysql mysql -uroot -ptest123456 < $x;
done
# rm -rf /tmp/falcon-plus/
安裝后端
docker pull openfalcon/falcon-plus:v0.3
docker run -itd --name falcon-plus \
--link=falcon-mysql:db.falcon \
--link=falcon-redis:redis.falcon \
-p 8433:8433 \
-p 8080:8080 \
-e MYSQL_PORT=root:test123456@tcp\(db.falcon:3306\) \
-e REDIS_PORT=redis.falcon:6379 \
-v /home/work/open-falcon/data:/open-falcon/data \
-v /home/work/open-falcon/logs:/open-falcon/logs \
openfalcon/falcon-plus:v0.3
啟動open-falcon后端模塊
docker exec falcon-plus sh ctrl.sh start \ graph hbs judge transfer nodata aggregator agent gateway api alarm
# 或者您可以按照以下方式啟動/停止/重啟特定模塊:
docker exec falcon-plus sh ctrl.sh start/stop/restart xxx
# 檢查后端模塊的狀態
docker exec falcon-plus ./open-falcon check
# 或者您可以在主機中的/ home / work / open-falcon / logs /中查看日志
ls -l /home/work/open-falcon/logs/
安裝前端
# 在容器中啟動Open-Falcon儀表盤
docker run -itd --name falcon-dashboard \
-p 8081:8081 \
--link=falcon-mysql:db.falcon \
--link=falcon-plus:api.falcon \
-e API_ADDR=http://api.falcon:8080/api/v1 \
-e PORTAL_DB_HOST=db.falcon \
-e PORTAL_DB_PORT=3306 \
-e PORTAL_DB_USER=root \
-e PORTAL_DB_PASS=test123456 \
-e PORTAL_DB_NAME=falcon_portal \
-e ALARM_DB_HOST=db.falcon \
-e ALARM_DB_PORT=3306 \
-e ALARM_DB_USER=root \
-e ALARM_DB_PASS=test123456 \
-e ALARM_DB_NAME=alarms \
-w /open-falcon/dashboard openfalcon/falcon-dashboard:v0.2.1 \
'./control startfg'