ããã¯ããªã«ãããããŠæžãããã®ïŒ
Spring Boot Actuatorã®ãã«ã¹ãã§ãã¯ãè¡ãæã«ãäžç·ã«ããŒã¿ã¹ãã¢ãªã©ã®ãã«ã¹ãã§ãã¯ãè¡ã£ãŠããããããªã®ã§ã
ã¡ãã£ãšèŠãŠã¿ãŸããã
Spring Boot ActuatorïŒHealth Information
ãããããSpring Boot Actuatorã¯ïŒãšãããšããããã§ããã
Spring Boot Actuatorã¯ãæ¬çªç°å¢ã§ã¢ããªã±ãŒã·ã§ã³ãåäœãããéã«ã¢ãã¿ãªã³ã°ã管çããã®ã«äŸ¿å©ãªæ©èœãå«ãã ãã®ã§ãã
HTTPãšã³ããã€ã³ããŸãã¯JMXã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ã管çãããã¢ãã¿ãªã³ã°ãããã§ããŸããç£æ»ããã«ã¹ãã§ãã¯ã
ã¡ããªã¯ã¹ã®åéãªã©ãå«ãã§ããŸãã
Spring Boot includes a number of additional features to help you monitor and manage your application when you push it to production. You can choose to manage and monitor your application by using HTTP endpoints or with JMX. Auditing, health, and metrics gathering can also be automatically applied to your application.
Spring Boot Actuatorã«ã¯ãè€æ°ã®ãšã³ããã€ã³ããšåŒã°ãããã®ããããŸãããã®äžèŠ§ã¯ã以äžã«èšèŒããŠãããŸãã
Production-ready Features / Endpoints
ãã«ã¹ãã§ãã¯ã®å Žåã¯ãhealth
ãšã³ããã€ã³ãã該åœããŸãã以éã¯ãã«ã¹ãã§ãã¯ïŒhealth
ãšã³ããã€ã³ãïŒã«çµã£ãŠããã¥ã¡ã³ãã
èŠãŠãããŸãã
Spring Boot Actuatorã®ãã«ã¹ãã§ãã¯ã«é¢ããããã¥ã¡ã³ãã¯ããã¡ãã
Production-ready Features / Endpoints / Health Information
ãã«ã¹ãã§ãã¯ã«äœ¿ãããæ
å ±ã¯ãHealthContributorRegistry
ããåéããããã®ã«ãªããšæžãããŠããŸãã
Health information is collected from the content of a HealthContributorRegistry (by default, all HealthContributor instances defined in your ApplicationContext).
ããã©ã«ãã§ã¯ãApplicationContext
ã§å®çŸ©ãããŠãããã¹ãŠã®HealthContributor
ã€ã³ã¹ã¿ã³ã¹ãå«ãŸããŠããŸãã
HealthContributor
ã¯ã€ã³ã¿ãŒãã§ãŒã¹ã§ãããHealthIndicator
ãŸãã¯CompositeHealthContributor
ã®ã©ã¡ããã«ãªããŸãã
HealthIndicator
ã¯ãStatus
ãå«ããã«ã¹æ
å ±ãæäŸããã€ã³ã¿ãŒãã§ãŒã¹ã§ããCompositeHealthContributor
ã¯ãè€æ°ã®HealthContributors
ã®
çµã¿åããã«ãªããŸãã
A HealthContributor can be either a HealthIndicator or a CompositeHealthContributor. A HealthIndicator provides actual health information, including a Status. A CompositeHealthContributor provides a composite of other HealthContributors.
ããã©ã«ãã§ã¯ãã¹ããŒã¿ã¹ã®é ã«åHealthIndicator
ã®ã¹ããŒã¿ã¹ã䞊ã³æ¿ããããšã«ãããæçµçãªã·ã¹ãã ã®ãã«ã¹æ
å ±ã¯
StatusAggregator
ã«ãã£ãŠå°åºãããŸãã
By default, the final system health is derived by a StatusAggregator, which sorts the statuses from each HealthIndicator based on an ordered list of statuses.
ãœãŒããããçµæãæåã®ã¹ããŒã¿ã¹ãå šäœã®ãã«ã¹ãã§ãã¯ã®çµæãšãªããŸãã
The first status in the sorted list is used as the overall health status.
Status
ãšããã®ã¯ããã¡ãã§ããã
Status (Spring Boot 2.6.7 API)
UP
ãDOWN
ãOUT_OF_SERVICE
ãUNKNOWN
ã®4ã€ã®ã¹ããŒã¿ã¹ããããŸãã
ããã©ã«ãã®ãœãŒãé ã¯ãDOWN
â OUT_OF_SERVICE
â UP
â UNKNOWN
ã®ããã§ãã
ã€ãŸããã©ããã²ãšã€ã§ãDOWN
ãè¿ãHealthIndicator
ãããã°ãå
šäœã®ãã«ã¹ãã§ãã¯ã®çµæãšããŠã¯DOWN
ãšãªãããã§ããã
ã¡ãªã¿ã«ãStatusAggregator
ãç¥ã£ãŠããã¹ããŒã¿ã¹ãè¿ãHealthIndicator
ãã²ãšã€ããªãå Žåãå
šäœã®ã¹ããŒã¿ã¹ãšããŠã¯UNKNOWN
ã«
ãªãããã§ãã
If no HealthIndicator returns a status that is known to the StatusAggregator, an UNKNOWN status is used.
ãŸããSpring Bootã¯ããã€ãã®HealthIndicator
ãèªåæ§æããŸãã以äžã«ãªã¹ãã¢ãããããŠããŸãã
Production-ready Features / Endpoints / Health Information / Auto-configured HealthIndicators
çŸæç¹ã§ã以äžã察象ãšãªãããã§ããïŒïŒå ã¯ããŒåã§ãã
- Apache CassandraïŒcassandraïŒ
- CouchbaseïŒcouchbaseïŒ
- DataSourceïŒdbïŒ
- ãã£ã¹ã¯ïŒdiskspaceïŒ
- ElasticsearchïŒelasticsearchïŒ
- HazelcastïŒhazelcastïŒ
- InfluxDBïŒinfluxdbïŒ
- JMSãããŒã«ãŒïŒjmsïŒ
- LDAPãµãŒããŒïŒldapïŒ
- ã¡ãŒã«ãµãŒããŒïŒmailïŒ
- MongoDBïŒmongoïŒ
- Neo4jïŒneo4jïŒ
- åžžã«
UP
ãè¿ãHealthIndicator
ïŒpingïŒ - RabbitMQïŒrabbitïŒ
- RedisïŒredisïŒ
- Apache SolrïŒsolrïŒ
åHealthIndicator
ã¯ãmanagement.health.[ããŒå].enabled
ããããã£ãfalse
ã«æå®ãããšç¡å¹ã«ããããšãã§ããŸãã
ããã©ã«ãã§èªåæ§æãããHealthIndicator
ããã¹ãŠç¡å¹ã«ããå Žåã¯ãmanagement.health.defaults.enabled
ããããã£ã
䜿ãã°ããã¿ããã§ãã
ã¡ãªã¿ã«ãããã©ã«ãã§æå¹ã«ãªã£ãŠããªãLivenessStateHealthIndicator
ïŒlivenessstateïŒãReadinessStateHealthIndicator
ïŒreadinessstateïŒ
ãšãã2ã€ã®HealthIndicator
ãããããã§ãããã¡ãã¯ãKubernetesåãã¿ããã§ããã
ä»åã¯æ±ããŸããããSpring Boot Actuatorã§çšæãããŠããHealthIndicator
ã§è¶³ããªãå Žåã¯ãèªåã§HealthIndicator
ãäœæããããšã«
ãªããã§ããããã
Production-ready Features / Endpoints / Health Information / Writing Custom HealthIndicators
ãã«ã¹ãã§ãã¯å
ã§äœ¿çšãããHealthIndicator
ã®æ
å ±ã¯ã詳现æ
å ±ãšãªãã®ã§ããã©ã«ãã§ã¯è¡šç€ºãããŸãããããã衚瀺ããããã«
ããã«ã¯management.endpoint.health.show-details
ããããã£ãŸãã¯management.endpoint.health.show-components
ããããã£ã
䜿çšããŸãã
The information exposed by the health endpoint depends on the management.endpoint.health.show-details and management.endpoint.health.show-components properties, which can be configured with one of the following values:
Production-ready Features / Endpoints / Health Information
説æã¯ãããããã«ããŠãä»åã¯DataSourceïŒJDBCã§ããïŒãšRedisãå«ãããã«æ§æããŠããã«ã¹ãã§ãã¯ãè¡ã£ãŠã¿ãŸãããã
ç°å¢
ä»åã®ç°å¢ã¯ããã¡ãã
$ java --version openjdk 17.0.3 2022-04-19 OpenJDK Runtime Environment (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1) OpenJDK 64-Bit Server VM (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing) $ mvn --version Apache Maven 3.8.5 (3599d3414f046de2324203b78ddcf9b5e4388aa0) Maven home: $HOME/.sdkman/candidates/maven/current Java version: 17.0.3, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64 Default locale: ja_JP, platform encoding: UTF-8 OS name: "linux", version: "5.4.0-110-generic", arch: "amd64", family: "unix"
ããŒã¿ããŒã¹ã«ã¯ãMySQLã䜿ãããšã«ããŸããããŒãžã§ã³ã¯ä»¥äžã§ã172.17.0.2ã§åäœããŠãããã®ãšããŸãã
$ mysql --version mysql Ver 8.0.29 for Linux on x86_64 (MySQL Community Server - GPL)
Redisã®ããŒãžã§ã³ã¯ãã¡ããRedisã¯172.17.0.3ã§åäœããŠãããã®ãšããŸãã
$ bin/redis-server --version Redis server v=7.0.0 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=45b2bca311da7733
ã¢ããªã±ãŒã·ã§ã³ãäœæãã
ãŸãã¯ãSpring Bootãããžã§ã¯ããäœæããŸããäŸåé¢ä¿ã«web
ãactuator
ãjdbc
ãmysql
ãdata-redis
ãå ããŠããŸãã
$ curl -s https://start.spring.io/starter.tgz \ -d bootVersion=2.6.7 \ -d javaVersion=17 \ -d name=actuator-healthcheck-with-datastore \ -d groupId=org.littlewings \ -d artifactId=actuator-healthcheck-with-datastore \ -d version=0.0.1-SNAPSHOT \ -d packageName=org.littlewings.spring.actuator \ -d dependencies=web,actuator,jdbc,mysql,data-redis \ -d baseDir=actuator-healthcheck-with-datastore | tar zxvf -
ãããžã§ã¯ãå ã«ç§»åã
$ cd actuator-healthcheck-with-datastore
Mavenã®äŸåé¢ä¿ããã©ã°ã€ã³èšå®ãªã©ã
<properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
èªåçæããããœãŒã¹ã³ãŒãã¯ãåé€ããŠãããŸãã
$ rm src/main/java/org/littlewings/spring/actuator/ActuatorHealthcheckWithDatastoreApplication.java src/test/java/org/littlewings/spring/actuator/ActuatorHealthcheckWithDatastoreApplicationTests.java
åäœç¢ºèªã®ããã«ãçšæããããŒã¿ã¹ãã¢ã«ã¢ã¯ã»ã¹ããControllerãäœæã
src/main/java/org/littlewings/spring/actuator/DataStoreController.java
package org.littlewings.spring.actuator; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Collections; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("datastore") public class DataStoreController { NamedParameterJdbcTemplate jdbcTemplate; StringRedisTemplate redisTemplate; public DataStoreController(NamedParameterJdbcTemplate jdbcTemplate, StringRedisTemplate redisTemplate) { this.jdbcTemplate = jdbcTemplate; this.redisTemplate = redisTemplate; } @GetMapping("jdbc") public String jdbc() { return jdbcTemplate .queryForObject("select now()", Collections.emptyMap(), LocalDateTime.class) .format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss")); } @GetMapping("redis") public String redis() { return redisTemplate .getRequiredConnectionFactory() .getConnection() .serverCommands() .info() .getProperty("redis_version"); } }
MySQLã«select now()
ãæããã¡ãœãããšãRedisã®ããŒãžã§ã³ãååŸããã¡ãœãããäœæããŠããŸãã
main
ã¯ã©ã¹ã
src/main/java/org/littlewings/spring/actuator/App.java
package org.littlewings.spring.actuator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class App { public static void main(String... args) { SpringApplication.run(App.class, args); } }
èšå®ã¯ããŸãã¯æäœéã«ããŠãããŸãã
src/main/resources/application.properties
spring.datasource.url=jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8 spring.datasource.username=kazuhira spring.datasource.password=password spring.redis.url=redis://redispass@172.17.0.3:6379 spring.redis.connect-timeout=3s spring.redis.timeout=3s
Redisã ãã¿ã€ã ã¢ãŠããå ¥ããŠããã®ã¯ãã¡ãã£ãšçç±ããããŸãã
åäœç¢ºèªããŠãããŸãããã
ããã±ãŒãžã³ã°ããŠãã¢ããªã±ãŒã·ã§ã³ãèµ·åã
$ mvn package $ java -jar target/actuator-healthcheck-with-datastore-0.0.1-SNAPSHOT.jar
確èªã
# MySQL $ curl localhost:8080/datastore/jdbc 2022-05-14 13:30:15 # Redis $ curl localhost:8080/datastore/redis 7.0.0
OKã§ããã
Spring Boot Actuatorã®ãã«ã¹ãã§ãã¯ã確èªããŠã¿ã
ã§ã¯ãSpring Boot Actuatorã®ãã«ã¹ãã§ãã¯ã®ç¢ºèªã«ç§»ããŸãããã
ããã©ã«ãã§ã¯/actuator/health
ãSpring Boot Actuatorã®ãã«ã¹ãã§ãã¯ã®ãã¹ãšããŠå
¬éãããã®ã§ããã¡ãã«ã¢ã¯ã»ã¹ããŠã¿ãŸãã
$ curl -i localhost:8080/actuator/health HTTP/1.1 200 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 13:37:33 GMT {"status":"UP"} $ curl -s localhost:8080/actuator/health | jq { "status": "UP" }
HTTPã¹ããŒã¿ã¹ã³ãŒãã¯200ã§ãã¹ããŒã¿ã¹ã¯UP
ãšè¿ã£ãŠããŸããã
ããã§ãRedisãåæ¢ããŠã¢ã¯ã»ã¹ããŠã¿ãŸãã
$ curl -i localhost:8080/actuator/health HTTP/1.1 503 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 13:38:16 GMT Connection: close {"status":"DOWN"} $ curl -s localhost:8080/actuator/health | jq { "status": "DOWN" }
HTTPã¹ããŒã¿ã¹ã³ãŒãã503ãšãªããã¹ããŒã¿ã¹ã¯DOWN
ãšãªããŸããã
Redisã«ã¢ã¯ã»ã¹ã§ããªããªã£ãã®ã§ããã«ã¹ãã§ãã¯å
šäœãšããŠã¯DOWN
ãšãªã£ãããã§ãã
ã¢ããªã±ãŒã·ã§ã³åŽã§ã¯ããããªãã°ãåºåãããŠããŸãã
2022-05-14 22:38:08.806 INFO 26433 --- [xecutorLoop-1-4] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was /172.17.0.3:6379 2022-05-14 22:38:08.807 WARN 26433 --- [ioEventLoop-4-1] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [172.17.0.3/<unresolved>:6379]: æ¥ç¶ãæåŠãããŸãã: /172.17.0.3:6379 2022-05-14 22:38:14.606 INFO 26433 --- [xecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 172.17.0.3/<unresolved>:6379 2022-05-14 22:38:14.607 WARN 26433 --- [ioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [172.17.0.3/<unresolved>:6379]: æ¥ç¶ãæåŠãããŸãã: /172.17.0.3:6379
ãšããã§ãSpring Data Redisã®èšå®ã§ã¿ã€ã ã¢ãŠããèšå®ããŠããã®ã¯ããªã«ãæå®ããªããšã¬ã¹ãã³ã¹ãè¿ã£ãŠãããŸã§ã«ãšãŠã
æéããããããã§ããâŠã
ãã ãããã ãšã¬ã¹ãã³ã¹ããã¯ãªã«ãèµ·ãã£ãŠããã®ãããããŸãããsrc/main/resources/application.properties
ã«ä»¥äžãè¿œå ããŠ
ã¿ãŸãããã
management.endpoint.health.show-details=always
ããã±ãŒãžã³ã°ããŠãå床起åã
$ mvn package $ java -jar target/actuator-healthcheck-with-datastore-0.0.1-SNAPSHOT.jar
Redisãèµ·åããŠãããŸãã
確èªãããšããããªçµæã«ãªããŸããã
$ curl -i localhost:8080/actuator/health HTTP/1.1 200 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 13:47:55 GMT {"status":"UP","components":{"db":{"status":"UP","details":{"database":"MySQL","validationQuery":"isValid()"}},"diskSpace":{"status":"UP","details":{"total":100000000000,"free":10000000000,"threshold":10485760,"exists":true}},"ping":{"status":"UP"},"redis":{"status":"UP","details":{"version":"7.0.0"}}}}
ã¡ãã£ãšãããã¥ããã®ã§ãjq
ã§èŠãŠã¿ãŸãããã
$ curl -s localhost:8080/actuator/health | jq { "status": "UP", "components": { "db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "isValid()" } }, "diskSpace": { "status": "UP", "details": { "total": 100000000000, "free": 10000000000, "threshold": 10485760, "exists": true } }, "ping": { "status": "UP" }, "redis": { "status": "UP", "details": { "version": "7.0.0" } } } }
db
ãdiskSpace
ãping
ãredis
ã®4ã€ã§æ§æãããŠããããšãããããŸããping
ã¯ãåžžã«UP
ãè¿ãHealthIndicator
ã§ããã
ãã£ã¹ã¯ã®æ å ±ã¯ä»åã¯ãããŠãããŸããããç¡å¹ã«ããŸãã
management.health.diskspace.enabled=false
å床ããã±ãŒãžã³ã°ããŠèµ·åã
$ mvn package $ java -jar target/actuator-healthcheck-with-datastore-0.0.1-SNAPSHOT.jar
確èªããã£ã¹ã¯ã®æ å ±ããªããªããŸããã
$ curl -s localhost:8080/actuator/health | jq { "status": "UP", "components": { "db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "isValid()" } }, "ping": { "status": "UP" }, "redis": { "status": "UP", "details": { "version": "7.0.0" } } } }
ããã§ãRedisãåæ¢ããŠã¢ã¯ã»ã¹ããŠã¿ãŸãã
$ curl -i localhost:8080/actuator/health HTTP/1.1 503 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 13:52:30 GMT Connection: close {"status":"DOWN","components":{"db":{"status":"UP","details":{"database":"MySQL","validationQuery":"isValid()"}},"ping":{"status":"UP"},"redis":{"status":"DOWN","details":{"error":"org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 3 second(s)"}}}} $ curl -s localhost:8080/actuator/health | jq { "status": "DOWN", "components": { "db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "isValid()" } }, "ping": { "status": "UP" }, "redis": { "status": "DOWN", "details": { "error": "org.springframework.dao.QueryTimeoutException: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 3 second(s)" } } } }
åæ§æèŠçŽ ã®ãã¡ãRedisã ããDOWN
ã«ãªã£ãŠããããšãããããŸããerror
ã«ã¯å€±æããæã®äŸå€ã¡ãã»ãŒãžãå
¥ã£ãŠããŸããã
Status
ã®ãœãŒãé ã¯ããã®çµæããã¯ããããªãããã§ãã
ããã§ãããã«Redisããã«ã¹ãã§ãã¯ã®å¯Ÿè±¡ããå€ããŠã¿ãŸãããã
management.health.redis.enabled=false
ããã±ãŒãžã³ã°ããŠèµ·åãRedisã¯åæ¢ãããŸãŸã§ãã
$ mvn package $ java -jar target/actuator-healthcheck-with-datastore-0.0.1-SNAPSHOT.jar
ãããšããã«ã¹ãã§ãã¯ãæ£åžžã«çµäºããããã«ãªããŸãã
$ curl -i localhost:8080/actuator/health HTTP/1.1 200 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 13:55:13 GMT {"status":"UP","components":{"db":{"status":"UP","details":{"database":"MySQL","validationQuery":"isValid()"}},"ping":{"status":"UP"}}} $ curl -s localhost:8080/actuator/health | jq { "status": "UP", "components": { "db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "isValid()" } }, "ping": { "status": "UP" } } }
åœç¶ã§ãããRedisã«ã¢ã¯ã»ã¹ããæ©èœã䜿çšãããšå€±æããŸãã
$ curl localhost:8080/datastore/redis {"timestamp":"2022-05-14T13:56:27.308+00:00","status":500,"error":"Internal Server Error","path":"/datastore/redis"}
Redisã®ãã«ã¹ãã§ãã¯ã¯ãå床æå¹ã«ããŠãããŸãããã
#management.health.redis.enabled=false
ã¡ãªã¿ã«ãMySQLã ããåæ¢ããå Žåã¯ãããªããŸããã
$ curl -i localhost:8080/actuator/health HTTP/1.1 503 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 15:38:57 GMT Connection: close {"status":"DOWN","components":{"db":{"status":"DOWN","details":{"error":"org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure\n\nThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server."}},"ping":{"status":"UP"},"redis":{"status":"UP","details":{"version":"7.0.0"}}}} $ curl -s localhost:8080/actuator/health | jq { "status": "DOWN", "components": { "db": { "status": "DOWN", "details": { "error": "org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure\n\nThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server." } }, "ping": { "status": "UP" }, "redis": { "status": "UP", "details": { "version": "7.0.0" } } } }
DataSourceãRedisã§è¡ããã«ã¹ãã§ãã¯ã®å 容ã確èªããŠã¿ã
ãšããã§ãDataSourceãšRedisã®HealthIndicator
ã¯ãªã«ã確èªããŠãããã§ããããïŒ
ã¡ãã£ãšèŠãŠã¿ãŸãããã
ãŸãã¯ããã«ã¹ãã§ãã¯ã®ã¬ã¹ãã³ã¹ã®å 容ããã1床èŠãŠã¿ãŸãã
{ "status": "UP", "components": { "db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "isValid()" } }, "ping": { "status": "UP" }, "redis": { "status": "UP", "details": { "version": "7.0.0" } } } }
db
ã®å Žåã¯validationQuery
ãredis
ã®å Žåã¯version
ãã¡ãã£ãšäžæè°ãªæããããŸããã
db
ã«å²ãåœãŠãããŠããDataSourceHealthIndicator
ã®å Žåã¯ãããªããŒã·ã§ã³çšã®ã¯ãšãªãŒãèšå®ãããŠããã°ãã¡ãã䜿ãã
ããã§ãªããã°JDBCãã©ã€ããŒã®Connection#isValid
ã¡ãœããã䜿ãããã§ãã
Connection#isValid(int timeout))
ã€ãŸãããã®ç¶æ
ã®validQuery
ãšããã®ã¯Connection#isValid
ã§ãã«ã¹ãã§ãã¯ãè¡ã£ãŠããããšã瀺ããŠããŸãã
"db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "isValid()" } },
redis
ã«å²ãåœãŠãããŠããRedisHealthIndicator
ã®å Žåã¯ãRedisãã¯ã©ã¹ã¿ãŒæ§æãã©ããã§å€ããããã§ããä»åã¯ã¹ã¿ã³ãã¢ãã³ã§ããã
ã¹ã¿ã³ãã¢ãã³ã®Redisã€ã³ã¹ã¿ã³ã¹ã®å Žåã¯ãRedisã®info
ã³ãã³ãã®redis_version
ããããã£ãè¿ãããã«ãªã£ãŠããŸãã
ããããã¡ãã§ããã
"redis": { "status": "UP", "details": { "version": "7.0.0" } }
ã¡ãªã¿ã«ãControllerã§ãåãããšããã£ãŠããŸããã
@GetMapping("redis") public String redis() { return redisTemplate .getRequiredConnectionFactory() .getConnection() .serverCommands() .info() .getProperty("redis_version"); }
redis-cli
ã§ç¢ºèªãããšããããªæãã«ãªããŸãã
$ bin/redis-cli -a redispass info server | grep redis_version Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. redis_version:7.0.0
æåŸã«ãDataSourceHealthIndicator
ã§äœ¿ãvalidationQuery
ãèšå®ããŠã¿ãŸãããã
Spring Bootã¯ã³ãã¯ã·ã§ã³ããŒã«ã«HikariCPã䜿ãããã«ãªã£ãŠãããããspring.datasource.hikari.connection-test-query
ãæå®ããŸãã
spring.datasource.hikari.connection-test-query=select now()
ã¡ãªã¿ã«ãHikariCPã®connectionTestQuery
ã§ãããJDBC version 4以éã䜿ã£ãŠããå Žåã¯äœ¿ããªãããšã匷ãæšå¥šãããŠããŸãã
If your driver supports JDBC4 we strongly recommend not setting this property.
Connection#isValid
ããµããŒãããŠããªãã¬ã¬ã·ãŒãªç°å¢åãã®ãã®ã§ãã
This is for "legacy" drivers that do not support the JDBC4 Connection.isValid() API.
ã€ãŸãããµã ã䜿ãæã¯spring.datasource.hikari.connection-test-query
ãèšå®ããªãããã«ããŠãããŸãããã
ããã±ãŒãžã³ã°ããŠèµ·åã
$ mvn package $ java -jar target/actuator-healthcheck-with-datastore-0.0.1-SNAPSHOT.jar
確èªã
$ curl -i localhost:8080/actuator/health HTTP/1.1 200 Content-Type: application/vnd.spring-boot.actuator.v3+json Transfer-Encoding: chunked Date: Sat, 14 May 2022 15:47:13 GMT {"status":"UP","components":{"db":{"status":"UP","details":{"database":"MySQL","validationQuery":"select now()","result":"2022-05-14T15:47:13"}},"ping":{"status":"UP"},"redis":{"status":"UP","details":{"version":"7.0.0"}}}} $ curl -s localhost:8080/actuator/health | jq { "status": "UP", "components": { "db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "select now()", "result": "2022-05-14T15:47:31" } }, "ping": { "status": "UP" }, "redis": { "status": "UP", "details": { "version": "7.0.0" } } } }
validationQuery
ã®å
容ãå€ãããã¯ãšãªãŒã®çµæãŸã§å
¥ãããã«ãªããŸããã
"db": { "status": "UP", "details": { "database": "MySQL", "validationQuery": "select now()", "result": "2022-05-14T15:47:31" } },
ããã§ã確èªOKãšããŸãããã
ãŸãšã
Spring Boot Actuatorã§ãããŒã¿ã¹ãã¢ãŸã§å«ãã ãã«ã¹ãã§ãã¯ãè¡ã£ãŠã¿ãŸããã
ãªããšãªãããããæ©èœããããã¡ãã£ãšèå³ããã£ãã®ã§ãã®æ©äŒã«è©ŠããŠãããŠããã£ãã§ãã
æåŸã«ãapplication.properties
ã®ã³ã¡ã³ãã¢ãŠãããŠããå
容ãå«ããŠãå
šäœã貌ã£ãŠãããŸãã
â» management.health.defaults.enabled
ã¯ãããã©ã«ãã§æå¹ãªAuto ConfigurationãããHealthIndicator
ããã¹ãŠç¡å¹ã«ããããããã£ã§ã
src/main/resources/application.properties
spring.datasource.url=jdbc:mysql://172.17.0.2:3306/practice?characterEncoding=utf-8 spring.datasource.username=kazuhira spring.datasource.password=password #spring.datasource.hikari.connection-test-query=select now() spring.redis.url=redis://redispass@172.17.0.3:6379 spring.redis.connect-timeout=3s spring.redis.timeout=3s management.endpoint.health.show-details=always management.health.diskspace.enabled=false #management.health.db.enabled=false #management.health.ping.enabled=false #management.health.redis.enabled=false #management.health.defaults.enabled=false