Java应用在docker环境配置容器健康检查( 二 )


主要功能类是SpringbootAppDockerHealthCheckApplication.java: package com.bolingcavalry.springbootappdockerhealthcheck; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import java.io.*; import java.util.List; @SpringBootApplication @RestController @Slf4j public class SpringbootAppDockerHealthCheckApplication { public static void main(String[] args) { SpringApplication.run(SpringbootAppDockerHealthCheckApplication.class, args); } /** * 读取本地文本文件的内容并返回 * @return */ private String getLocalFileContent() { String content = null; try{ InputStream is = new FileInputStream("/app/depend/abc.txt"); List<String> lines = IOUtils.readLines(is, "UTF-8"); if(null!=lines && lines.size()>0){ content = lines.get(0); } } catch (FileNotFoundException e) { log.error("local file not found", e); } catch (IOException e) { log.error("io exception", e); } return content; } /** * 对外提供的http服务 , 读取本地的txt文件将内容返回 ,  * 如果读取不到内容返回码为403 * @return */ @RequestMapping(value = https://www.isolves.com/it/cxkf/rongqi/2019-10-22/"/hello", method = RequestMethod.GET) public ResponseEntity hello(){ String localFileContent = getLocalFileContent(); if(StringUtils.isEmpty(localFileContent)) { log.error("hello service error"); return ResponseEntity.status(403).build(); } else { log.info("hello service success"); return ResponseEntity.status(200).body(localFileContent); } } /** * 该http服务返回当前应用是否正常 , * 如果能从本地txt文件成功读取内容 , 当前应用就算正常 , 返回码为200 , * 如果无法从本地txt文件成功读取内容 , 当前应用就算异常 , 返回码为403 * @return */ @RequestMapping(value = "/getstate", method = RequestMethod.GET) public ResponseEntity getstate(){ String localFileContent = getLocalFileContent(); if(StringUtils.isEmpty(localFileContent)) { log.error("service is unhealthy"); return ResponseEntity.status(403).build(); } else { log.info("service is healthy"); return ResponseEntity.status(200).build(); } } }复制代码上述代码有以下几处需要注意:a. hello方法是此应用对外提供的服务 , 如果本地文件abc.txt存在且内容不为空 , hello方法的返回码就是200 , 否则返回码为403 , 表示当前服务出现异常;b. getstate方法是新增的服务 , 该接口会被docke-daemon调用 , 如果返回码是200 , 就表示容器健康 , 如果返回码是403 , 表示容器不健康;
在pom.xml文件所在目录执行mvn clean compile -U -DskipTests jib:dockerBuild , 即可将当前工程构建为镜像 , 名为bolingcavalry/springboot-app-docker-health-check:0.0.1-SNAPSHOT 至此 , 支持容器健康检查的Java应用镜像构建成功 , 接下来验证容器的健康检查功能是否正常; 验证步骤验证的步骤如下:a. 让应用容器正常工作 , 确保文件/app/depend/abc.txt是正常的 , 此时容器状态应该是healthyb. 将文件/app/depend/abc.txt删除 , 此时应用hello接口返回码为403 , 并且容器状态变为unhealthy
验证操作 创建文件abc.txt , 完整路径是/Users/zhaoqin/temp/201910/20/abc.txt , 文件内容是个字符串 , 例如:123456 执行以下命令 , 用新建的java应用镜像创建容器 , 该容器会将test文件夹映射到容器的/app/depend文件夹: docker run --rm--name=java-health-check-p 8080:8080-v /Users/zhaoqin/temp/201910/20:/app/dependbolingcavalry/springboot-app-docker-health-check:0.0.1-SNAPSHOT复制代码 控制台可见以下输出 , 表明健康检查接口已经被调用: 2019-10-20 14:16:34.875 INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' 2019-10-20 14:16:34.876 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 2019-10-20 14:16:34.892 INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 16 ms 2019-10-20 14:16:34.959 INFO 1 --- [nio-8080-exec-1] pringbootAppDockerHealthCheckApplication : service is healthy 2019-10-20 14:16:40.159 INFO 1 --- [nio-8080-exec-2] pringbootAppDockerHealthCheckApplication : service is healthy 2019-10-20 14:16:45.356 INFO 1 --- [nio-8080-exec-4] pringbootAppDockerHealthCheckApplication : service is healthy 2019-10-20 14:16:50.580 INFO 1 --- [nio-8080-exec-6] pringbootAppDockerHealthCheckApplication : service is healthy复制代码 执行命令docker ps查看容器状态 , 可见已经是healthy: (base) zhaoqindeMBP:20 zhaoqin$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 51572d2488fb bolingcavalry/springboot-app-docker-health-check:0.0.1-SNAPSHOT "java -Xms1g -Xmx1g …" About a minute ago Up About a minute (healthy) 0.0.0.0:8080->8080/tcp java-health-check复制代码 删除宿主机上的/Users/zhaoqin/temp/201910/20/abc.txt , 相当于容器内的abc.txt文件被删除 , 此时控制台可见健康检查接口在被调用时发现文件不存在 , 已返回了403错误码: 019-10-20 14:22:37.490 ERROR 1 --- [nio-8080-exec-7] pringbootAppDockerHealthCheckApplication : service is unhealthy复制代码 健康检查接口被连续10次调用后 , 再执行命令docker ps查看容器状态 , 可见已经是unhealthy: (base) zhaoqindeMBP:20 zhaoqin$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 51572d2488fb bolingcavalry/springboot-app-docker-health-check:0.0.1-SNAPSHOT "java -Xms1g -Xmx1g …" 7 minutes ago Up 7 minutes (unhealthy) 0.0.0.0:8080->8080/tcp java-health-check复制代码至此 , Java应用在docker环境配置容器健康检查的实战就完成了 , 希望您在给自己的应用添加健康检查时 , 此文能给您一些参考 。


推荐阅读