- SpringBoot actuator学习
- 一, Actuator端點
- 1.1 Bean裝配報告
- 1.2 自動配置
- 1.3 配置屬性
- 1.4 度量值
- 1.5 Web請求
- 1.6 線程活動
- 1.7 健康情況
- 二, 定制Actuator
- 2.1 修改端點ID
- 2.2 啟動和禁用端點
- 2.3 自定義健康指示器
- 2.4 自定義度量信息
SpringBoot Actuator的關鍵特性是在應用程序中提供眾多Web端點, 通過它們了解應用程序運行時的內部狀況. 可以知道Bean在Spring應用程序上下文是如何組裝在一起, 應用程序的環境屬性學習, 運行時度量信息的快照等等.
HTTP方法 | 路徑 | 描述 |
---|---|---|
GET | /autoconfig | 提供了一份自動配置報告, 記錄哪些自動配置條件通過, 哪些沒通過 |
GET | /configprops | 描述配置屬性(包括默認值)如何注入Bean |
GET | /beans | 描述應用程序上下文里全部的Bean, 以及它們的關係 |
GET | /dump | 獲取線程活動的快照 |
GET | /env | 獲取所有環境屬性 |
GET | /env/{name} | 根據名稱獲取特定的環境屬性值 |
GET | /health | 報告應用程序的健康指標, 這些值由HealthIndicator的實現類提供 |
GET | /info | 獲取應用程序的定制信息, 這些信息由info打頭的屬性提供 |
GET | /mappings | 描述所有的URL路徑, 以及它們和控制器(包括Actuator端點)的映射關係 |
GET | /metrics | 報告各種應用程序度量信息, 比如內存用量和HTTP請求基數 |
GET | /metrics/{name} | 報告指定名稱的應用程序度量值 |
POST | /shutdown | 關閉應用程序, 要求endpoint.shutdown.enabled設置為true |
GET | /trace | 根據基本的HTTP請求跟蹤信息(時間戳, HTTP頭等) |
要啟用Actuator端點, 需要在項目中引入actuator的依賴 :
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
此時如果訪問以上端點出現瀏覽器401無權限訪問錯誤信息時, 在配置文件中添加配置參數 :
management:
security:
enabled: false
1.1 Bean裝配報告
要了解应用程序中Spring上下文的情況, 最重要的端點就是/beans. 它会返回一个JSON文档, 描述上下文里每个Bean的情況, 包括其Java類型以及注入的其他Bean. 如下所示 :
[
{
"context":"bootstrap","parent":null,
"beans":[
{"bean":"propertySourceBootstrapConfiguration","aliases":[],"scope":"singleton","type":"org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration$$EnhancerBySpringCGLIB$$c0ea36e9","resource":"null","dependencies":["configServicePropertySource"]},
{"bean":"encryptionBootstrapConfiguration","aliases":[],"scope":"singleton","type":"org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration$$EnhancerBySpringCGLIB$da679d9","resource":"null","dependencies":["encrypt-org.springframework.cloud.bootstrap.encrypt.KeyProperties"]}
......
]
}
]
Bean條目的信息 :
- bean:Spring应用程序上下文中的Bean名稱或ID。
- resource:.class文件的物理位置, 通常是一个URL,指向構建出的JAR文件, 这会隨著应用程序的構建和运行方式发生變化。
- dependencies:当前Bean注入的Bean ID列表。
- scope:Bean的作用(通常是單例, 這也是默認作用域)。
- type:Bean的Java類型。
/beans端點產生的報告告訴我們spring應用程序上下文都有哪些bean, /autoconfig端點能夠告訴我們為什麼會有這個bean.
示例 :
{
"positiveMatches": {
"AuditAutoConfiguration#auditListener":[
{
"condition":"OnBeanCondition",
"message":"@ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory'"
}
],
......
}
}
positiveMatches裡, 有一個條件, 決定SpringBoot是否自動配置auditListener, 條件是OnBeanCondition. 本例中,message屬性表明了該條件是@ConditionalOnClass檢查是否找到類ConnectionFactory和ActiveMQConnectionFactory, 沒有則條件成立, 創建一個auditListener的Bean.
1.3 配置屬性/env端點會生成應用程序可用的所有環境屬性的列表, 無論這些屬性是否用到. 其中包括了環境變量, JVM屬性, 命令行參數, 以及application.yml/properties文件提供的屬性.
示例 :
{
"profiles":["dev"],
"server.ports":{"local.server.port":"8001"},
"servletContextInitParams":{},
"systemProperties":{
@appId: "microservice-provider-user",
com.sun.management.jmxremote: ""
file.encoding: "UTF-8"
file.encoding.pkg: "sun.io"
file.separator: "\"
java.awt.graphicsenv: "sun.awt.Win32GraphicsEnvironment"
java.awt.headless: "true"
java.awt.printerjob: "sun.awt.windows.WPrinterJob"
java.class.path: "C:\Program Files (x86)\Java\jdk1.8.0_171\jre\lib\c"
},
"applicationConfig: [classpath:/application-dev.yml]":{
server.port: "8001"
spring.application.name: "microservice-provider-user"
spring.data.mongodb.database: "lmc",
......
},
......
}
屬性信息 :
- applicationConfig : 應用屬性
- systemEnvironment : 環境變量
- systemProperties : JVM系統屬性
/env端點還可以用來獲取單個屬性的值, 只需要在請求時在 /env 後加上屬性名即可, 例如 http://localhost:8001/env/server.port,
1.4 度量值 運行中的應用程序有許多計算器和度量器, /metrics端點提供了這些東西的快照.
示例 :
{
"mem":137347,
"mem.free":37071,
"processors":6,
"instance.uptime":4544370,
"uptime":4551413,
"systemload.average":-1.0,
"heap.committed":95696,
......
}
度量值信息分類 :
分類 | 前綴 | 報告內容 |
---|---|---|
垃圾收集器 | gc.* | 已經發生過的垃圾收集次數, 以及垃圾收集所耗費的時間, 適用於標記-清理垃圾收集器和並行垃圾收集器 |
內存 | mem.* | 分配給應用程序的內存數量和空閒的內存數量 |
堆 | heap.* | 當前內存用量 |
類加載器 | classes.* | JVM類加載器於卸載的類的數量 |
系統 | processors, uptime, instance.uptime, systemload.average | 系統信息, 例如處理器數量, 運行時間, 平均負載 |
線程池 | threads.* | 線程, 守護線程的數量, 以及JVM啟動後的線程數量峰值 |
數據源 | datasource.* | 數據源連接的數量(僅當spring應用程序上下文裡存在DataSource時候才有這個信息) |
Tomcat會話 | httpsessions.* | Tomcat的活躍會話數和最大會話數 |
HTTP | counter.status., gauge.response. | 多種應用程序服務HTTP請求的度量值於計數器 |
/metrics雖然提供了一些針對web請求的基本計數器和計時器, 但那些度量值缺少詳細信息. /trace斷點能報告所有web請求的詳細信息, 包括請求方法, 路徑, 時間戳以及請求和響應的頭信息.
示例 :
{
{"timestamp":1602124272478,
"info":{
"method":"GET",
"path":"/metrics",
"headers": {
"request": {...},
"response": {...}
}
}
},
}
屬性信息 :
- timestamp : 請求的處理時間
- headers : 請求和響應中所攜帶的頭信息
在確認應用程序運行情況時, 除了跟蹤請求, 了解線程活動也很重要. /dump端點會生成當前線程活動的快照.
示例 :
[
{
"threadName":"DestroyJavaVM",
"threadId":47,
"blockedTime":-1,
"blockedCount":0,
"waitedTime":-1,
"waitedCount":0,
"lockName":null,
"lockOwnerId":-1,
"lockOwnerName":null,
"inNative":false,
"suspended":false,
"threadState":"RUNNABLE",
"stackTrace":[],
"lockedMonitors":[],
"lockedSynchronizers":[],
"lockInfo":null
},
{...},...
]
1.7 健康情況
如果想知道應用程序是否在運行, 直接訪問/health端點. status屬性顯示應用程序的狀態. /health端點輸出的某些信息可能涉及內容, 因此對未經授權的請求只能提供簡單的健康狀態. 如果結果身份驗證, 則可以提供更多信息.
示例 :
{
"status":"UP",
"diskSpace":{
"status":"UP",
"total":926646530048,
"free":895984504832,
"threshold":10485760
},
"mongo":{
"status":"UP",
"version":"4.4.1"
},
"db": {
"status":"UP",
"database":"H2",
"hello":1
},
"refreshScope":{"status":"UP"},
"hystrix":{"status":"UP"},
"configServer":{"status":"UNKNOWN","error":"no property sources located"},
}
這些健康指示器都會按需來自動配置.
二, 定制Actuator 2.1 修改端點ID每個actuator端點都有一個ID用來決定端點的路徑, 可以通過修改ID來改變端點的路徑, 要做的就是設置一個熟悉, 屬性名是 endpoint.endpoint-ID.id.
endpoint:
health:
id: status
重命名端點, 修改其路徑的理由很多. 最明顯的理由就是, 增加一些安全感.
2.2 啟動和禁用端點雖然actuator的端點都很有用, 但不一定需要全部這些端點. 默認情況下, 所有端點(除了shutdown)都啟用.
endpoint:
shutdown:
enabled: true #啟動shutdown端點
metrics:
enabled: false #關閉metrics端點
如果要禁用全部端點, 只留下metrics, 可以使用 :
endpoint:
enabled: false
metrics:
enabled: true
2.3 自定義健康指示器
如果應用程序需要和一些沒有健康指示器的系統交互, 就需要自定義健康指示器了. 需要實現HealthIndicator接口, 重寫health()方法.
package com.lmc.actuactor;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* @author: lmc
* @Description: TestHealth
* @version: 1.0
* @date: 2020/10/8 11:44
*/
@Component
public class TestHealth implements HealthIndicator {
@Override
public Health health() {
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getForObject("http://www.baidu.com", String.class);
return Health.up().build();
}catch (Exception e) {
return Health.down().build();
}
}
}
除了簡單的狀態之外, 如果還想向健康記錄裡添加其他附加信息, 可以調用Health構造器的withDetail()方法, 具體如下所示 :
public Health health() {
try {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getForObject("http://www.baidu.com", String.class);
return Health.up().build();
}catch (Exception e) {
return Health.down().withDetail("reason", e.getMessage()).build();
}
}
2.4 自定義度量信息
如果我們想定義自己的度量, 用來捕獲應用程序中的特定信息. 自動配置允許Actuator創建CounterService的實例, 並將其註冊為Spring的應用程序上下文中的Bean. CounterService這個接口定義了三個方法, 分別用來增加, 減少或重置特定名稱的度量值, 接口源代碼如下 :
public interface CounterService {
/**
* Increment the specified counter by 1.
* @param metricName the name of the counter
*/
void increment(String metricName);
/**
* Decrement the specified counter by 1.
* @param metricName the name of the counter
*/
void decrement(String metricName);
/**
* Reset the specified counter.
* @param metricName the name of the counter
*/
void reset(String metricName);
}
Actuator的自動配置還會配置一個GaugeService類型的Bean, 該接口與CounterService類似, 能夠將某個值記錄到特定名稱的度量值里. 接口源代碼如下 :
public interface GaugeService {
/**
* Set the specified gauge value.
* @param metricName the name of the gauge to set
* @param value the value of the gauge
*/
void submit(String metricName, double value);
}
我們無需實現這些接口, SpringBoot已經提供了兩者的實現, 我們要做的就是把他們的實例注入所需的Bean, 在適當的時候調用其中的方法, 更新想要的度量值.
示例 : 訪問 http://localhost:8001/user/{id} 時訪問次數lmc.visit自增, 同時記錄最近一次訪問時間
繼承CounterService實現類並使其自動注入(CounterService實現類沒有被Spring自動加載, 因此我繼承其實現類再手動添加註解使其自動注入)
package com.lmc.service;
import org.springframework.boot.actuate.metrics.buffer.BufferCounterService;
import org.springframework.boot.actuate.metrics.buffer.CounterBuffers;
import org.springframework.stereotype.Service;
/**
* @author: lmc
* @Description: BufferCounterServiceImpl
* @version: 1.0
* @date: 2020/10/8 14:30
*/
@Service("bufferCounterService")
public class BufferCounterServiceImpl extends BufferCounterService {
public BufferCounterServiceImpl(CounterBuffers buffers) {
super(buffers);
}
@Override
public void increment(String metricName) {
super.increment(metricName);
}
@Override
public void decrement(String metricName) {
super.decrement(metricName);
}
@Override
public void reset(String metricName) {
super.reset(metricName);
}
}
修改Controller :
@RestController
@RequestMapping("/user")
public class RestfulController {
@Autowired
private UserService userService;
@Autowired
private UserRepository userRepository;
@Qualifier(value = "bufferCounterService")
@Autowired
private CounterService counterService;
@Qualifier("gaugeService")
@Autowired
private GaugeService gaugeService;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User getUser(@PathVariable("id")Long id) {
counterService.increment("lmc.visit");
gaugeService.submit("lmc.last.visit", System.currentTimeMillis());
return userRepository.findOne(id);
}
}
訪問 http://localhost:8001/metrics, 可以看到 counter.lmc.visit和gauge.lmc.last.visit的值
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)