當spring-boot 打包 docker 鏡像 , 父鏡像中沒有 curl 時 ,此時還想使用 actuator/health 做 healthcheck 的問題
在打包鏡像時,將一個java 類複製到鏡像中 **dockerfile **
FROM gcr.io/distroless/java:11
COPY target/*.jar app.jar
COPY HealthCheck.java .
EXPOSE 8080
CMD ["app.jar"]
HEALTHCHECK --interval=25s --timeout=3s --retries=2 CMD ["java", "HealthCheck.java", "||", "exit", "1"]
HealthCheck.java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse.BodyHandlers;
import java.util.Objects;
/**
* 健康監測
*/
public class HealthCheck {
public static void main(String[] args) throws IOException, InterruptedException {
String port = Objects.requireNonNullElse(System.getProperty("port"),"8080");
String path = Objects.requireNonNullElse(System.getProperty("path"), "/actuator/health");
String schemas = Objects.requireNonNullElse(System.getProperty("schemas"), "http");
String url = System.getProperty("url");
if(url==null || url.isBlank()){
url = schemas + "://localhost:" + port + path;
}
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("accept", "application/json")
.build();
var response = client.send(request, BodyHandlers.ofString());
String body = response.body();
if (response.statusCode() != 200) {
throw new RuntimeException("Healthcheck failed "+body);
}
if (body.contains("\"status\":\"DOWN\"")) {
throw new RuntimeException("Healthcheck failed "+body);
}
}
}
參考: https://naiyer.dev/post/2021/03/01/java-based-health-check-for-docker/