docs/Spring全家桶/SpringBoot/SpringBoot生产环境工具Actuator.md
| վ(springdoc.cn)еԴ spring.io ԭʼȨ spring.io springboot.io - Spring Boot з룬ɹѧϰоδɣýκתءû֮صΪ ̱Spring Pivotal Software, Inc. Լҵ̱ꡣ |
|---|
Spring BootһЩĹܣڽӦóʱغӦó ѡͨʹHTTP˵ʹJMXͼӦó ơָռҲԶӦӦó
spring-boot-actuator ģṩSpring Bootܡ ЩܵƼӶ spring-boot-starter-actuator Starter
ActuatorĶ
actuatorִ һָƶijĻеװáactuator ԴһСı仯в˶
ҪڻMavenĿactuator Starter
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
spring-boot-starter-actuator
</dependency>
</dependencies>
Gradleʹ
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}
Actuator ˵㣨endpointԼزӦó Spring BootһЩõĶ˵㣬ԼĶ˵㡣 磬health ˵ṩӦóϢ
ûÿĶ˵㣬ͨHTTPJMXǣʹǿԶ̷ʣһ˵㱻úͱ¶ʱΪǿõġõĶ˵ֻǿʱŻᱻԶáӦóѡͨHTTP¶ж˵ID /actuator ǰӳ䵽һURL磬Ĭ£health ˵㱻ӳ䵽 /actuator/health
| Ҫ˽actuatorĶ˵ԼǵӦʽ뿴APIĵ HTML PDF |
|---|
Ǽصնˡ
<colgroup><col><col></colgroup> | ID | ˵ | | --- | --- | | `auditevents` | ǰӦó¼Ϣ Ҫһ `AuditEventRepository` bean | | `beans` | ʾӦóSpring Beanб | | `caches` | ʾõĻ档 | | `conditions` | ʾúԶԼǷϻϵԭ | | `configprops` | ʾ `@ConfigurationProperties` б | | `env` | ¶Spring `ConfigurableEnvironment` еԡ | | `flyway` | ʾκѾӦõFlywayݿǨơ Ҫһ `Flyway` bean | | `health` | ʾӦóĽϢ | | `httpexchanges` | ʾ HTTP exchange ϢĬ£ 100 HTTP request/response exchange Ҫһ `HttpExchangeRepository` bean | | `info` | ʾӦóϢ | | `integrationgraph` | ʾSpringͼ Ҫ `spring-integration-core` | | `loggers` | ʾӦóloggerá | | `liquibase` | ʾκѾӦõLiquibaseݿǨơ Ҫһ `Liquibase` Bean | | `metrics` | ʾǰӦó metrics Ϣ | | `mappings` | ʾ `@RequestMapping` ·б | | `quartz` | ʾйQuartz Scheduler JobϢ | | `scheduledtasks` | ʾӦóеļƻ | | `sessions` | Spring Sessionֵ֧ĻỰ洢мɾûỰ ҪһʹSpring SessionĻServletWebӦó | | `shutdown` | ӦóŵعرաֻʹjarʱЧĬǽõġ | | `startup` | ʾ `ApplicationStartup` ռ[](https://springdoc.cn/spring-boot/features.html#features.spring-application.startup-tracking)Ҫ `SpringApplication` Ϊ `BufferingApplicationStartup` | | `threaddump` | Performs a thread dump. |ӦóһWebӦóSpring MVCSpring WebFluxJerseyʹ¶Ķ˵㡣
<colgroup><col><col></colgroup> | ID | ˵ | | --- | --- | | `heapdump` | һdumpļ HotSpot JVMϣһ `HPROF` ʽļ OpenJ9 JVMϣһ `PHD` ʽļ | | `logfile` | ־ļݣ `logging.file.name` `logging.file.path` ѱã ֧ʹHTTP `Range` ͷ־ļIJݡ | | `prometheus` | Կɱ Prometheus ץȡĸʽչʾmetric `micrometer-registry-prometheus` |Ĭ£ shutdown ж˵㶼á Ҫһ˵ãʹ management.endpoint.<id>.enabled ԡ shutdown ˵㡣
Properties
Yaml
management.endpoint.shutdown.enabled=true
ϣ˵ǡѡáǡѡá뽫 management.endpoints.enabled-by-default Ϊ falseʹõ˵ enabled ѡá info ˵㣬˵㡣
Properties
Yaml
management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
õĶ˵Ӧóȫɾֻı䱩¶˵ļʹ include exclude 档 |
|---|
Ĭ£ֻhealth˵ͨHTTPJMX¶ġ ڶ˵ܰϢӦϸǺʱ¶ǡ
ҪıЩ˵㱻¶ʹض include exclude ԡ
include г˱¶Ķ˵ID exclude г˲ӦñĶ˵ID exclude include ԡ һ˵IDб include exclude ԡ
磬ҪͨJMXֻ health info ˵㣬ʹԡ
Properties
Yaml
management.endpoints.jmx.exposure.include=health,info
* ѡж˵㡣 磬ҪͨHTTPеĶ env beans ˵㣬ʹԡ
Properties
Yaml
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
* YAMLо⺬壬ųеĶ˵㣬һҪš |
|---|
| Ӧóǹ¶ģǿҽҲĶ˵ |
|---|
ڶ˵㱩¶ʱʵʩԼIJԣעһ EndpointFilter bean |
|---|
Ϊ˰ȫĬֻ /health ˵ͨHTTP ʹ management.endpoints.web.exposure.include ñ¶Ķ˵㡣
management.endpoints.web.exposure.include ֮ǰȷ¶ִϢڷǽ֮Spring Security֮Ķ֤ȫ |
|---|
Spring Securityclasspathϣû SecurityFilterChain beanô /health ִ֮actuatorSpring BootԶ֤ȫ 㶨һԶ SecurityFilterChain beanSpring BootԶþͻȫִķʹ
ΪHTTP˵Զ尲ȫ磬ֻijֽɫûʣSpring BootṩһЩ RequestMatcher Spring Securityʹá
һ͵Spring Securityÿܿӡ
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
http.httpBasic(withDefaults());
return http.build();
}
}
ǰʹ EndpointRequest.toAnyEndpoint() ƥһκζ˵㣬ȻȷеĶ˵㶼 ENDPOINT_ADMIN Ľɫ EndpointRequest ϻƥ APIĵ HTML PDF
ڷǽ沿Ӧóϣִ˵㶼ܱʣҪ֤ ͨı management.endpoints.web.exposure.include һ㣬ʾ
Properties
Yaml
management.endpoints.web.exposure.include=*
⣬Spring SecurityҪԶ尲ȫãδ֤ķʶ˵㣬ʾ
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
return http.build();
}
}
ǰУֻactuator˵㡣 Spring Bootİȫκ SecurityFilterChain bean¶ȫ˳Ҫһ SecurityFilterChain beanӦó֡ |
|---|
Spring BootSpring SecurityĬֵCSRFĬ± ζʹĬϰȫʱҪ POSTshutdownloggers˵㣩PUT DELETE actuator˵403ֹĴ
| ǽֻ㴴ķͻʹʱȫCSRF |
|---|
Springȫοָ ҵCSRFϢ
˵Զ治ҪκβĶȡӦ Ҫö˵㻺Ӧʱ䣬ʹ cache.time-to-live ԡ ӽ beans ˵ĻʱΪ10롣
Properties
Yaml
management.endpoint.beans.cache.time-to-live=10s
management.endpoint.<name> ǰΨһرʶõĶ˵㡣 |
|---|
һ discovery page ӵж˵С Ĭ£discovery page /actuator ǿõġ
Ҫ discovery pageӦóԡ
Properties
Yaml
management.endpoints.web.discovery.enabled=false
һԶĹ·ʱdiscovery page Զ /actuator Ƶĵĸ 磬· /managementdiscovery pageԴ /management á ·Ϊ / ʱҳãԷֹmappingͻĿԡ
ԴԴCORS W3Cһ淶ķʽָֿȨʹSpring MVCSpring WebFluxActuatorWeb˵֧
CORS֧Ĭǽõģֻ management.endpoints.web.cors.allowed-origins ԺŻá example.com е GET POST
Properties
Yaml
management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
μ CorsEndpointProperties Իѡб |
|---|
һ @Endpoint ע @Beanκδ @ReadOperation``@WriteOperation @DeleteOperation ע͵ķԶͨJMXWebӦóҲͨHTTP ͨʹJerseySpring MVCSpring WebFlux˵ͨHTTP¶ JerseySpring MVCãʹSpring MVC
ӱ¶һһԶ
Java
Kotlin
@ReadOperation
public CustomData getData() {
return new CustomData("test", 5);
}
Ҳͨʹ @JmxEndpoint @WebEndpoint дضĶ˵㡣 Щ˵㱻ǸԵļϡ 磬@WebEndpoint ֻͨHTTP¶ͨJMX
ͨʹ @EndpointWebExtension @EndpointJmxExtension дضļչ ЩעṩضIJǿеĶ˵㡣
ҪWebܵضܣʵservletSpring @Controller @RestController ˵㣬DzͨJMXʹòͬWebʱá
˵ϵIJͨ롣 ͨwebʱЩֵURLIJѯJSON塣 ͨJMXʱӳ䵽MBeanIJС Ĭ£DZġ ǿͨʹ @javax.annotation.Nullable @org.springframework.lang.Nullable עΪѡ
ԽJSONеÿӳ䵽˵һ һJSON塣
{
"name": "test",
"counter": 42
}
һдòҪ String name int counter ʾ
Java
Kotlin
@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
Ϊ˵Ǽ֪ģڷǩָֻ͡ رǣ֧ CustomData һ name counter Եĵһ |
|---|
Ϊӳ䵽IJʵֶ˵JavaӦ -parameters 룬ʵֶ˵KotlinӦ -java-parameters 롣 ʹSpring BootGradleʹMaven spring-boot-starter-parent⽫Զ |
|---|
бҪݸ˵IJԶתΪ͡ ڵò֮ǰͨJMXHTTPյ뱻תΪͣʹ ApplicationConversionService ʵԼκ Converter GenericConverter Bean @EndpointConverter
@Endpoint``@WebEndpoint @EndpointWebExtension ԶʹJerseySpring MVCSpring WebFluxͨHTTP JerseySpring MVCãʹSpring MVC
һνʻΪweb¶Ķ˵ϵÿoperationԶɡ
pathνɶ˵ID籩¶Ķ˵Ļ· ĬϵĻ· /actuator 磬һIDΪ sessions Ķ˵νʹ /actuator/sessions Ϊ·
ͨ @Selector עһһ· IJΪһ·ӵ·νС ڵö˵ʱñֵᱻ 벶ʣ·Ԫأһ @Selector(Match=ALL_REMAINING)ʹΪһ String[] תݵ͡
HTTP methodνɲ;ģ±ʾ
<colgroup><col><col></colgroup> | Operation | HTTP method | | --- | --- | | `@ReadOperation` | `GET` | | `@WriteOperation` | `POST` | | `@DeleteOperation` | `DELETE` |ʹrequest body @WriteOperationHTTP POSTνʵ consumes Ӿ application/vnd.spring-boot.actuator.v2+json, application/json consumes Ӿǿյġ
νʵ produces Ӿ @DeleteOperation``@ReadOperation @WriteOperation ע͵ produces Ծ ǿѡġ ʹproduces ӾԶȷ
void Void produces ӾΪա org.springframework.core.io.Resource``produces Ӿ application/octet-stream produces Ӿ application/vnd.spring-boot.actuator.v2+json, application/json
˵ĬӦ״̬ȡڲͣдɾͲصݣеĻ
@ReadOperation һֵӦ״̬200(Ok) ûзһֵӦ״̬404(Not Found)
@WriteOperation @DeleteOperation һֵӦ״̬200OK ûзһֵӦ״̬204No Content
һڵʱûIJ߲ܱתΪͣͲᱻãӦ״̬400Bad Request
ʹHTTP rangeһHTTPԴһ֡ ʹSpring MVCSpring Web Fluxʱ org.springframework.core.io.Resource IJԶַ֧Χ
| ʹJerseyʱ֧ Range |
|---|
web˵webض˵չϵIJԽյǰ java.security.Principal org.springframework.boot.actuate.endpoint.SecurityContext Ϊ ǰͨ @Nullable һʹãΪ֤δ֤ûṩͬΪ ͨͨʹ isUserInRole(String) ִȨ顣
һServletΪһ˵㱩¶ʵһ @ServletEndpoint ע࣬ͬʱʵ Supplier<EndpointServlet> Servlet˵ṩservletĸεϣȴ˿ֲԡ ǵĿеServletΪһ˵ µĶ˵㣬Ӧѡ @Endpoint @WebEndpoint ע⡣
ʹ @ControllerEndpoint @RestControllerEndpoint ʵһSpring MVCSpring WebFluxĶ˵㡣 ͨʹSpring MVCSpring WebFluxıעӳ䣬 @RequestMapping @GetMapping˵ID·ǰ ˵ṩSpringWebܸļɣȴ˿ֲԡ Ӧѡ @Endpoint @WebEndpoint ע⡣
ʹýϢеӦó״̬ ϵͳʱѱˡ health ˵㱩¶Ϣȡ management.endpoint.health.show-details management.endpoint.health.show-components ԣǿΪֵ֮һ
Ĭֵ never ûڶ˵һɫʱDZΪDZȨġ ˵ûýɫĬֵ֤ûΪȨġ ͨʹ management.endpoint.health.roles ýɫ
ѾӦóϣʹ alwaysİȫãsecurity configuration֤ͷ֤ûhealth˵㡣 |
|---|
ϢǴ HealthContributorRegistry ռģĬ£ HealthContributor ʵ ApplicationContext У Spring BootһЩԶõ HealthContributorҲԱдԼġ
һ HealthContributor һ HealthIndicator һ CompositeHealthContributor һ HealthIndicator ṩʵʵĽϢ Status һ CompositeHealthContributor ṩ HealthContributors ϡ ۺcontributorγһ״ṹʾϵͳĽ״
Ĭ£յϵͳ״һ StatusAggregator óģһ״̬бÿ HealthIndicator ״̬ беĵһ״̬彡״̬ û HealthIndicator ص״̬ StatusAggregator ֪ģͻʹ UNKNOWN ״̬
ʹ HealthContributorRegistry ʱעȡעὡָꡣ |
|---|
ʵʱSpring BootԶ±г HealthIndicators Ҳͨ management.health.key.enabled ûͣѡָꡣ ±г key
ͨ management.health.defaults.enabled ǡ |
|---|
HealthIndicators ǿõģĬ²á
ΪṩԶĽϢעʵ HealthIndicator ӿڵSpring Bean Ҫṩһ health() ʵ֣һ Health Ӧ Health ӦӦðһstatusѡҪʾϸڡ Ĵʾһ HealthIndicator ʵ
Java
Kotlin
@Component
public class MyHealthIndicator implements HealthIndicator {
@Override
public Health health() {
int errorCode = check();
if (errorCode != 0) {
return Health.down().withDetail("Error Code", errorCode).build();
}
return Health.up().build();
}
private int check() {
// perform some specific health check
return ...
}
}
һ HealthIndicator ıʶIDû HealthIndicator Bean֣ڵĻ ǰУϢһΪ my Ŀҵ |
|---|
ָͨͨHTTPõģҪκӳʱ֮ǰӦ κνָӦʱ䳬10룬Spring Boot¼һϢ ֵʹ management.endpoint.health.logging.slow-indicator-threshold ԡ |
|---|
Spring BootԤ Status ⣬Health Էشϵͳ״̬Զ Status £㻹Ҫṩ StatusAggregator ӿڵԶʵ֣ͨʹ management.endpoint.health.status.order Ĭʵ֡
磬һ HealthIndicator ʵʹһΪ FATAL Status Ϊ˳Ӧóԡ
Properties
Yaml
management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up
ӦеHTTP״̬뷴ӳ彡״̬ Ĭ£OUT_OF_SERVICE DOWN ӳ䵽503 κδӳĽ״̬ UPӳΪ200 ͨHTTPʽ˵㣬ܻעԶ״̬ӳ䡣 Զӳ DOWN OUT_OF_SERVICE Ĭӳ䡣 뱣Ĭӳ䣬ȷǣԼκԶӳ䡣 磬Խ FATAL ӳΪ503ã DOWN OUT_OF_SERVICE Ĭӳ䡣
Properties
Yaml
management.endpoint.health.status.http-mapping.down=503
management.endpoint.health.status.http-mapping.fatal=503
management.endpoint.health.status.http-mapping.out-of-service=503
ҪĿƣԶԼ HttpCodeStatusMapper bean |
|---|
±ʾ״̬Ĭ״̬ӳ䡣
<colgroup><col><col></colgroup> | Status | Mapping | | --- | --- | | `DOWN` | `SERVICE_UNAVAILABLE` (`503`) | | `OUT_OF_SERVICE` | `SERVICE_UNAVAILABLE` (`503`) | | `UP` | Ĭûӳ䣬HTTP״̬Ϊ `200` | | `UNKNOWN` | Ĭûӳ䣬HTTP״̬Ϊ `200` |ӦʽӦóЩʹSpring WebFluxӦóReactiveHealthContributor ṩһԼȡӦóĽ״ 봫ͳ HealthContributor ƣϢ ReactiveHealthContributorRegistry ռĬ£ HealthContributor ReactiveHealthContributor ʵ ApplicationContext
ӦʽAPIмij HealthContributors ڵԵִС
һӦʽӦóУӦʹ ReactiveHealthContributorRegistry ʱעȡעὡָꡣ Ҫעһͨ HealthContributorӦ ReactiveHealthContributor#adapt װ |
|---|
Ϊ˴ӦʽAPIṩԶĽϢעʵ ReactiveHealthIndicator ӿڵSpring Bean Ĵʾһ ReactiveHealthIndicator ʾʵ֡
Java
Kotlin
@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {
@Override
public Mono<Health> health() {
return doHealthCheck().onErrorResume((exception) ->
Mono.just(new Health.Builder().down(exception).build()));
}
private Mono<Health> doHealthCheck() {
// perform some specific health check
return ...
}
}
ΪԶԿǴ AbstractReactiveHealthIndicator չ |
|---|
ʵʱSpring BootԶµ ReactiveHealthIndicators
бҪӦʽָȡָꡣ ⣬κûбȷ HealthIndicator ᱻԶװ |
|---|
ʱָ֯ɿڲͬĿĵǺõġ
Ҫһָ飬ʹ management.endpoint.health.group.<name> ԣָһָIDб include exclude 磬Ҫһֻݿָ飬Զ¡
Properties
Yaml
management.endpoint.health.group.custom.include=db
Ȼͨ [localhost:8080/actuator/health/custom](http://localhost:8080/actuator/health/custom)
ͬҪһ飬ݿָųڸ֮⣬ָ꣬Զ¡
Properties
Yaml
management.endpoint.health.group.custom.exclude=db
Ĭ£̳ϵͳͬ StatusAggregator HttpCodeStatusMapper á ȻҲÿĻ϶Щ ҪҲԸ show-details roles ԡ
Properties
Yaml
management.endpoint.health.group.custom.show-details=when-authorized
management.endpoint.health.group.custom.roles=admin
management.endpoint.health.group.custom.status.order=fatal,up
management.endpoint.health.group.custom.status.http-mapping.fatal=500
management.endpoint.health.group.custom.status.http-mapping.out-of-service=500
ҪעԶ StatusAggregator HttpCodeStatusMapper Bean飬ʹ @Qualifier("groupname") |
|---|
һҲ/ųһ CompositeHealthContributor Ҳֻ/ųһ CompositeHealthContributor ij ʹȫɣʾ
management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"
Уcustom 齫Ϊ primary HealthContributorǸ test һɲ֡ primary һ壬Ϊ b HealthContributor ų custom ֮⡣
˿ڻ˿ڵĶ·ṩ KubernetesƻкãЩУڰȫǣΪִ˵ʹһĹ˿Ǻܳġ һĶ˿ڿܵ²ɿĽ飬ΪʹɹӦóҲ һ·ãʾ
management.endpoint.health.group.live.additional-path="server:/healthz"
⽫ʹ live ˿ /healthz Ͽá ǰǿԵģ server:˿ڣ management:˿ڣã ·һһ·Ρ
DataSource ָʾԴ·ԴBeanĽ״ ·ԴĽ״ÿĿԴĽ״ ڽ˵ӦУ·ԴÿĿ궼ͨʹ·ɼġ 㲻ϣָа·Դ뽫 management.health.db.ignore-routing-data-sources Ϊ true
KubernetesϵӦóͨ ̽ ṩйڲ״̬Ϣ KuberneteskubeletЩ̽벢ԽӦ
Ĭ£Spring BootӦÿ״̬ KubernetesУactuator ApplicationAvailability ӿռ Liveness Readiness ϢרָʹЩϢLivenessStateHealthIndicator ReadinessStateHealthIndicator Щָʾȫֽ˵㣨"/actuator/health" ҲͨʹΪHTTP̽룺"/actuator/health/liveness" "/actuator/health/readiness"
Ȼ¶˵ϢKubernetesʩ
livenessProbe:
httpGet:
path: "/actuator/health/liveness"
port:
failureThreshold: ...
periodSeconds: ...
readinessProbe:
httpGet:
path: "/actuator/health/readiness"
port:
failureThreshold: ...
periodSeconds: ...
`` ӦñΪִ˵õĶ˿ڡ WebĶ˿ڣҲһĹ˿ڣ "management.server.port" Ѿá |
|---|
ֻеӦóKubernetesʱЩŻԶá ͨʹ management.endpoint.health.probes.enabled κλǡ
һӦóʱ䳬õЧڣKubernetes ᵽ "startupProbe" ΪһܵĽһ˵ﲻһҪ "startupProbe"Ϊ "readinessProbe" ֮ǰʧЧζӦó֮ǰյȻӦóҪܳʱԿʹ "startupProbe" ȷKubernetesӦóɱ̽ӦóеΪIJ֡ |
|---|
Actuator˵㱻һĹУôЩ˵Ͳʹͬʩ˿ڡӳء £ʹ磬ܽµӣ̽Ҳܳɹ ԭ˿ liveness readiness Ǹ⡣ ͨʵ֡
management.endpoint.health.probes.add-additional-paths=true
⽫ʹ liveness /livez ãreadiness readyz ˿ڿá
ִ liveness readiness ̽Ϊ顣ζеĹǶǿõġ磬öĽָꡣ
Properties
Yaml
management.endpoint.health.group.readiness.include=readinessState,customCheck
Ĭ£Spring BootЩָꡣ
liveness ̽벻ӦⲿϵͳĽ顣ӦóЧ״̬ƻKubernetes᳢ͨӦóʵ⡣ζţһⲿϵͳݿ⡢Web APIⲿ棩ֹϣKubernetesܻӦóʵϡ
readiness ̽⣬ⲿϵͳѡӦóԱԭSpring Boot״̬̽вκζĽ顣Ӧóʵreadiness stateunreadyKubernetesͲὫ·ɵʵһЩⲿϵͳܲӦʵ£ǿԱ״̬̽СⲿϵͳܲӦóĹؼӦóж·ͻˣ£ǾԲӦñڡҵǣһӦʵⲿϵͳܳжϡ̽УⲿʱӦóᱻֹ߲ͣջи߲εĹϣҲͨڵʹö·
һӦóʵûãtype=ClusterIP NodePort KubernetesκδӡûHTTPӦ503ȣΪûӡtype=LoadBalancer ķܽҲܲӣȡṩߡһȷ ingress ķҲһȡʵֵķʽӦ?ڷδε connection refusedڸؾڵ£HTTP 503Ǻпܵġ |
|---|
⣬һӦóʹ Kubernetes autoscalingܻӦóӸƽȡͬķӦȡautoscalerá
Kubernetes Probesֵ֧һҪӦóڵһԡ AvailabilityStateӦóڴڲ״̬ʵʵ̽루¶״̬֮ ʵʵ̽루¶˸״̬֮кܴ ӦóڵIJͬΣ̽ʹá
Spring Bootرڼ䷢application event̽ԼЩ¼¶ AvailabilityState Ϣ
±ʾ˲ͬε AvailabilityState HTTP connector״̬
һSpring BootӦóʱ
<colgroup><col><col><col><col><col></colgroup> | | LivenessState | ReadinessState | HTTP server | ע | | --- | --- | --- | --- | --- | | Starting | `BROKEN` | `REFUSING_TRAFFIC` | δ | Kubernetes "liveness" ̽룬ʱӦó | | Started | `CORRECT` | `REFUSING_TRAFFIC` | ܾ | Ӧóıˢ¡Ӧóִûյ | | Ready | `CORRECT` | `ACCEPTING_TRAFFIC` | | ѾɡӦóڽ |һSpring BootӦóرʱ
<colgroup><col><col><col><col><col></colgroup> | ͣ | Liveness State | Readiness State | HTTP server | ע | | --- | --- | --- | --- | --- | | Running | `CORRECT` | `ACCEPTING_TRAFFIC` | | Ҫرա | | Graceful shutdown | `CORRECT` | `REFUSING_TRAFFIC` | µܾ | ã [ŹػᴦС](https://springdoc.cn/spring-boot/web.html#web.graceful-shutdown) | | Shutdown complete | N/A | N/A | ر | ӦóıرգӦóرա || KubernetesĸϢμKubernetes֡ |
|---|
ӦóϢ˴ ApplicationContext ж InfoContributor BeanռĸϢ Spring BootһЩԶõ InfoContributor BeanҲԱдԼġ
ʵʱSpringԶ InfoContributor Bean
˹ߣcontributorǷ management.info.<id>.enabled Կơ ͬcontributorвͬĬֵȡǵȾ¶Ϣʡ
ûȾӦñãenv``java os contributor Ĭǽõġ ͨ management.info.<id>.enabled Ϊ true ǡ
build git ϢcontributorĬõġ ͨ management.info.<id>.enabled Ϊ false á ⣬ҪÿһĬõcontributor뽫 management.info.defaults.enabled Ϊ false
env contributor ʱͨ info.* Spring info ˵¶ݡ info keyµ Environment ԶԶ¶ 磬 application.properties ļá
Properties
Yaml
info.app.encoding=UTF-8
info.app.java.source=17
info.app.java.target=17
ӲЩֵ㻹 ڹʱչϢʹMavenԽǰӸд¡PropertiesYaml[email protected]@[email protected]@[email protected]@ |
|---|
info ˵һõĹܹ git ԴĿʱ״̬Ϣ һ GitProperties beanʹ info ˵Щԡ
classpathĸ git.properties ļGitProperties BeanͻᱻԶáϸڼ "gitϢ" |
|---|
Ĭ£˵ᱩ¶ git.branch``git.commit.id git.commit.time ԣڣ 㲻ЩԳڶ˵ӦУҪ git.properties ļųǡ ʾgitϢ git.properties ȫݣʹ management.info.git.mode ԣʾ
Properties
Yaml
management.info.git.mode=full
Ҫ info ˵ȫgitύϢ management.info.git.enabled Ϊ falseʾ
Properties
Yaml
management.info.git.enabled=false
BuildProperties Beanǿõģinfo ˵ҲԷĹϢclasspathе META-INF/build-info.properties ļãͻᷢ
| MavenGradleɸļ "ɹϢ" |
|---|
info ˵㷢˹JavaлϢϸڼ JavaInfo
info ˵㷢IJϵͳϢϸڼ OsInfo`
ΪṩԶӦóϢעʵ InfoContributor ӿڵSpring Bean
ӹһֻһֵ example Ŀ
Java
Kotlin
@Component
public class MyInfoContributor implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("example", Collections.singletonMap("key", "value"));
}
}
info ˵㣬Ӧÿһ¶ĿӦ
{
"example": {
"key" : "value"
}
}
ڿһWebӦóSpring Boot ActuatorԶõĶ˵㣬ʹͨHTTP ĬϵĹʹö˵ id /actuator ǰΪURL· 磬health /actuator/health ʽ
| Actuator ֧ Spring MVCSpring WebFluxJersey JerseySpring MVCãʹSpring MVC |
|---|
| Ϊ˻APIĵ HTML PDF мصȷJSONӦJacksonһҪ |
|---|
ʱΪ˵㶨ǰǺõġ 磬ӦóѾ /actuator Ŀġ ʹ management.endpoints.web.base-path ı˵ǰʾ
Properties
Yaml
management.endpoints.web.base-path=/manage
ǰ application.properties ӽ˵ /actuator/{id} Ϊ /manage/{id} 磬/manage/info
ǹ˿ڱΪʹòͬHTTP˿¶˵㣬 management.endpoints.web.base-path server.servlet.context-path Servlet WebӦã spring.webflux.base-path reactive WebӦã management.server.port management.endpoints.web.base-path management.server.base-path ġ |
|---|
Ѷ˵ӳ䵽ͬ·ʹ management.endpoints.web.path-mapping ԡ
ӽ /actuator/health ӳΪ /healthcheck
Properties
Yaml
management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck
ڻƵIJ˵ͨʹĬϵHTTP˿¶˵һǵѡ ȻӦóԼУܸϲʹòͬHTTP˿¶˵㡣
management.server.port ıHTTP˿ڣʾ
Properties
Yaml
management.server.port=8081
| Cloud Foundry ϣĬ£Ӧóڶ˿ 8080 Ͻ HTTP TCP ·ɵ Cloud Foundry ʹԶ˿ڣҪȷӦó·ԽתԶ˿ڡ |
|---|
ΪʹԶ˿ʱҲͨʹø management.server.ssl.* ùSSL 磬ùͨHTTPṩӦóʹHTTPSʾ
Properties
Yaml
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:store.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=false
ߣʹSSLʹòͬԿ洢ʾ
Properties
Yaml
server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:main.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:management.jks
management.server.ssl.key-password=secret
ͨ management.server.address ƹ˵Ŀõַ ֻڲάϼֻ localhost ӣá
| ֻе˿˿ڲͬʱڲͬĵַϽм |
|---|
application.properties Զ̹ӡ
Properties
Yaml
management.server.port=8081
management.server.address=127.0.0.1
㲻ͨHTTP¶˵㣬ѹ˿Ϊ -1ʾ
Properties
Yaml
management.server.port=-1
Ҳͨʹ management.endpoints.web.exposure.exclude ʵ֣ʾ
Properties
Yaml
management.endpoints.web.exposure.exclude=*
JavaչJMXṩһĻغӦó Ĭ£ùδá ͨ spring.jmx.enabled Ϊ true Spring Bootʵ MBeanServer ΪIDΪ mbeanServer Bean κδSpring JMXעBean@ManagedResource``@ManagedAttribute @ManagedOperationᱩ¶
ƽ̨ṩһ MBeanServer Spring BootʹڱҪʱĬΪVM MBeanServer Щʧˣͻᴴһµ MBeanServer
ϸڼ JmxAutoConfiguration ࡣ
Ĭ£Spring BootҲ˵ΪJMX MBeans org.springframework.boot ¹ ҪȫJMXеĶ˵עᣬԿעԼ EndpointObjectNameFactory ʵ֡
MBeanͨɶ˵ id ɡ 磬 health ˵㱻¶Ϊ org.springframework.boot:type=Endpoint,name=Health
ӦóһϵSpring ApplicationContextַܻᷢͻ Ϊ˽⣬Խ spring.jmx.unique-names Ϊ trueMBean־Ψһġ
㻹Զ屩¶˵JMX ʾ application.properties һӡ
Properties
Yaml
spring.jmx.unique-names=true
management.endpoints.jmx.domain=com.example.myapp
㲻ͨJMX¶˵㣬 management.endpoints.jmx.exposure.exclude Ϊ *ʾ
Properties
Yaml
management.endpoints.jmx.exposure.exclude=*
ɹ۲ָⲿ۲һеϵͳڲ״̬֧ɣ־١
ڶ٣Spring Bootʹ Micrometer ObservationҪԼĹ۲죨⽫¶٣עһ ObservationRegistry
@Component
public class MyCustomObservation {
private final ObservationRegistry observationRegistry;
public MyCustomObservation(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
public void doSomething() {
Observation.createNotStarted("doSomething", this.observationRegistry)
.lowCardinalityKeyValue("locale", "en-US")
.highCardinalityKeyValue("userId", "42")
.observe(() -> {
// Execute business logic here
});
}
}
| ͿȵıǩӵָУ߿ȵıǩֻӵС |
|---|
ObservationPredicate``GlobalObservationConvention ObservationHandler ͵ Bean Զעᵽ ObservationRegistry ϡע ObservationRegistryCustomizer Beanһע
| JDBCR2DBCĿɹ۲ԣObservabilityʹõĿá JDBC Datasource Micrometer Ŀ ṩһ Spring Boot StarterڵJDBCʱԶ۲졣 οĵĶϢR2DBC R2DBC۲Spring BootԶ ΪR2DBCѯô۲졣 |
|---|
½ڽṩ־ָٵĸϸڡ
Spring Boot Actuatorʱ鿴Ӧó־Ĺܡ Բ鿴б־¼ãȷõ־Լ־ܸЧ־ɡ Щ֮һ
TRACE
DEBUG
INFO
WARN
ERROR
FATAL
OFF
null
null ʾûȷá
Ҫһļ¼POST һʵ嵽ԴURIʾ
{
"configuredLevel": "DEBUG"
}
Ҫ reset ã¼ض𣨲ʹĬãԴһ null ֵΪ configuredLevel |
|---|
Spring Boot ActuatorΪ Micrometer ṩԶãMicrometerһ֧ ڶϵͳ Ӧóָӿڣ
| Ҫ˽MicrometerĹܣμ οĵر |
|---|
Spring BootԶһϵ MeterRegistryΪclasspathϷֵÿֵ֧ʵһע ʱclasspathж micrometer-registry-{system} Spring Bootעˡ
עйͬص㡣 磬ʹ Micrometer עʵclasspathϣҲԽһضע ӽDatadog
Properties
Yaml
management.datadog.metrics.export.enabled=false
ҲԽеעעض˵ʾ
Properties
Yaml
management.defaults.metrics.export.enabled=false
Spring BootκԶõעӵ Metrics ϵȫ־̬עȷҪ
Properties
Yaml
management.metrics.use-global-registry=false
ע MeterRegistryCustomizer Beanһעκαע֮ǰӦͨǩ
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return (registry) -> registry.config().commonTags("region", "us-east-1");
}
}
ͨķͽӦضעʵ֡
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {
@Bean
public MeterRegistryCustomizer<GraphiteMeterRegistry> graphiteMetricsNamingConvention() {
return (registry) -> registry.config().namingConvention(this::name);
}
private String name(String name, Meter.Type type, String baseUnit) {
return ...
}
}
Spring Boot instrumentationͨûרעơ
ڼҪÿֵ֧ļϵͳ
Ĭ£AppOpticsעĻᶨڽָ͵ [api.appoptics.com/v1/measurements](https://api.appoptics.com/v1/measurements)Ҫָ굼 SaaS AppOpticsṩAPIơ
Properties
Yaml
management.appoptics.metrics.export.api-token=YOUR_TOKEN
Ĭ£ָᱻ㱾ػϵ Atlasṩ Atlas server λá
Properties
Yaml
management.atlas.metrics.export.uri=https://atlas.example.com:7101/api/v1/publish
һDatadogעĻᶨڽָ͵ datadoghq Ҫָ굽 DatadogṩAPIԿ
Properties
Yaml
management.datadog.metrics.export.api-key=YOUR_KEY
ṩһӦԿѡôԪݣDZͺͻλҲ
Properties
Yaml
management.datadog.metrics.export.api-key=YOUR_API_KEY
management.datadog.metrics.export.application-key=YOUR_APPLICATION_KEY
Ĭ£ָ걻͵Datadog site [api.datadoghq.com](https://api.datadoghq.com/) DatadogĿйվϣҪָͨ꣬ӦURI
Properties
Yaml
management.datadog.metrics.export.uri=https://api.datadoghq.eu
㻹ԸıDatadogָʱ
Properties
Yaml
management.datadog.metrics.export.step=30s
DynatraceṩָȡAPIΪ Micrometer ʵֵġ ҵDynatraceMicrometerָĵv1 ռеֻڵ Timeseries v1 API ʱv2 ռеֻڵ Metrics v2 API ʱע⣬üÿֻܵAPI v1 v2 汾v2 汾ѡ device-idv1Ҫv2вʹã v1 ռбãômetric v1 ˵㡣ͼٶ v2 汾
ַͨʽʹv2 API
DynatraceԶOneAgentDynatrace Operator for Kubernetesص
OneAgentOneAgentָԶ local OneAgent ingest endpoint ȡ˵㽫ָתDynatraceˡ
Dynatrace Kubernetes OperatorڰװDynatrace OperatorKubernetesʱעԶӲԱȡĶ˵URIAPIơ
ĬΪ io.micrometer:micrometer-registry-dynatrace ֮⣬Ҫرá
ûԶãҪ Metrics v2 API Ķ˵һ API ơAPIƱ Ingest metrics metrics.ingestȨáǽ齫ƵķΧһȨϡȷ˵URI·磬/api/v2/metrics/ingest
Metrics API v2ȡ˵URLIJѡͬ
SaaS: https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest
Managed deployments: https://{your-domain}/e/{your-environment-id}/api/v2/metrics/ingest
example environment id öֵ
Properties
Yaml
management.dynatrace.metrics.export.uri=https://example.live.dynatrace.com/api/v2/metrics/ingest
management.dynatrace.metrics.export.api-token=YOUR_TOKEN
ʹDynatrace v2 APIʱʹ¿ѡܣϸڿ Dynatraceĵ ҵ
Metric key ǰһǰǰӵеmetric keyС
DynatraceԪʵOneAgentDynatraceԱУöԪݣ磬̻Podḻָꡣ
Ĭάȡָӵеļֵԡ Micrometerָ˾ͬıǩǽĬdimension
ʹDynatrace Summary instrumentijЩ£Micrometer Dynatraceעָ걻ܾ Micrometer 1.9.xУͨDynatraceضժҪ⡣ Ϊ false ʹMicrometerص1.9.x֮ǰĬΪ ֻڴMicrometer 1.8.xǨƵ1.9.xʱʱſʹá
ԲָURIAPIƣʾ £ʹԶõĶ˵㡣
Properties
Yaml
management.dynatrace.metrics.export.v2.metric-key-prefix=your.key.prefix
management.dynatrace.metrics.export.v2.enrich-with-dynatrace-metadata=true
management.dynatrace.metrics.export.v2.default-dimensions.key1=value1
management.dynatrace.metrics.export.v2.default-dimensions.key2=value2
management.dynatrace.metrics.export.v2.use-dynatrace-summary-instruments=true
Dynatrace v1 APIָעͨʹ Timeseries v1 API ڽָ͵õURI Ϊеã device-id ʱv1Ҫv2вʹãָ걻Timeseries v1˵㡣 Ҫ Dynatrace ָ꣬ṩAPIơ豸IDURI
Properties
Yaml
management.dynatrace.metrics.export.uri=https://{your-environment-id}.live.dynatrace.com
management.dynatrace.metrics.export.api-token=YOUR_TOKEN
management.dynatrace.metrics.export.v1.device-id=YOUR_DEVICE_ID
v1APIָURIָ·Ϊv1Ķ˵·Զӡ
API˵⣬㻹ԸıDynatraceָļʱ䡣 Ĭϵĵʱ 60s ӽʱΪ30롣
Properties
Yaml
management.dynatrace.metrics.export.step=30s
Micrometerĵ Dynatraceĵ ҵΪMicrometerDynatrace exporterĸϢ
Ĭ£ָ걻㱾ػϵ Elastic ͨʹṩҪʹõElasticλá
Properties
Yaml
management.elastic.metrics.export.host=https://elastic.example.com:8086
Ĭ£ָ걻㱾ػϵ Ganglia ṩ Ganglia server Ͷ˿ڣʾ
Properties
Yaml
management.ganglia.metrics.export.host=ganglia.example.com
management.ganglia.metrics.export.port=9649
Ĭ£ָᱻ㱾ػϵ Graphite ṩ Graphite server Ͷ˿ڣʾ
Properties
Yaml
management.graphite.metrics.export.host=graphite.example.com
management.graphite.metrics.export.port=9004
MicrometerṩһĬϵ HierarchicalNameMapperdimensional meter IDhttps://micrometer.io/docs/registry/graphite#_hierarchical_name_mapping[ӳ䵽 flat hierarchical name]
ҪΪ붨 GraphiteMeterRegistry ṩԼ HierarchicalNameMapper Լ壬ṩһԶõ GraphiteConfig Clock BeanJavaKotlin@Configuration(proxyBeanMethods = false)public class MyGraphiteConfiguration { @Bean public GraphiteMeterRegistry graphiteMeterRegistry(GraphiteConfig config, Clock clock) { return new GraphiteMeterRegistry(config, clock, this::toHierarchicalName); } private String toHierarchicalName(Meter.Id id, NamingConvention convention) { return ... }} |
|---|
Ĭ£HumioעĻᶨڽָ͵ cloud.humio.com Ҫָ굼SaaS HumioṩAPIơ
Properties
Yaml
management.humio.metrics.export.api-token=YOUR_TOKEN
㻹ӦһǩȷָԴ
Properties
Yaml
management.humio.metrics.export.tags.alpha=a
management.humio.metrics.export.tags.bravo=b
Ĭ£ָᱻڱػϵ Influx v1ʵĬáҪָ굽InfluxDB v2 org``bucket дָauthentication tokenͨ·ʽṩҪʹõ Influx server λá
Properties
Yaml
management.influx.metrics.export.uri=https://influx.example.com:8086
Micrometerṩ˶ JMX ķֲӳ䣬ҪΪһۺͿֲķʽ鿴صĶ Ĭ£ָ걻 metrics JMX ͨ·ʽṩҪʹõ
Properties
Yaml
management.jmx.metrics.export.domain=com.example.app.metrics
MicrometerṩһĬϵ HierarchicalNameMapperdimensional meter ID ӳ䵽 flat hierarchical name
ҪΪ붨 JmxMeterRegistry ṩԼ HierarchicalNameMapper Լ壬ṩһԶõ JmxConfig Clock BeanJavaKotlin@Configuration(proxyBeanMethods = false)public class MyJmxConfiguration { @Bean public JmxMeterRegistry jmxMeterRegistry(JmxConfig config, Clock clock) { return new JmxMeterRegistry(config, clock, this::toHierarchicalName); } private String toHierarchicalName(Meter.Id id, NamingConvention convention) { return ... }} |
|---|
Ĭ£ָ걻㱾ػϵ KairosDB ͨ·ʽṩҪʹõ KairosDB server λá
Properties
Yaml
management.kairos.metrics.export.uri=https://kairosdb.example.com:8080/api/v1/datapoints
New RelicעĻᶨڽָ͵ New RelicҪָ굽 New RelicṩAPIԿ˻ID
Properties
Yaml
management.newrelic.metrics.export.api-key=YOUR_KEY
management.newrelic.metrics.export.account-id=YOUR_ACCOUNT_ID
㻹ԸıNew Relicָʱ
Properties
Yaml
management.newrelic.metrics.export.step=30s
Ĭ£ָͨREST÷ģclasspathJava Agent APIҲʹ
Properties
Yaml
management.newrelic.metrics.export.client-provider-type=insights-agent
ͨԼ NewRelicClientProvider ȫơ
Ĭ£ָ걻㱾ػϵ OpenTelemetry ͨ·ʽṩҪʹõ OpenTelemtry metric endpoint λá
Properties
Yaml
management.otlp.metrics.export.url=https://otlp.example.com:4318/v1/metrics
Prometheus ϣscrapeѯӦóʵָꡣSpring Boot /actuator/prometheus ṩһactuator˵㣬Աʵĸʽ Prometheus scrape
| Ĭ£ö˵Dzõģ뱻¶ϸμ¶˵ |
|---|
scrape_config ӵ prometheus.yml
scrape_configs:
- job_name: "spring"
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ["HOST:PORT"]
Ҳ֧ Prometheus ExemplarsҪܣӦһ SpanContextSupplier Beanʹ Micrometer Tracing⽫ΪԶã룬ǿԴԼġ鿴 Prometheus ĵ ΪҪPrometheusȷãֻ֧ʹ OpenMetrics ʽ
ڶݵĻҵܴڵʱ䲻ȡʹ Prometheus Pushgateway ָ֧֣걩¶PrometheusҪPrometheus Pushgateway֧֣Ŀ
<dependency>
<groupId>io.prometheus</groupId>
simpleclient_pushgateway
</dependency>
Prometheus Pushgatewayclasspathϣ management.prometheus.metrics.export.pushgateway.enabled ԱΪ true ʱһ PrometheusPushGatewayManager beanͱԶˡ Prometheus PushgatewayָĹ
ͨʹ management.prometheus.metrics.export.pushgateway µ PrometheusPushGatewayManager ڸãҲṩԼ PrometheusPushGatewayManager bean
SignalFxעĻᶨڽָ͵ SignalFxҪָ굽 SignalFxṩaccess token
Properties
Yaml
management.signalfx.metrics.export.access-token=YOUR_ACCESS_TOKEN
ҲԸıSignalFxָʱ
Properties
Yaml
management.signalfx.metrics.export.step=30s
Micrometerṩһġڴеĺˣûעú˻ԶΪá㿴 metrics endpoint ռЩ
һʹκõĺˣڴеĺ˾ͻԶرաҲȷؽ
Properties
Yaml
management.simple.metrics.export.enabled=false
StackdriverעĻᶨ Stackdriver ָꡣҪָ굽SaaS StackdriverṩGoogle Cloud project ID
Properties
Yaml
management.stackdriver.metrics.export.project-id=my-project
㻹ԸıStackdriverָʱ
Properties
Yaml
management.stackdriver.metrics.export.step=30s
StatsDעеؽָͨUDPStatsD agentĬ£ָ걻㱾ػϵ StatsD agentͨ·ʽṩStatsD˿ںЭ飬Աʹá
Properties
Yaml
management.statsd.metrics.export.host=statsd.example.com
management.statsd.metrics.export.port=9125
management.statsd.metrics.export.protocol=udp
㻹ԸıҪʹõStatsD·Э飨ĬΪDatadog
Properties
Yaml
management.statsd.metrics.export.flavor=etsy
Wavefrontעڽָ͵ Wavefrontֱӽָ굼 WavefrontṩAPI token
Properties
Yaml
management.wavefront.api-token=YOUR_API_TOKEN
⣬ĻʹWavefront sidecarڲתָݵWavefront API
Properties
Yaml
management.wavefront.uri=proxy://localhost:2878
ָ귢Wavefront Wavefrontĵ proxy://HOST:PORT ʽ
ҲԸıWavefrontָʱ
Properties
Yaml
management.wavefront.metrics.export.step=30s
Spring BootΪָļṩԶעᡣ ڴ£Ĭֵṩ˺ָ꣬Էκֵ֧ļϵͳС
Զͨʹú Micrometer JVM JVMָ jvm. meter name ·
ṩJVMָꡣ
ڴͻϸ
ռйصͳ
߳
غжص
JVMİ汾Ϣ
JIT ʱ
ԶͨʹúMicrometerʵϵͳ ϵͳָ system.``process. disk. meter ·
ṩϵͳָꡣ
CPUָ
ļָ
ʱָ꣨ӦóѾеʱ;ʱĹ̶
õĴ̿ռ
Զñ¶Ӧóʱָꡣ
application.started.time: Ӧóʱ䡣
application.ready.timeӦóΪṩʱ䡣
ָӦȫǵġ
ԶLogbackLog4J2¼ ϸ log4j2.events. logback.events. meter¹
Զʹпõ ThreadPoolTaskExecutor ThreadPoolTaskScheduler BeanֻܱҪײ ThreadPoolExecutor á ָexecutorǣexecutorBeanơ
Զܹ Spring MVC Controllerͱʽhandlerж Ĭ£ָ http.server.requests Ϊɵġ ͨ management.observations.http.server.requests.name Ƹơ
ڲĹ۲observationĸϢμ Spring Framework οĵ
ҪӵĬϱǩУṩһ̳ org.springframework.http.server.observation е DefaultServerRequestObservationConvention @BeanҪ滻Ĭϱǩṩһʵ ServerRequestObservationConvention @Bean
| ijЩ£Webд쳣ᱻ¼ΪǩӦóѡ벢ͨhandled exception Ϊ request attribute¼쳣 |
|---|
Ĭ£ ҪԶṩһʵ FilterRegistrationBean<WebMvcMetricsFilter> @Bean
ԶܹSpring WebFlux controllerͱʽhandlerж Ĭ£ָ http.server.requests Ϊɵġ ͨ management.observations.http.server.requests.name Ƹơ
ڲĹ۲observationĸϢμ Spring Framework οĵ
ҪӵĬϱǩУṩ̳ org.springframework.http.server.reactive.observation е DefaultServerRequestObservationConvention @BeanҪ滻Ĭϱǩṩһʵ ServerRequestObservationConvention @Bean
| ijЩ£ʹд쳣ᱻ¼ΪǩӦóѡ벢ͨhandled exceptionΪrequest attribute¼쳣 |
|---|
ԶʹJersey JAX-RSʵܱ Ĭ£ָ http.server.requests Ϊɵġ ͨ management.observations.http.server.requests.name ơ
Ĭ£Jerseyָ걻ΪϢ
<colgroup><col><col></colgroup> | Tag | ˵ | | --- | --- | | `exception` | ʱ׳κ쳣ļ | | `method` | ķ磬`GET` `POST` | | `outcome` | ĽӦ״̬롣 1xx `INFORMATIONAL`2xx `SUCCESS`3xx `REDIRECTION`4xx `CLIENT_ERROR`5xx `SERVER_ERROR` | | `status` | ӦHTTP״̬루磬`200` `500` | | `uri` | ܵĻڽб滻֮ǰURIģ壨磺`/api/person/{id}` |ҪƱǩṩһʵ JerseyTagsProvider @Bean
Spring Boot Actuator RestTemplate WebClient ĹߡΪˣעԶõĹʹʵ
RestTemplateBuilder RestTemplate
WebClient.Builder WebClient
ҲֶӦøߵcustomizer ObservationRestTemplateCustomizer ObservationWebClientCustomizer
Ĭ£ָ http.client.requests ɵġ
ͨ management.observations.http.client.requests.name ֡
ڲĹ۲observationĸϢμ Spring Framework οĵ
Ҫʹ RestTemplate ʱƱǩṩһʵ org.springframework.http.client.observation ClientRequestObservationConvention @BeanҪʹ WebClient ʱԶǩṩһʵ org.springframework.web.reactive.function.client ClientRequestObservationConvention @Bean
Զý MBeanRegistry ʱŻTomcat Ĭ£MBeanRegistry ǽõģͨ server.tomcat.mbeanregistry.enabled Ϊ true
Tomcatָ tomcat. meter ·
Զÿʱпõ Cache ʵм⣬ָ cache Ϊǰ
DZDZĻָ꼯
ҲʹöġԻָꡣ
֧»⡣
Cache2k
Caffeine
Hazelcast
κμݵJCacheJSR-107ʵ
Redis
ָɻƺ CacheManager ǣCacheManager Beanġ
ֻʱõĻ汻ע ûڻжĻ棬κʱĻԱ̷ʽĻ棬Ҫȷעᡣ һ CacheMetricsRegistrar Beanʹ̸ס |
|---|
Զʹпõ DataSource ָǰΪ jdbc.connections ԴĽDZʾеǰġеġĺСDZ
ҲɻbeanƼ DataSource ǡ
Ĭ£Spring BootΪֵ֧ԴṩԪݡ ϲԴ֧֣Ӷ DataSourcePoolMetadataProvider Bean DataSourcePoolMetadataProvidersConfiguration ˽ʵ |
|---|
⣬Hikariضָ hikaricp ǰ¶ ÿָ궼poolǣ spring.datasource.name ƣ
org.hibernate.orm:hibernate-micrometer classpathϣͳƹܵHibernate EntityManagerFactory ʵᱻһΪ hibernate ָ⡣
Ҳ EntityManagerFactory ǣBeanġ
ҪͳƣJPA hibernate.generate_statistics Ϊ true Զõ EntityManagerFactory á
Properties
Yaml
spring.jpa.properties[hibernate.generate_statistics]=true
ԶܹSpring Data Repository ĵýж Ĭ£ָ spring.data.repository.invocations Ϊɡ ͨ management.metrics.data.repository.metric-name Զơ
io.micrometer.core.annotation е @Timed ע֧ Repository ӿںͷ㲻¼ Repository õĶmetricԽ management.metrics.data.repository.autotime.enabled Ϊ falseרʹ @Timed ע⡣
һ longTask = true @Timed עΪ÷һʱʱҪһ metric nameҿʱtask timerӡ |
|---|
Ĭ£repositoryصĶΪϢ
<colgroup><col><col></colgroup> | Tag | ˵ | | --- | --- | | `repository` | Դ `Repository` ļ | | `method` | õ `Repository` ơ | | `state` | ״̬`SUCCESS`, `ERROR`, `CANCELED`, `RUNNING` | | `exception` | ׳κ쳣ļ |Ҫ滻ĬϱǩҪṩһʵ RepositoryTagsProvider @Bean
Զʹпõ RabbitMQ ӹָΪ rabbitmq
ֻҪ MeterRegistry beanSpring IntegrationͻԶṩ Micrometer support spring.integration. meter ·
ԶΪԶõ߹߹ֱעһ MicrometerConsumerListener MicrometerProducerListener Ϊ StreamsBuilderFactoryBean עһ KafkaStreamsMicrometerListener ϸڣSpring Kafkaĵе Micrometer Native Metrics ֡
ڼҪMongoDBĿö
Զý MongoMetricsCommandListener Զõ MongoClient עᡣ
һΪ mongodb.driver.commands timerָ걻ײMongoDB driverÿ Ĭ£ÿָ궼ΪϢ
Ϊ滻ĬϵĶǩһ MongoCommandTagsProvider beanʾ
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MyCommandTagsProviderConfiguration {
@Bean
public MongoCommandTagsProvider customCommandTagsProvider() {
return new CustomCommandTagsProvider();
}
}
ҪԶõԡ
Properties
Yaml
management.metrics.mongo.command.enabled=false
Զý MongoMetricsConnectionPoolListener Զõ MongoClient עᡣ
ΪӳشIJָꡣ
mongodb.driver.pool.size ӳصĵǰСкʹõijԱ
mongodb.driver.pool.checkedout 浱ǰʹе
mongodb.driver.pool.waitqueuesize ӵĵȴеĵǰС
Ĭ£ÿָ궼ΪϢ
<colgroup><col><col></colgroup> | Tag | ˵ | | --- | --- | | `cluster.id` | ӳӦļȺıʶ | | `server.address` | ӳӦķĵַ |ҪȡĬϵĶǩ붨һ MongoConnectionPoolTagsProvider bean
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MyConnectionPoolTagsProviderConfiguration {
@Bean
public MongoConnectionPoolTagsProvider customConnectionPoolTagsProvider() {
return new CustomConnectionPoolTagsProvider();
}
}
ҪԶõӳضԡ
Properties
Yaml
management.metrics.mongo.connectionpool.enabled=false
ԶͨʹMicrometer JettyServerThreadPoolMetrics ΪJetty ThreadPool ָꡣ Jetty Connector ʵָͨʹMicrometer JettyConnectionMetrics server.ssl.enabled Ϊ true ʱMicrometer JettySslHandshakeMetrics
ҪSpring Bootֱֵ֧ĵطʹ @Timedο Micrometer ĵ
ԶΪԶõ LettuceConnectionFactory עһ MicrometerCommandLatencyRecorder ϸڣLettuceĵ Micrometer Metrics
ҪעԶ뽫 MeterRegistry עС
Java
Kotlin
@Component
public class MyBean {
private final Dictionary dictionary;
public MyBean(MeterRegistry registry) {
this.dictionary = Dictionary.load();
registry.gauge("dictionary.size", Tags.empty(), this.dictionary.getWords().size());
}
}
ĶBeanǽʹ MeterBinder עǡ
Java
Kotlin
public class MyMeterBinderConfiguration {
@Bean
public MeterBinder queueSize(Queue queue) {
return (registry) -> Gauge.builder("queueSize", queue::size).register(registry);
}
}
ʹ MeterBinder ȷȷϵڼֵʱBeanǿõġ 㷢Ӧóظһָ꣬ô MeterBinder ʵҲá
Ĭ£ MeterBinder Beanָ궼ԶSpring MeterRegistry |
|---|
Ҫض Meter ʵԶ壬ʹ io.micrometer.core.instrument.config.MeterFilter ӿڡ
磬 com.example ͷDZID mytag.region ǩΪ mytag.area¹
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MyMetricsFilterConfiguration {
@Bean
public MeterFilter renameRegionTagMeterFilter() {
return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
}
}
Ĭ£е MeterFilter BeanԶSpring MeterRegistry ȷʹSpring MeterRegistry עָ꣬ʹ Metrics κξ̬ ЩʹõDzSpringȫע |
|---|
ͨñǩһڶлά꣬ʵջȡ ñǩDZԽãʾ
Properties
Yaml
management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod
ǰΪֵΪ us-east-1 prod DZ region stack ǩ
ʹGraphiteͨǩ˳ǺҪġ ʹַܱ֤ǩ˳GraphiteûһԶ MeterFilter 档 |
|---|
MeterFilter Bean㻹ʹÿĻӦһԶ幦ܡ ʹSpring Boot PropertiesMeterFilterÿĶƱӦԸƿͷκαID ӹ˵κID example.remote ͷDZ
Properties
Yaml
management.metrics.enable.example.remote=false
per-meterĶơ
<caption>Table 1\. Per-meter customizations</caption><colgroup><col><col></colgroup> | Property | ˵ | | --- | --- | | `management.metrics.enable` | ǷܾضIDMeter ܵMeter `MeterRegistry` й˵ | | `management.metrics.distribution.percentiles-histogram` | Ƿʺϼɾۼάȣİٷλֱֵͼ | | `management.metrics.distribution.minimum-expected-value`, `management.metrics.distribution.maximum-expected-value` | ͨǯԤֵķΧٵֱͼͰ | | `management.metrics.distribution.percentiles` | Ӧóмİٷλֵ | | `management.metrics.distribution.expiry`, `management.metrics.distribution.buffer-length` | ͨڻλлǸȨأλڿõĹںתΪ õĻȡ | | `management.metrics.distribution.slo` | һۻֱͼеͰķˮƽĿ궨塣 |percentiles-histogram ٷ-ֱͼpercentilesٷ slo ĸĸϸڣμMicrometerĵе Histograms and percentiles ֱͼͰٷ
Spring Bootṩһ metrics ˵㣬ԵʹӦóռָꡣö˵ĬDzõģ빫ϸμ ¶˵
/actuator/metrics ʾһõDZб ͨṩΪѡ鿴ijضDZϢ磬/actuator/metrics/jvm.memory.max
ʹõӦʹõһ£ļϵͳо淶֡ 仰˵ jvm.memory.max PrometheusʾΪ jvm_memory_maxΪȻӦʹ jvm.memory.max Ϊѡ metrics ˵мDZ |
|---|
ҲURLĩβ tag=KEY:VALUE ѯԶDZά??磬/actuator/metrics/jvm.memory.max?tag=area:nonheap
IJֵDZƥDZκӦõıǩͳ ܺ ǰУص Value ͳǶѵ Code CacheCompressed Class Space Metaspace ڴ桰㼣֮͡ ֻ Metaspace ߴ磬һ tag=id:Metaspace -- /actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace |
|---|
һ DefaultMeterObservationHandler Զע ObservationRegistry ϣΪÿɵĹ۲죨completed observationmetric
Spring Boot Actuator Ϊ Micrometer Tracing ṩԹԶã Micrometer Tracing еtracerһӿڣfacade
| Ҫ˽ Micrometer Tracing ܵϢ οĵ |
|---|
Spring BootΪṩԶá
ҪһʼٵʾӦóǵĿĶԣgetting-started.html 漰ļ Hello World! web㹻ˡǽʹ OpenTelemetry Zipkin Ϊٺˡ
عһ£ǵҪӦô뿴ġ
@RestController
@SpringBootApplication
public class MyApplication {
private static final Log logger = LogFactory.getLog(MyApplication.class);
@RequestMapping("/")
String home() {
logger.info("home() has been called");
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
home() Уһӵlogger䣬ںҪ |
|---|
ڣDZ
org.springframework.boot:spring-boot-starter-actuator
io.micrometer:micrometer-tracing-bridge-otel - Micrometer Observation API OpenTelemetry ıҪ
io.opentelemetry:opentelemetry-exporter-zipkin - Zipkin traces Ҫġ
µ application properties:
Properties
Yaml
management.tracing.sampling.probability=1.0
Ĭ£Spring Bootֻ10%вԷֹٺ˲ظԽлΪ100%ÿᱻ͵ٺˡ
ΪռͿӻ٣ҪһиٵĺˡʹZipkinΪǵĸٺˡ Zipkinָ ṩڱZipkin˵
ZipkinкӦó
web [localhost:8080](http://localhost:8080/)Ӧÿ
Hello World!
ĻѾΪHTTPһ observationŽӵ OpenTelemetryZipkinһµĸ٣trace
ڣ [localhost:9411](http://localhost:9411/) Zipkinû棬 "Run Query" ťгռĸϢӦÿһ١ "Show" ť鿴ٵϸڡ
ͨ logging.pattern.level Ϊ %5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]־аǰĸ٣trace span id |
|---|
Micrometer Tracerֶ֧ʾʵ֣Spring Bootжϡ
ʵֶҪ org.springframework.boot:spring-boot-starter-actuator
io.micrometer:micrometer-tracing-bridge-otel - Micrometer Observation API OpenTelemetry ıҪ
io.opentelemetry:opentelemetry-exporter-zipkin - ZipkintraceҪġ
io.micrometer:micrometer-tracing-bridge-otel - Micrometer Observation API OpenTelemetry ıҪ
io.micrometer:micrometer-tracing-reporter-wavefront - WavefronttraceҪġ
io.micrometer:micrometer-tracing-bridge-brave - Micrometer Observation API Brave ıҪ
io.zipkin.reporter2:zipkin-reporter-brave - Zipkin trace Ҫġ
ĿûʹSpring MVCSpring WebFluxҲҪʹ io.zipkin.reporter2:zipkin-sender-urlconnection |
|---|
io.micrometer:micrometer-tracing-bridge-brave - ӲMicrometer Observation APIBraveıҪ
io.micrometer:micrometer-tracing-reporter-wavefront - WavefronttraceҪġ
ͨһ observation ԼspanΪˣ ObservationRegistry ע뵽С
@Component
class CustomObservation {
private final ObservationRegistry observationRegistry;
CustomObservation(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
void someOperation() {
Observation observation = Observation.createNotStarted("some-operation", this.observationRegistry);
observation.lowCardinalityKeyValue("some-tag", "some-value");
observation.observe(() -> {
// Business logic ...
});
}
}
⽫һΪ "some-operation" observationǩΪǩΪ "some-tag=some-value"
| ڲmetric´һspanҪʹ Micrometer ͼTracer API |
|---|
һSpring SecurityãSpring Boot ActuatorһƿܣԷ¼ĬΪ authentication success, failure access denied 쳣 һܶڱʵʩ֤ʧܵԷdzá
ͨӦóṩһ AuditEventRepository ͵beanơ Ϊ˷㣬Spring Bootṩһ InMemoryAuditEventRepository InMemoryAuditEventRepository Ĺޣǽֻڿʹ 뿼ǴԼ AuditEventRepository ʵ֡
Ϊ˶Ʒİȫ¼ṩԼ AbstractAuthenticationAuditListener AbstractAuthorizationAuditListener ʵ֡
ҲΪԼҵ¼ʹƷ Ҫһ㣬Ҫô AuditEventRepository beanעԼֱʹҪôSpring ApplicationEventPublisher AuditApplicationEventͨʵ ApplicationEventPublisherAware
ͨӦóṩһ HttpExchangeRepository ͵ bean HTTP exchange ļ¼Ϊ˷Spring Boot ṩ InMemoryHttpExchangeRepositoryĬ£洢100 request/response exchangeٽtracing solutionsȣInMemoryHttpExchangeRepository ģǽֻڿʹǽʹһĸٻ۲ Zipkin OpenTelemetry⣬ҲԴԼ HttpExchangeRepository
ʹ httpexchanges ˵ȡ洢 HttpExchangeRepository е request/response exchange Ϣ
ҪԶÿ¼ exchange Ŀʹ management.httpexchanges.recording.include ԡ
Ҫȫֹ±룬뽫 management.httpexchanges.recording.enabled Ϊ false
spring-boot ģУҵļ࣬Щļڽ̼ͨá
ApplicationPidFileWriter һӦóPIDļĬ£ӦóĿ¼£ļΪ application.pid
WebServerPortFileWriter һļеWebĶ˿ڣĬ£ӦóĿ¼£ļΪ application.port
Ĭ£Щдûбǡ
META-INF/spring.factories ļУԼдPIDļlistenerһ߶
org.springframework.context.ApplicationListener=
org.springframework.boot.context.ApplicationPidFileWriter,
org.springframework.boot.web.context.WebServerPortFileWriter
Ҳͨ SpringApplication.addListeners(?) ʵ Writer һ Writer 캯Զļ·
Spring Boot actuatorģ֧֣ݵ Cloud Foundry ʵʱֽ֧ /cloudfoundryapplication ·Ϊ @Endpoint Beanṩһȫ·ߡ
չ֧ʹ Cloud Foundry UI鿴ѲӦó Web Ӧóõ Spring Boot ִϢǿ 磬Ӧó״̬ҳĽϢǵ͵ running stopped ״̬
ͨûֱӷ /cloudfoundryapplication · Ҫʹøö˵㣬дһЧ UAA ơ |
|---|
ȫ /cloudfoundryapplication ˵㣬 application.properties ļá
Properties
Yaml
management.cloudfoundry.enabled=false
Ĭ£/cloudfoundryapplication ˵İȫ֤Ը Cloud Foundry SSL á Cloud Foundry UAA Cloud Controller ʹǩ֤飬Ҫԡ
Properties
Yaml
management.cloudfoundry.skip-ssl-validation=true
context-path Ϊ / κݣ Cloud Foundry ˵Ӧóĸá 磬 server.servlet.context-path=/app Cloud Foundry ˵ /app/cloudfoundryapplication/* á
ϣ Cloud Foundry ˵ʼ /cloudfoundryapplication/* ã۷·ΣҪӦóȷá ʹõ Web ͬͬ Tomcatá
Java
Kotlin
@Configuration(proxyBeanMethods = false)
public class MyCloudFoundryConfiguration {
@Bean
public TomcatServletWebServerFactory servletWebServerFactory() {
return new TomcatServletWebServerFactory() {
@Override
protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
super.prepareContext(host, initializers);
StandardContext child = new StandardContext();
child.addLifecycleListener(new Tomcat.FixContextListener());
child.setPath("/cloudfoundryapplication");
ServletContainerInitializer initializer = getServletContextInitializer(getContextPath());
child.addServletContainerInitializer(initializer, Collections.emptySet());
child.setCrossContext(true);
host.addChild(child);
}
};
}
private ServletContainerInitializer getServletContextInitializer(String contextPath) {
return (classes, context) -> {
Servlet servlet = new GenericServlet() {
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
ServletContext context = req.getServletContext().getContext(contextPath);
context.getRequestDispatcher("/cloudfoundryapplication").forward(req, res);
}
};
context.addServlet("cloudfoundry", servlet).addMapping("/*");
};
}
}
һ Graphite ͼιߡ