服务监控是保证生产环境稳定最基础也是最重要的措施,微服务下尤是。如果没有成熟的一套监控方案那微服务化注定会失败!
服务监控的核心是监控什么?基础系统监控包含节点的硬盘/网络IO、CPU/内存/硬盘占用等,针对JVM的微服务我们还要特别关注以下指标:
- 类的loaded与unloaded
- 内存的used/committed/max
- 垃圾回收Minor/Full GC的频率、次数、暂停时间
- 线程的峰值数量、当前数量,守护线程的数量
这些信息在我们在告警、故障转移、故障定位及复盘时非常有用。
除了这些我们还要关注应用级的监控,我们的服务是否存活及健康、服务的质量如何。要明确的是不是进程存在服务就肯定存活,比如比较常见的接收线程占满的情况,无法对外提供服务,但进程还在,所有传统的通用进程判断的方式是不可取的。
服务存活判断最简单的方式是让服务提供ping接口,由监控服务定期ping这个接口,如有响应则表示存活。当然这有其局限,比如我们服务依赖了多个中间件,ping接口只是简单的请求-响应,无法感知中间件故障,所以一般的微服务框架都会提供health接口,此接口会报告当前服务的详细情况:
{
"status" : "DOWN",
"db" : {
"status" : "UP",
"database" : "MYSQL"
},
"redis" : {
"status" : "DOWN",
"version" : "2.8.19"
},
"diskSpace" : {
"status" : "UP",
"free" : 309047318528,
"threshold" : 20485760
},
"some-custom-service" : {
"status" : "UP"
}
}
这是返回示例,我们可以看到各中间件的情况,也可以将自定义服务加入到健康检查中,只要有一个服务DOWN了,服务整体的状态就标识为DOWN状态。这是一种非有效的服务存活及健康情况方式。
再深入些我们还会关心服务质量(Quality of Service),常见于特定接口的TPS、最大/90%/平均响应时间等性能指标,这些也需要服务提供特定接口暴露给监控服务。服务质量是判断是否需要动态伸缩的关键,后文会进一步说明。
对于核心的接口我们也需要针对性做监控,比如用户信息获取接口,这是大部分服务的公共依赖,非常重要,因此可以为这个接口做单独的请求-响应监控以便运维、开发可以在第一时间发现问题。
指标的采集是服务监控的第一步,主流微服务框架都提供了上述能力支撑,如需要自行集成推荐micrometer 这一工具,它也被Spring Boot 2.x做为默认的指标收集工具。
服务监控当然离不开运维工具,Zabbix、Nagios、Ganglia等都相当成熟,Prometheus 算是后期之秀,在云支持、微服务管理上有比较明显的优势。它是CNCF(Cloud Native Computing Foundation)成员,在对Kubernetes 集群环境下的监控有着先天优势。
特定框架也会有其自己生态下的监控工具,比如Spring Cloud的Spring Boot Admin,Dubbo的Dubbo Admin,但这些多是补充者的角色,无法替代主流运维工具。
如上图,是Spring Boot Admin的示例,它可以监控各服务的存活及健康情况,各个服务的详细信息,诸如JVM、访问日志、统计指标、环境配置、线程、实时接口调用、熔断等,另外还可以动态调整日志级别以快速排查问题。
下一节:容器化部署是微服务非常理想的选择,它可以实现上文提到的快速发布及本节要谈的自动化节点伸缩与故障转移。