背景
當我們用 K8s + Docker 容器化部署基於 SpringCloud 微服務時,根據實際業務需要,可能會對某些服務採取多節點實例部署,這樣可以實現服務的負載均衡及高可用架構。但我們有時為了監控服務的穩定性,除了 K8s 平臺提供的控制檯監控以外,項目組內部也會針對微服務的穩定性提出監控的需求,來開發自己內部監控的平臺,所以需要通過採集服務節點不同時刻的日誌數據來分析服務的健康狀態,從而實現對服務監控預警的目的。
Eureka 客戶端配置
<code>spring:
application:
name: dcp-hellworld-service
eureka:
client:
serviceUrl:
defaultZone: http://dcp-peer-eureka1:8000/eureka/,http://dcp-peer-eureka2:8000/eureka/,http://dcp-peer-eureka3:8000/eureka/
instance:
status-page-url-path: /info
instance-id: ${spring.cloud.client.ipAddress}:${server.port}
preferIpAddress: true
registry-fetch-interval-seconds: 30
lease-renewal-interval-in-seconds: 15
lease-expiration-duration-in-seconds: 15/<code>
eureka.client.serviceUrl.defaultZone 指定的是 Eureka 高可用集群 Server 節點:dcp-peer-eureka1,dcp-peer-eureka2、dcp-peer-eureka3,三節點之間互為主備。
我們在 K8s 平臺為微服務 dcp-hellworld-service 配置 10 個實例節點,當 dcp-hellworld-service 服務啟動後,這個 10 個節點會同時向 Eureka 註冊中心註冊,這時我們會在 Eureka 監控頁看到這10個註冊節點節點實例信息。
為了實現對 dcp-hellworld-service 服務監控,需要獲取服務的實例列表,首先,需要在監控程序的 Controller 層引入 DiscoveryClient 服務註冊發現類。
<code>@Autowired
private DiscoveryClient discoveryClient;/<code>
其次,通過 DiscoveryClient 獲取到 dcp-hellworld-service 服務的 10 個節點信息。
<code>List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceId);/<code>
最後, dcp-hellworld-service 定義一個 test 接口,通過調接口的方式檢查服務心跳是否運行正常。
<code>@GetMapping("/test")
public String invoke() {
return "invoke::" + UUID.randomUUID();
}/<code>
Actuator 監控模塊
當然有些同學可能會說,可以引用 actuator 監控模塊,其內部提供了非常豐富的監控指標,當然也是可以的。
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>/<code>
常用的監控指標如下:
1 /health/{component}/{instance} GET
報告程序的健康指標,這些數據由HealthIndicator實現類提供
2 /info GET
獲取程序指定發佈的信息,這些信息由配置文件中info打頭的屬性提供
3 /configprops GET
描述配置屬性(包含默認值)如何注入到bean
4 /beans GET
描述程序中的bean,及之間的依賴關係
5 /env GET
獲取全部環境屬性
6 /env/{name} GET
根據名稱獲取指定的環境屬性值
7 /mappings GET
描述全部的URI路徑,及和控制器的映射關係
8 /metrics/{requiredMetricName} GET
統計程序的各種度量信息,如內存用量和請求數
9 /httptrace GET
提供基本的http請求跟蹤信息,如請求頭等
10 /threaddump GET
獲取線程活動的快照
11 /conditions GET
提供自動配置報告,記錄哪些自動配置通過,哪些沒有通過
12 /loggers/{name} GET
查看日誌配置信息
13 /auditevents GET
查看系統發佈的事件信息
14 /caches/{cache} GET/DELETE
查看系統的緩存管理器,另可根據緩存管理器名稱查詢;
另DELETE操作可清除緩存
15 /scheduledtasks GET
查看系統發佈的定時任務信息
16 /features GET
查看Springcloud全家桶組件信息
17 /refresh POST
重啟應用程序,慎用
18 /shutdown POST
關閉應用程序,慎用
接口耗時分析服務健康狀態
但是,上面的監控指標針對是服務系統級層面。如果你還有別的一些業務型監控指標需要監控,可能就滿足不了,所以需要你單獨開發接口實現,例如:定期測試下某個接口的平均調用時長。
下面代碼是循獲取 dcp-hellworld-service 服務10 個節點信息,調用 api/v1/test 接口,記錄接口調用的耗時情況,同時通過消息隊列 kafka 發送消息到監控平臺進行日誌分析。
<code>@GetMapping("/service/{serviceId}/multinstances")
public R testMuitlIntancesInvoke(@PathVariable String serviceId) {
RestTemplate restTemplate = new RestTemplate();
// 獲取服務的實例列表
List<ServiceInstance> serviceInstances = discoveryClient.getInstances(serviceId);
if (CollectionUtils.isNotEmpty(serviceInstances)) {
serviceInstances.forEach(s -> {
long s = System.currentTimeMillis();
StringBuilder invokeURL = new StringBuilder();
invokeURL.append("http://").append(s.getHost()).append(":").append(s.getPort());
invokeURL.append("api/v1/test");
String invokeResult = restTemplate.getForObject(invokeURL.toString(), String.class);
long e = System.currentTimeMillis();
// 發送 kafka 消息
kafkaClient.send(topicName, s , (e-s)/1000);
});
}
return R.ok().data(serviceInstances.size());
}/<code>
總結
上面例子是一個簡單的通過接口調用統計接口耗時情況來分析服務的健康狀態,起一個拋磚引玉的作用吧。
實際上實現服務的監控指標有很多,如數據庫的讀寫、服務器資源、消息隊列的積壓監控,Nginx等等,需要使用不同的組件來實現,如調用 K8s 原生 API 獲取容器的資源使用情況,在這裡就不做深入探討了。
參考
<code>https://www.jianshu.com/p/d59f06724f1b/<code>
後臺私信回覆 1024 免費領取 SpringCloud、SpringBoot,微信小程序、Java面試等全套視頻資料。
閱讀更多 猿芯 的文章