此话题不是本文重点,如你还不知道。请谷歌一波,会有遍地的解释。引用下图说明下微服务可能呈现的形态: 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