
SpringBoot自带监控功能Actuator,可以帮助实现对程序内部运行情况监控,比如监控状况、Bean加载情况、环境变量、日志信息、线程信息等,但是无法监控eureka注册中心下各个微服务的健康状态,只能监控每一个微服务的启停状态,如果想要监控到这个状态,则需要手动进行埋点并把相关指标数据暴露到prometheus即可
对于整个监控流程图大致如下:
grafana和prometheus在我的其他文章中有相关说明,在此主要把注册中心这边通过actuator暴露指标数据并由prometheus采集的这个过程进行详细编码说明
首先创建一个PrometheusMetricsService类,此类主要负责对接监控数据采集服务,将指标通过此类设置到actuator/prometheus插件环境里
@Service
public class PrometheusMetricsService {
private static final String EUREKA_INSTANCE_STATUS = "eureka_instance_status";
private static final String EUREKA_INSTANCE_COUNT = "eureka_instance_count";
private static final String LABEL_CLIENT = "client";
private final Gauge instanceStatusGauge;
private final Gauge instanceCountGauge;
public PrometheusMetricsService(CollectorRegistry registry) {
instanceStatusGauge = Gauge
.build(EUREKA_INSTANCE_STATUS, "instance status")
.labelNames(LABEL_CLIENT)
.register(registry);
instanceCountGauge = Gauge
.build(EUREKA_INSTANCE_COUNT, "instance count")
.labelNames(LABEL_CLIENT)
.register(registry);
}
void metricInstanceStatus(String client, Integer statusValue) {
instanceStatusGauge.labels(client).set(statusValue);
}
void metricInstanceCount(String client, Integer count) {
instanceCountGauge.labels(client).set(count);
}
}
然后需要创建一个InstanceStateCollector类,此类定时通过eureka注册实例类PeerAwareInstanceRegistry获取注册到eureka的服务的健康状态,并通过调用上一步的PrometheusMetricsService类将各个服务的信息暴露出来
@Component
public class InstanceStateCollector {
@Autowired
PeerAwareInstanceRegistry registry;
@Autowired
PrometheusMetricsService prometheusMetricsService;
private static final Logger log = LoggerFactory.getLogger(InstanceStateCollector.class);
@Scheduled(cron = "0/5 * * * * ?")
public void collect() {
try {
Applications applications = registry.getApplications();
applications.getRegisteredApplications().forEach((registeredApplication) -> {
Integer count = registeredApplication.size();
String client = registeredApplication.getName();
prometheusMetricsService.metricInstanceCount(client, count);
registeredApplication.getInstances().forEach((instance) -> {
prometheusMetricsService.metricInstanceStatus(client, getStatus(instance.getStatus()));
});
});
} catch (Exception e) {
log.warn("eureka下的客户端的健康状态监控信息获取失败..." + e);
}
}
private Integer getStatus(InstanceInfo.InstanceStatus status){
if(status == InstanceInfo.InstanceStatus.UP){
return 1;
}else if(status == InstanceInfo.InstanceStatus.DOWN){
return 5;
}else if(status == InstanceInfo.InstanceStatus.STARTING){
return 2;
}else if(status == InstanceInfo.InstanceStatus.OUT_OF_SERVICE){
return 3;
}else{
return 4;
}
}
}
这样子prometheus监控到的各个微服务的状态status将不只是0和1的状态了,将会出现如下状态