transfer模塊的做用是接收全部被監控服務器上發送過來的數據進行一些判斷和處理以後轉發至後面的graph和judge模塊。node
transfer主要從四個來源接收數據:golang
transfer設計時支持三種數據後端,分別是:judge、graph、OpenTSDB.傳輸給judge是爲了對收集上來的數據進行實時告警判斷,graph是使用RRD技術存儲監控數據的組件,OpenTSDB是開源的時間序列數據存儲服務。後端
transfer的後端judge和graph爲了提供高可用及負載均衡,均可能部署了多節點,transfer使用一致性hash對數據映射到不一樣節點。而OpenTSDB沒有使用一致性hash,只提供了一個接口寫數據。api
transfer經過接收的數據的endpoint+metric+排序後的tags組成的pk做爲key,進行hash(進行crc32循環冗餘校驗),最後獲取該數據應該發送到的node。下面是pk生成的源碼:服務器
func PK(endpoint, metric string, tags map[string]string) string { if tags == nil || len(tags) == 0 { return fmt.Sprintf("%s/%s", endpoint, metric) } return fmt.Sprintf("%s/%s/%s", endpoint, metric, SortedTags(tags)) }
transfer源碼分析須要結合數據流動的方向來進行梳理。負載均衡
初始化時首先初始化鏈接池,而後初始化發送隊列,最後初始化一致性hash環。
初始化完成以後開始執行發送數據任務startSendTasks
將會按期將隊列中的數據發送到不一樣的後端,至於最後的startSenderCron
是開啓定時任務,記錄不一樣隊列發送數據的狀況。socket
safe list
。graph
是兩層循環,拼接成node+addr
建立一個safe list
。tsdb若是開啓,建立了一個safe list
。initNodeRings
建立一致性hash環時,只獲取了judge
和graph
的node名稱,經過名稱生成hash值,再生成hash環。startSendTasks
發送數據時,對於judge
,循環每一個judge node
隊列中的數據,將其發送到對應的node
中,對於graph node
隊列,將循環該node
列表中的全部地址,每一個地址將接收到一份數據,這樣,同一份數據被拷貝了len(node.addr)
份發送。// 初始化數據發送服務, 在main函數中調用 func Start() { // 初始化默認參數 MinStep = g.Config().MinStep if MinStep < 1 { MinStep = 30 //默認30s } // initConnPools() initSendQueues() initNodeRings() // SendTasks依賴基礎組件的初始化,要最後啓動 startSendTasks() startSenderCron() log.Println("send.Start, ok") }
transfer接收數據有三種方式,除了Http提供數據接收以外,另兩種,一種是使用golang的rpc模塊,另外一種是使用socket直接傳輸數據,兩種方式將在下面介紹:函數
rpc方法 | 接收數據 | 做用 |
---|---|---|
Ping | 空 | 檢測transfer是否存活,code=0說明正常,code=1說明請求異常 |
Update | MetricValue 列表 |
將上報的數據進行簡單處理,檢測是否知足格式條件,最後將數據發送到隊列中 |
\n
進行分割。socket指令 | 接收數據 | 做用 |
---|---|---|
quit | 空 | 退出該次處理 |
update | 上報數據,用\n 分隔 |
上報數據進行處理後發送到對應的發送隊列中 |
在open-falcon中基本都是使用rpc和http進行傳輸數據,這裏添加了socket支持,多是爲了用戶使用其餘語言寫的客戶端,發送一些自定義的監控數據的上報,基本不使用。源碼分析
http服務含有一個上報數據的接口,是"/api/push"
,該接口能夠接受其餘服務push
上來的數據,其餘主要是一些關於transfer統計信息,狀態信息等的獲取。ui
golang
能用的rpc
和Http
之外,另外提供的socket
感受不友好,但願可以改進以支持其餘語言編寫的服務可以比較方便的上報數據。