SpringBoot Actuator学习

SpringBoot Actuator学习,第1张

SpringBoot actuator学习

文章目录
  • 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 自定義度量信息

一, Actuator端點

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類型。
1.2 自動配置

​ /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的活躍會話數和最大會話數
HTTPcounter.status., gauge.response.多種應用程序服務HTTP請求的度量值於計數器
1.5 Web請求

​ /metrics雖然提供了一些針對web請求的基本計數器和計時器, 但那些度量值缺少詳細信息. /trace斷點能報告所有web請求的詳細信息, 包括請求方法, 路徑, 時間戳以及請求和響應的頭信息.

示例 :

{
    {"timestamp":1602124272478,
        "info":{
    		"method":"GET",
    		"path":"/metrics",
    		"headers": {
    			"request": {...},
				"response": {...}
			}
		}
	},
}

屬性信息 :

  • timestamp : 請求的處理時間
  • headers : 請求和響應中所攜帶的頭信息
1.6 線程活動

​ 在確認應用程序運行情況時, 除了跟蹤請求, 了解線程活動也很重要. /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的值

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/795115.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存