Open-falcon Agent模組rpc通訊過程
1.Agent模組內容簡述
在解析Agent模組通訊過程的同時,需要對Agent模組的內容進行簡單的概述,主要包括以下幾個方面,是支援Agent通訊模組的基礎內容。
1.1 Open-falcon簡述
Open-falcon是小米公司開源的一個企業級運維監控系統,主要使用go語言編寫。總體結構分為服務端與客戶端,站在使用者的角度上看,可以有非常多個客戶端對應一個服務端。這裡的說的客戶端就是即將要介紹的Agent模組,包括Agent在監控機器的工作過程,以及Agent與服務端的通訊過程。服務端是接收Agent上傳的資料,儲存、處理而且展示給相應的運維人員。也可以通過服務端提供的Web介面管理Agent的工作、更新等等。Open-falcon的系統架構比較複雜,Agent主要與HBS心跳伺服器以及transfer資料上報模組進行通訊,還包括獲取主機的監控資訊等。下圖為小米監控官方文件的架構圖。
1.2 Agent的系統位置
Agent在運維監控系統的位置具體如下:
如上圖,整個運維監控系統相當於一個網路環境,各個主機的Agent位於網路的末端,使用rpc通訊的方式與伺服器進行資料通訊,包括:HBS心跳伺服器、transfer資料轉發。
1.3 Agent的簡單介紹
Agent是一個golang開發的daemon程式,用於自發現的採集單機的各種資料和指標,這些指標包括不限於以下幾個方面,共計200多項指標。
CPU相關
磁碟相關
IO
Load
記憶體相關
網路相關
埠存活、程序存活
ntp offset(外掛)
某個程序資源消耗(外掛)
netstat、ss等相關統計項採集
機器核心配置引數
只要安裝了falcon-agent的機器,就會自動開始採集各項指標,主動上報,不需要使用者在server做任何配置。採集以上監控資料之外,Agent需要通過與服務端的HBS進行心跳連線通訊,包括主機資訊上報、同步外掛、同步監控程序埠等等。falcon-agent,可以在github上找到 : https://github.com/open-falcon/agent。
1.4 Agent的通訊物件
Agent的通訊物件主要有以下兩個:
a、HBS心跳伺服器
Agent按照配置檔案說明(預設以一分鐘為週期)定期給HBS傳送心跳連線請求,上報主機存活資訊、同步主機監控外掛、同步主機監控程序埠等。
b、transfer資料轉發服務
Agent 按照配置檔案說明(預設以一分鐘為週期)定期給transfer傳送主機個項監控資料,包括:cpu、磁碟、記憶體等等。
1.5 Agent的配置檔案
Agent的配置檔案位於Agent目錄下,命名為cfg.josn。包括:debug、hostname、ip、plugin、heartbeat、transfer、http、collector、ignore多個選項。其中,heartbeat對應心跳伺服器配置,transfer對應資料轉發配置。如下圖,Agent配置檔案內容:
debug為開啟除錯模式、hostname填寫主機名字、ip為主機網路地址、heartbeat包括:開關,rpc地址埠,連線時間週期,超時時間、transfer類比heartbeat、collector收集網絡卡資訊、ignore為不監控的專案。
2.Agent模組通訊方式
Agent模組使用單向同步的rpc通訊方式,把資料資訊以傳送請求的方式推送到服務端,並且返回傳送錯誤以及請求響應結果。
2.1 rpc通訊方式
Agent模組推送資訊時,使用tcp協議連線rpc服務端,推送資料並且接受伺服器返回的響應資料後,關閉rpc連線,等待下一次的通訊。正常來說,只有在Agent向HBS伺服器請求外掛同步、程序埠同步時,伺服器才會返回相應資料,其他的請求只會返回請求狀態,成功或者失敗。
2.2 rpc資料結構
rpc資料結構:SingleConnRpcClient、Call、Client等,這裡只關注SingleConnRpcClient即可,其他的大部分是go語言封裝的rpc通訊相關結構體。
struct {
sync.Mutex
rpcClient *rpc.Client
RpcServer string
Timeout time.Duration
}
sync.Mutex :Go語言的排它鎖,其他開發語言會不一樣,根據情況使用。此處目的是實現rpc通訊程序與主程序同步,主程序等待rpc通訊結束後才繼續往下執行任務。
rpcClient :宣告一個rpc通訊的客戶端,用於連線服務端並且傳送訊息。
RpcServer :宣告一個rpc通訊的服務端描述,是rpcClient的通訊物件,讀取配置檔案。
Timeout :rpc連線超時,讀取配置檔案。
3.Agent模組通訊內容採集
Agent模組通訊內容的採集包括:面向HBS心跳伺服器內容採集、面向transfer資料傳送伺服器內容採集。把採集到的主機存活資訊、主機監控資料週期性上報給伺服器。
3.1 內容採集相關專案
A、HBS心跳伺服器
Agent與心跳伺服器的通訊有三個方面:主機存活資訊、同步程序埠、同步監控外掛資訊。
主機存活資訊:主機名字、主機IP地址、Agent當前版本、外掛當前版本內容等資訊。
同步程序埠:向HBS伺服器傳送當前Agent主機名字與一個校驗和,第一次傳送一個空的校驗和,HBS伺服器每次返回一個校驗和,並且儲存為當前檢驗和,下一次傳送當前檢驗和。
同步監控外掛:向HBS伺服器傳送當前Agent主機名字,等待HBS返回外掛列表,並且處理外掛列表,此處理過程在Agent模組通訊內容處理體現。
可信IP地址:此功能暫時不考慮
B、transfer資料傳送服務器
Agent傳送到transfer的主機監控資料包括如下幾個方面:
機器負載資訊, cpu.idle/load.1min//mem.memfree.percent/df.bytes等
硬體資訊,比如功耗、風扇轉速、磁碟是否可寫服務監控資料,比如某個介面每分鐘呼叫的次數,latency等等
資料庫、HBase、Redis、Openstack等開源軟體的監控指標,具體資訊如下:
CPU相關採集項,計算方法:通過採集/proc/stat來得到,大家可以參考sar命令的統計輸出來理解。
cpu.idle:Percentage of time that the CPU or CPUs were idle and the system didnot have an outstanding disk I/O request.
cpu.busy:與cpu.idle相對,他的值等於100減去cpu.idle。
cpu.guest:Percentage of time spent by the CPU or CPUs to run a virtualprocessor.
cpu.iowait:Percentage of time that the CPU or CPUs were idle during which thesystem had an outstanding disk I/O request.
cpu.irq:Percentage of time spent by the CPU or CPUs to service hardwareinterrupts.
cpu.softirq:Percentage of time spent by the CPU or CPUs to service softwareinterrupts.
cpu.nice:Percentage of CPU utilization that occurred while executing at theuser level with nice priority.
cpu.steal:Percentage of time spent in involuntary wait by the virtual CPU orCPUs while the hypervisor was servicing another virtual processor.
cpu.system:Percentage of CPU utilization that occurred while executing at thesystem level (kernel).
cpu.user:Percentage of CPU utilization that occurred while executing at theuser level (application).
cpu.cnt:cpu核數。
cpu.switches:cpu上下文切換次數,計數器型別。
磁碟相關採集項,計算方法:先讀取/proc/mounts拿到所有掛載點,然後通過syscall.Statfs_t拿到blocks和inode的使用情況。每個metric都會附加一組tag描述,類似mount=$mount,fstype=$fstype,其中$mount是掛載點,比如/home,$fstype是檔案系統,比如ext4。
df.bytes.free:磁碟可用量,int64
df.bytes.free.percent:磁碟可用量佔總量的百分比,float64,比如32.1
df.bytes.total:磁碟總大小,int64
df.bytes.used:磁碟已用大小,int64
df.bytes.used.percent:磁碟已用大小佔總量的百分比,float64
df.inodes.total:inode總數,int64
df.inodes.free:可用inode數目,int64
df.inodes.free.percent:可用inode佔比,float64
df.inodes.used:已用的inode資料,int64
df.inodes.used.percent:已用inode佔比,float64
megacli工具輸出,使用 megacli 工具讀取 RAID 相關資訊,每個metric都會附件一組tag描述,用來標明所屬PD或者 VD,PD格式為PD=Enclosure_ID:SLOT_ID,比如PD=32:0表明第一塊磁碟 ,VD=0 表明第一個邏輯磁碟。
sys.disk.lsiraid.pd.Other_Error_Count
sys.disk.lsiraid.pd.Predictive_Failure_Count
sys.disk.lsiraid.pd.Drive_Temperature
sys.disk.lsiraid.pd.Firmware_state:如果值不為0,則此物理磁碟出現問題
sys.disk.lsiraid.vd.cache_policy:如果值不為0,表示此邏輯磁碟快取策略和設定不符
sys.disk.lsiraid.vd.state: 如果值不為0,表示此邏輯磁碟出現問題
SMART工具輸出,使用smartctl 工具讀取磁碟 SMART 資訊,目前所有指標僅作為資料收集,不一定意味磁碟損壞(只是表示概率變大),每個metric都會有一組tag描述,表明碟符,例如device=/dev/sda。
sys.disk.smart.Reallocated_Sector_Ct
sys.disk.smart.Spin_Retry_Count
sys.disk.smart.Reallocated_Event_Count
sys.disk.smart.Current_Pending_Sector
sys.disk.smart.Offline_Uncorrectable
sys.disk.smart.Temperature_Celsius
分割槽讀寫監控,測試所有已掛載分割槽是否可讀寫,每個metric都會有一組tag描述,表示掛載點,比如mount=/home
sys.disk.rw:如果值不為0,表明此分割槽讀寫出現問題
IO相關採集項,計算方法:每秒採集一次/proc/diskstats,計算差值,都是計數器型別的。每個metric都會有一組tag描述,形如device=$device,用來表示具體的裝置,比如sda1、sdb。使用者可以參考iostat的幫助文件來理解具體的metric含義。
disk.io.ios_in_progress:Number of actual I/O requestscurrently in flight.
disk.io.msec_read:Total number of ms spent by all reads.
disk.io.msec_total:Amount of time during which ios_in_progress >= 1.
disk.io.msec_weighted_total:Measure of recent I/O completiontime and backlog.
disk.io.msec_write:Total number of ms spent by all writes.
disk.io.read_merged:Adjacent read requests merged in a single req.
disk.io.read_requests:Total number of reads completedsuccessfully.
disk.io.read_sectors:Total number of sectors read successfully.
disk.io.write_merged:Adjacent write requests merged in a single req.
disk.io.write_requests:total number of writes completedsuccessfully.
disk.io.write_sectors:total number of sectors writtensuccessfully.
disk.io.read_bytes:單位是byte的數字
disk.io.write_bytes:單位是byte的數字
disk.io.avgrq_sz:下面幾個值就是iostat -x 1看到的值
disk.io.avgqu-sz
disk.io.await
disk.io.svctm
disk.io.util:是個百分數,比如56.43,表示56.43%
機器負載相關採集項,計算方法:讀取/proc/loadavg,都是原始值型別的:
load.1min
load.5min
load.15min
記憶體相關採集項
計算方法:讀取/proc/meminfo 中的內容,其中的mem.memfree是free+buffers+cached,mem.memused=mem.memtotal-mem.memfree。使用者具體可以參考free命令的輸出和幫助文件來理解每個metric的含義。
mem.memtotal:記憶體總大小
mem.memused:使用了多少記憶體
mem.memused.percent:使用的記憶體佔比
mem.memfree
mem.memfree.percent
mem.swaptotal:swap總大小
mem.swapused:使用了多少swap
mem.swapused.percent:使用的swap的佔比
mem.swapfree
mem.swapfree.percent
網路相關採集項,計算方法:讀取/proc/net/dev的內容,每個metric都附加有一組tag,形如iface=$iface,標明具體那個interface,比如eth0。metric中帶有in的表示流入情況,out表示流出情況,total是總量in+out,支援的metric如下:
net.if.in.bytes
net.if.in.compressed
net.if.in.dropped
net.if.in.errors
net.if.in.fifo.errs
net.if.in.frame.errs
net.if.in.multicast
net.if.in.packets
net.if.out.bytes
net.if.out.carrier.errs
net.if.out.collisions
net.if.out.compressed
net.if.out.dropped
net.if.out.errors
net.if.out.fifo.errs
net.if.out.packets
net.if.total.bytes
net.if.total.dropped
net.if.total.errors
net.if.total.packets
埠採集項,計算方法,通過ss -ln,來判斷指定的埠是否處於listen狀態。原始值型別,值要麼是1:代表在監聽,要麼是0,代表沒有在監聽。每個metric都附件一組tag,形如port=$port,$port就是具體的埠。
net.port.listen
機器核心配置
kernel.maxfiles: 讀取的/proc/sys/fs/file-max
kernel.files.allocated:讀取的/proc/sys/fs/file-nr第一個Field
kernel.files.left:值=kernel.maxfiles-kernel.files.allocated
kernel.maxproc:讀取的/proc/sys/kernel/pid_max
ntp採集項,使用 ntpq-pn 獲取本機時間相對於 ntp 伺服器的 offset。
sys.ntp.offset: 本機偏移時間,單位為ms,值過大或者為0則表明有異常,需要報警
程序監控,proc.num:判斷某個程序的數目,這裡需要分兩個場景,一種是根據程序的名字來判定,比如name=sshd;另外一種是根據cmdline來判定,比如Java的應用程序名可能都是java,根據第一種情況沒法做區分,此時可以配置cmdline,如cmdline=./falcon_agent-c./cfg.ini程序資源監控
process.cpu.all:程序和它的子程序使用的sys+user的cpu,單位是jiffies
process.cpu.sys:程序和它的子程序使用的sys cpu,單位是jiffies
process.cpu.user:程序和它的子程序使用的user cpu,單位是jiffies
process.swap:程序和它的子程序使用的swap,單位是page
process.fd:程序使用的檔案描述符個數
process.mem:程序佔用記憶體,單位byte
ss命令輸出
ss.orphaned
ss.closed
ss.timewait
ss.slabinfo.timewait
ss.synrecv
ss.estab
本節內容來自於open-falcon對linux運維基礎採集項的說明。
3.2 內容採集資料結構
A、HBS心跳伺服器
Agent與心跳伺服器的通訊有三個方面:主機存活資訊、同步程序埠、同步監控外掛資訊。
主機存活資訊:主機名字、主機IP地址、Agent當前版本、外掛當前版本內容等資訊。
使用rpc通訊傳送以上資訊後,返回rpc通訊結果,傳送失敗寫入日誌,成功與否,進入下一次通訊週期再次傳送。傳送原始碼如下:
time.Sleep(interval)是通訊週期,interval來自於配置檔案。
同步程序埠:向HBS伺服器傳送當前Agent主機名字與一個校驗和,第一次傳送一個值為nil的校驗和,HBS伺服器每次返回一個校驗和,並且儲存為當前檢驗和,下一次傳送當前檢驗和。
傳送HBS請求後,Agent等待HBS返回同步埠的資訊,並且儲存到BuiltinMetricResponse結構體當中,用於後續的處理
BuiltinMetricResponse結構體包括多個BuiltinMetric結構體,BuiltinMetric儲存單個埠或者程序的資訊。
具體函式原始碼如下:
Agent獲取到程序埠資訊後,處理操作將在Agent模組通訊內容處理說明。
同步監控外掛:向HBS伺服器傳送當前Agent主機名字,等待HBS返回外掛列表,並且處理外掛列表,此處理過程在Agent模組通訊內容處理體現。
注意:這哪即使使用了AgentHeartbeatRequest結構體封裝RPC通訊請求,但是同步外掛的操作沒有傳送Checksum字串,區別同步程序埠,具體過程體現在原始碼當中。
AgentPluginsResponse結構用於接收儲存HBS返回的外掛列表,等待後續處理。
具體原始碼如下:
可信IP地址:此功能暫時不考慮
RPC通訊相關結構體
定義一個RPC通訊結構體,封裝rpcClient客戶端結構體
sync.Mutex :Go語言的排它鎖,其他開發語言會不一樣,根據情況使用。此處目的是實現rpc通訊程序與主程序同步,主程序等待rpc通訊結束後才繼續往下執行任務。
rpcClient :宣告一個rpc通訊的客戶端,用於連線服務端並且傳送訊息。
RpcServer :宣告一個rpc通訊的服務端描述,是rpcClient的通訊物件,讀取配置檔案。
Timeout :rpc連線超時,讀取配置檔案。
go語言中rpc.Client的原型如下:
宣告兩個RPC通訊客戶端結構體用於HBS、transfer的通訊。
B、transfer資料傳送伺服器
Agent傳送給transfer伺服器的監控資料包括多個專案,每個專案有多個指標。Agent的收集器把監控資料週期性讀取到記憶體中,拼接好之後傳送給伺服器。在收集器裡定義一個用於綜合管理主機監控資料的結構體:Mappers
Interval是從配置檔案讀過來的超時時間,Fs 是一個函式指標陣列,儲存多個函式指標。Mappers結構體內初始化了四個方面的監控資料包括:機器負載資訊、硬體資訊、伺服器監控資訊、開源軟體監控指標。即Mappers中已經規定包含四個FuncsAndInterval,每個FuncsAndInterval中有一個Fs,Fs是一個model.MetricValue結構體陣列指標,四個Fs內容如下:
a、AgentMetrics,CpuMetrics,NetMetrics,KernelMetrics,LoadAvgMetrics,MemMetrics,DiskIOMetrics,IOStatsMetrics,NetstatMetrics,ProcMetrics,UdpMetrics
b、DeviceMetrics
c、PortMetrics,SocketStatSummaryMetrics
d、DuMetrics
具體初始化程式碼如下:
上面每一個Metrics是一個函式,每個函式讀取相關標籤的監控資訊,讀取標籤資訊重新封裝model.MetricValue結構體並且返回。
如下是MetricValue結構體原型:
最後,把各個MetricValue結構體返回一個[]*model.MetricValue結構體指標陣列。示例:CpuMetrics
CpuMetrics是Fs: []func() []*model.MetricValue中的成員,同時也是一個函式,收集器迴圈遍歷得到CpuMetrics,執行上面的函式內容,獲取相關的監控資訊,傳遞給GaugeValue(),呼叫NewMetricValue()重新封裝MetricValue結構體,在CpuMetrics函式結束返回包含多個MetricValue的[]*model.結構體指標陣列。
如下為GaugeValue()函式原型:
metric對應cpu.idle、cpu.busy、cpu.user等標籤,val 是當前標籤的值,其他的暫時保持預設。至於,標籤對應的監控資訊獲取方法就不再展開解析了。
如下圖,是Agent傳送資料到transfer伺服器的資料結構一個整體概覽,Mappers裡面四個FuncsAndInterval都有各自的Fs,可以看成Mappers裡面有四個Fs,而Fs裡面封裝了跟多的Metrics,這些Metrics指向一項獲取各個監控指標的函式,該函式也是返回[]*model.MetricValue型別,儲存著各個model.MetricValue結構體內容。
如CpuMetrics包括:idle, busy, user, nice, system, iowait, irq, softirq, steal, guest,switches等model.MetricValue。
具體採集資訊過程原始碼如下:
Collect()為主函式所呼叫,Collect()為每一個FuncsAndInterval建立一個collect(int64(v.Interval), v.Fs)來處理所對應的Fs,Fs中包含多個model.MetricValue,而這些model.MetricValue又是一個函式,讀取相應專案的監控資訊,每一個專案裡面又有多個標籤,每一個標籤都是一個model.MetricValue,後來把全部的model.MetricValue都放到了一個[]func() []*model.MetricValue裡面傳送出去。
4.Agent模組通訊互動過程
該模組主要描述通訊過程的概述,包括:監控資料上報的過程、主機存活狀態的上報、主機程序埠的同步、主機外掛資訊的同步。也是劃分為兩個部分說明。
4.1 模組互動簡述
互動過程主要是Agent向伺服器傳送RPC訊息,等待伺服器返回結果,並且進行處理,而下面的通訊互動過程並不是全部都要處理返回結果。
A、HBS心跳伺服器
主機存活資訊
使用RPC通訊,週期性傳送主機存活報告,檢驗傳送訊息結果,傳送出錯完成寫日誌操作,傳送成功與否進入下一次傳送週期,等待訊息傳送。
同步程序埠
使用RPC通訊,週期性傳送Agent.BuiltinMetricsHBS心跳連線請求,包括主機名與一個校驗和。校驗和的初始值為”nil”,HBS響應心跳連線,返回程序埠資訊、校驗和、時間戳。程序埠資訊儲存起來等待處理,校驗和儲存起來用於下一次心跳連線請求。時間戳儲存起來,用於下一次時間校驗,若下一次HBS相應的時間戳比當前時間戳小,直接跳過當前週期,不做程序埠資訊處理。同時,校驗和沒有發生改變是不做任何程序埠資訊處理。因為校驗和沒有發生改變,意味著程序埠資訊也沒有發生改變。程序埠資訊處理結束後,進入下一個通訊週期。
同步監控外掛
使用RPC通訊,週期性傳送Agent.MinePluginsHBS心跳連線請求,包含當前主機名。HBS響應心跳連線,返回監控外掛資訊、時間戳。監控外掛資訊儲存起來等待後續處理,時間戳儲存起來,用於下一次時間校驗,若下一次HBS相應的時間戳比當前時間戳小,直接跳過當前週期,不做監控外掛資訊處理。監控外掛資訊處理結束後,進入下一個通訊週期。
B、transfer資料傳送伺服器
使用RPC通訊,週期性傳送Transfer.Update資訊,包含一個Mapperers中的全部專案中標籤的主機監控資訊,讀到每一個標籤重新封裝到一個專案當中。然後,傳送主機監控資訊,檢驗傳送訊息結果,傳送出錯完成寫日誌操作,傳送成功與否進入下一次傳送週期,等待訊息傳送。
4.2 互動資料結構
資料結構統一在Agent模組通訊內容採集中體現。
5.Agent模組通訊內容處理
Agent模組通訊內容的處理主要針對:伺服器返回給Agent的響應資訊,特別是同步資訊的處理。
5.1 內容處理相關專案
A、HBS心跳伺服器
主機存活資訊
沒有相關資訊的處理
同步程序埠
處理程序資訊或者處理埠資訊或者獲取某個目錄的大小(例如:log目錄是否發生改變)。
同步監控外掛
處理監控外掛的資訊,由伺服器下發的外掛資訊與本地的外掛資訊作比較,然後處理外掛資訊。
B、 transfer資料傳送伺服器
沒有相關資訊的處理
該節建議參考Agent原始碼以及Agent原始碼解釋視訊。
5.2 內容處理資料結構
資料結構統一在Agent模組通訊內容採集中體現。具體資料處理過程如下:
A、 HBS心跳伺服器
主機存活資訊
沒有內容處理,只是出錯時完成寫日誌操作。
同步程序埠
a、net.port.listen:埠資訊,根據下發的埠號,設定需要監控埠的值。從結構體BuiltinMetricResponseresp中查詢是否存在net.port.listen,找到則新增到需要監控埠之中。
b、du.bs:監控目錄大小,從結構體BuiltinMetricResponseresp中查詢是否存在du.bs,找到則新增到需要監控埠之中。
c、proc.num:程序數量(當前程序名字存在程序的個數),從結構體BuiltinMetricResponseresp中查詢是否存在proc.num,找到則新增到需要監控埠之中。
resp儲存HBS伺服器返回的程序埠資訊。
最後呼叫函式,更新程序埠資訊,程式碼如下圖:
更新埠資訊:g.SetReportPorts(ports)
更新程序資訊:g.SetReportProcs(procs)
更新監控目錄:g.SetDuPaths(paths)
其中更新程序資訊根據程序名字與程序命令進行分類,兩種tag不能同時出現。
同步監控外掛
如下是外掛資訊的結構體:這裡只關心FilePath 外掛的路徑
Agent把HBS伺服器返回的外掛儲存在結構體AgentPluginsResponse resp裡面:
Plugins存放了HBS返回的全部外掛路徑。然後列出全部外掛,獲取到真實的外掛名字,最後更新外掛。
B、transfer資料傳送伺服器
沒有內容處理,只是出錯時完成寫日誌操作。
6.Agent模組通訊過程總結
6.1 通訊過程總結
本文件基本完成了Agent模組RPC通訊的過程,包括Agent的簡單介紹、通訊方式、通訊內容採集、通訊互動過程以及通訊內容的處理。不論是否存在疑問,都需要參考官方文件以及Agent原始碼解讀,本文件只是加快了解Agent通訊過程的腳步,並不是全部。
6.2 其他補充說明
a、沒有處理IP白名單,open-falcon功能已經穩定不再需要後門除錯,而且這樣做非常不安全。
b、 具體Agent升級相關操作並沒有做說明,具體關聯應該不大。
b、Agent通訊模組之外的內部細節並沒有說分,例如:監控資訊如何獲取、如何設定監聽埠、如何設定監聽程序、如何設定、獲取、更新、啟動外掛等等。