CLOVER🍀

That was when it all began.

Spring Boot ActuatorでデヌタストアJDBC、Redisを含んだヘルスチェックを行う

これは、なにをしたくお曞いたもの

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.

Production-ready Features

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のようです。

https://github.com/spring-projects/spring-boot/blob/v2.6.7/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/health/SimpleStatusAggregator.java#L44-L49

぀たり、どれかひず぀でも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))

https://github.com/spring-projects/spring-boot/blob/v2.6.7/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java#L107-L118

https://github.com/spring-projects/spring-boot/blob/v2.6.7/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java#L134

぀たり、この状態のvalidQueryずいうのはConnection#isValidでヘルスチェックを行っおいるこずを瀺しおいたす。

    "db": {
      "status": "UP",
      "details": {
        "database": "MySQL",
        "validationQuery": "isValid()"
      }
    },

https://github.com/spring-projects/spring-boot/blob/v2.6.7/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/jdbc/DataSourceHealthIndicator.java#L115

redisに割り圓おられおいるRedisHealthIndicatorの堎合は、Redisがクラスタヌ構成かどうかで倉わるようです。今回はスタンドアロンですね。

https://github.com/spring-projects/spring-boot/blob/v2.6.7/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/redis/RedisHealthIndicator.java#L58-L64

スタンドアロンのRedisむンスタンスの堎合は、Redisのinfoコマンドのredis_versionプロパティを返すようになっおいたす。

https://github.com/spring-projects/spring-boot/blob/v2.6.7/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/redis/RedisHealth.java#L37

それがこちらですね。

    "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.

HikariCP / Configuration

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