此話題不是本文重點,如你還不知道。請谷歌一波,會有遍地的解釋。引用下圖說明下微服務可能呈現的形態: html
監控的目的是爲了讓集羣中全部的服務組件,不論是HTTP服務,數據庫服務,仍是中間件服務。都可以健康穩定得運行,能發現問題,遇到問題能找到緣由。
在過去,監控工具側重於基礎設施或單一軟件組件以及衡量運營健康。這些工具在實現這一目標方面只取得了必定的成功,可是對於單一的,傳統的應用程序和基礎設施來講效果不錯。微服務的出現暴露了工具中的弱點。
如今,組件託管在位於私有云,公共雲或二者的混合體之間的虛擬化機器或容器內。獲悉我並不須要關心服務cpu用了多少,內存用了多少?確保這些服務相互通訊以提供所需的結果須要從監控的角度重要看幾件事情:mysql
咱們想要監控分析應用,從它的服務狀態出發是否更直接呢?linux
目前有些廠商提出了微服務的監控解決方案。git
每一種商業或開源方案都有它的優點所在。能夠根據你的需求來進行選擇。例如你的全部服務都是本身研發,日誌標準一致or可以統一處理。全部訪問信息都能打出日誌,那麼我認爲日誌分析多是你最適合的方案。可是對於公有云平臺,那就不一樣了。github
好雨雲幫提供了公有云和私有化的部署方式,平臺內部署的服務各式各樣。各類通訊協議,各類日誌標準。咱們怎麼實現對全部服務的應用狀態監控?好雨雲幫完善的租戶網絡,環境隔離,所以咱們提供用戶在本身環境下安裝本身的監控組件,咱們的基礎數據收集是經過網絡分析。下文詳細講解:golang
kubernetes中pod內容器共享網絡空間,掛在卷等爲咱們監控pod內主服務容器提供方便。其實按照官方對pod的定義的使用面來講:sql
* content management systems, file and data loaders, local cache managers, etc. * log and checkpoint backup, compression, rotation, snapshotting, etc. * data change watchers, log tailers, logging and monitoring adapters, event publishers, etc. * proxies, bridges, and adapters * controllers, managers, configurators, and updaters
pod內除了主服務外咱們能夠部署一些附屬服務。以前的文章我談過使用pod的插件服務收集處理日誌。今天我再談使用pod的網絡便利監控主服務應用級指標。mongodb
咱們拿一個http服務爲例,咱們監控網絡流量能拿到幾乎全部訪問和服務返回信息。例如1分鐘內多少request
,分別請求哪些path
,多長時間服務返回了。返回狀態碼等等信息。
要得到以上的數據,咱們須要獲取到網絡包,解碼網絡包而後得到http協議數據。
咱們WatchData
服務容器與應用容器在同pod中,通過應用容器eth0
網卡的流量咱們再WatchData
容器中eth0
網卡獲取。經過解碼網絡包獲取http報文頭關鍵信息,每個Response
造成一個消息發送到server端完成分析,存儲而後造成連續的實時的監控數據。下圖展示個簡要的總體架構圖:數據庫
固然,上文已經說了,咱們採起此方案主要就是爲了可以監控各類應用,只是http
怎麼行。不通的通訊應用使用不一樣的通訊協議,好比mysql
的協議,mongodb
的協議。TCP/IP
網絡協議棧分爲應用層(Application
)、傳輸層(Transport
)、網絡層(Network
)和鏈路層(Link
)四層。。咱們抓取到的網絡包信息也是四層模型。網絡
使用golang實現網絡抓包很是容易。得益於谷歌的包:
github.com/google/gopacket github.com/google/gopacket/layers github.com/google/gopacket/pcap
這裏我舉一個監聽網卡的Demo主要代碼
//device 網卡名 if handle, err := pcap.OpenLive(device, int32(n.Option.Snaplen), true, n.Option.TimeOut); err != nil { log.With("error", err.Error()).Errorln("PCAP OpenLive Error.") return 1 } else if err := handle.SetBPFFilter(n.Option.Expr); err != nil { // optional log.With("error", err.Error()).Errorln("PCAP SetBPFFilter Error.", n.Option.Expr) return 1 } else { log.Infoln("Start listen the device ", device) packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) go func(close chan struct{}, h *pcap.Handle) { for { select { case packet := <-packetSource.Packets(): n.handlePacket(packet) // Do something with a packet here. case <-close: log.Infoln("stop listen the device.") h.Close() return } } }(n.Option.Close, handle) }
這段代碼就是監聽某個網卡,經過n.Option.Expr
規則過濾點無用網絡包,規則語法與linux tcpdump同樣。參考:PCAP-FILTER 接收到網絡包通常有多種類型:2層模型的包,和4層模型的包。若是你不關注tcp握手這種類型的包你只須要關注具備四層模型的網絡包。 n.handlePacket(packet)
處理網絡包。
app := packet.ApplicationLayer() if app != nil { //log.With("type", app.LayerType().String()).Infoln("Receive a application layer packet") //log.Infoln(packet.String()) go func() { sd := &SourceData{ Source: app.Payload(), ReceiveDate: packet.Metadata().Timestamp, } tran := packet.TransportLayer() if tran != nil { src, dst := tran.TransportFlow().Endpoints() sd.SourcePoint = &src sd.TargetPoint = &dst if tran.LayerType().Contains(layers.LayerTypeTCP) { tcp := &layers.TCP{} err := tcp.DecodeFromBytes(tran.LayerContents(), gopacket.NilDecodeFeedback) if err != nil { log.With("error", err.Error()).Errorln("Decode bytes to TCP error") } else { sd.TCP = tcp } } } netL := packet.NetworkLayer() if netL != nil { src, dst := packet.NetworkLayer().NetworkFlow().Endpoints() sd.SourceHost = &src sd.TargetHost = &dst } decode := FindDecode(n.Option.Protocol) if decode != nil { decode.Decode(sd) } else { log.Debugf("%s protol can not be supported \n", n.Option.Protocol) }
如上代碼簡單處理四層模型網絡包。通常你能夠從網絡層獲取雙方ip地址,從傳輸層獲取雙方端口以及tcp包的相關信息。從應用層獲取應用數據。 具體的怎麼優化和實踐就留給你們本身嘗試吧。
優勢:
缺點:
總之,就像上文說得同樣。若是你的需求只是想監控一個應用。你就別考慮這個方案了。若是你想監控集羣中全部應用,你能夠嘗試。
雲盟認證成員:barnett