<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.bolingcavalry</groupId>
<artifactId>springboot-app-docker-health-check</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-app-docker-health-check</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</
dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>1.7.0</version>
<configuration>
<image>bolingcavalry/jdk8-healthcheck:0.0.1</image>
</from>
<image>bolingcavalry/${project.artifactId}:${project.version}</image>
<container>
<jvmFlags>
<jvmFlag>-Xms1g</jvmFlag>
<jvmFlag>-Xmx1g</jvmFlag>
</jvmFlags>
<ports>
<port>8080</port>
</ports>
<useCurrentTimestamp>true</useCurrentTimestamp>
</container>
</configuration>
</plugin>
</plugins>
</build>
</project>
上述pom.xml有以下几处需要注意:
a. 使用jib插件来将当前工程构建成docker镜像;
b. 基础镜像是前面构建的bolingcavalry/jdk8-healthcheck:0.0.1,以此为基础镜像的镜像都带有健康检查功能;
- 主要功能类是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 = "/hello", method = RequestMethod.GET)
public ResponseEntity<String> 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<String> 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,表示容器不健康;
3. 在pom.xml文件所在目录执行mvn clean compile -U -DskipTests jib:dockerBuild,即可将当前工程构建为镜像,名为bolingcavalry/springboot-app-docker-health-check:0.0.1-SNAPSHOT
4. 至此,支持容器健康检查的Java应用镜像构建成功,接下来验证容器的健康检查功能是否正常;
验证的步骤如下:
a. 让应用容器正常工作,确保文件/app/depend/abc.txt是正常的,此时容器状态应该是healthy
b. 将文件/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/depend \
bolingcavalry/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环境配置容器健康检查的实战就完成了,希望您在给自己的应用添加健康检查时,此文能给您一些参考。
摘要:自动构建是美团对Docker的首次应用。解决方案可以概括为三点:把构建过程放到Docker容器;提交代码时自动触发构建;发布时直接使用构建好的应用包。方案很好地解决了三个问题:资源竞争、环境冲突和安全隐患。自动构建系统是从美团的自动部署系统发展出来的一个新功能。每当开发人员提交代码到仓库后,系统会自动根据开发人员定制的构建配置,启动新的Docker容器,在其中对源代码进行构建(build),包括编译(如Java、C++和Go)、预处理(如JavaScript和CSS)、压缩(如图片)等操作,生成最终需要上线的程序包。
美团的代码自动部署
健康检查机制是用来检查服务的可用性,当服务不可用时及时重启以恢复可用性。之前的文章《Kubernetes中配置livenessProbe、readinessProbe和startupProbe》讲解了Kubernetes中的各种健康检查类型和配置方法,本篇文章讲解一下docker容器的健康检查机制。看过上文提到的那篇文章的同学型相信肯定能理解为什么需要对服务本身做健康检查。
容器使用沙箱机制,互相隔离,优势在于让各个部署在容器的里的应用互不影响,独立运行,提供更高的安全性。本文主要介绍python应用(django)跑在docker容器里,编写dockerfile实现镜像构建自动化以及docker神器compose。
二、编写Dockerfile文件
官网下载的python镜像比较精简,web应用相关依赖还是需要自己安装的。编写Dockerfile,可以让你构建镜像的时候自动化。实例如下:
FROM python:3.6.4
RUN mkdir /code \
&&apt-get update \
&&apt-get -y install free
目前docker官方并没有提供标准的Java api,只有Go与Python语言的,其他语言都是用户自己实现。Java的api官方推荐了三个,分别是docker-java、docker-java-api、jocker,官方链接如下。本人使用的是docker-java-api,尝试过docker-client个人感觉封装度不高正如docker-java-api中说的一样:与其他用于 Java 的 docker 客户端不同,这个客户端的目标是尽可能轻量级,尽可能少地传递依赖,并且绝对不会导致与其他框架或平
docker环境中,应用容器还在,但已无法提供服务(例如数据或文件被破坏,线程池等资源被耗尽等各种异常),此时需要一种方式快速得知这种状态,此时容器健康检查(即HEALTHCHECK)就派上用场了,一起来体验这个重要的功能。
在《极速体验docker容器健康》一文已体验了docker容器健康检查功能,今天就来给java应用的容器加入健康检查,使应用的状态随时都可以被监控和查看。实战环境信息操作系统:macOS Catalina 10.15Docker:19.03.2java应用简介今天实战的java应用,是用来模拟生产环境应用的,特点如下:普通springboot应用,对外提供http服务,路径:/hellosprin...
摘要: 在分布式系统中,经常需要利用健康检查机制来检查服务的可用性,防止其他服务调用时出现异常。自 1.12 版本之后,Docker 引入了原生的健康检查实现。本文将介绍Docker容器健康检查机制,以及在Docker Swarm mode下面的新特性
在分布式系统中,经常需要利用健康检查机制来检查服务的可用性,防止其他服务调用时出现异常。
对于容器而言,最简单的健康检查是进程级的健...
Docker Daemon 会自动监控容器中的 PID1 进程,如果 docker run 命令中指明了 restart policy,可以根据策略自动重启已结束的容器。指令的 Dockerfile 构建出来的镜像,在实例化 Docker 容器的时候,就具备了健康状态检查的功能。指令声明了健康检测命令,用这个命令来判断容器主进程的服务状态是否正常,从而比较真实的反应容器实际状态。如果是以 supervisor 来管理容器的多个服务,想通过子服务的状态来判断容器的监控状态,可以使用。...
之前在论坛上发过一个求助贴:
求助,我参考github项目xxproject做容器化部署,中间有双eureka高可用,但是eureka始终处于health:starting状态,从浏览器能访问到eureka控制台,证明已经启动,但容器状态就是不变成healthy,打日志发现eureka除了一直在同步状态外,没有任何异常。
1容器健康状态转化的机制和标志
2针对我遇到...
docker容器的健康检测是在编写dockerfile时,将检测机制写入到dockerfile中,基于此docerfile生成的镜像,在运行容器时会有健康检测的功能。
dockerfile中的格式:
HEALTHCHECK [选项] CMD <命令>:设置检查容器健康状况的命令。
HEALTHCHECK NONE:如果基础镜像有健康检查指令,使用这行可以屏蔽掉其健康检查指令。
Dockerfile中使用HEALTHCHECK的形式有两种:
1、HEALTHCHECK [options] CMD command(本次详细解释)
2、HEALTHCHECK NODE 意思是禁止从父镜像继承的HEALTHCHECK生效
下面我们主要介绍第一种形式的应用:
options有三个参数可设定:
interval:间隔(s秒、m分钟、h小时),从容器运行起来开始计时interv
容器的状态是 Up ,应用就是健康的吗?
其实即使容器状态是 Up ,也不能保证应用没有问题。比如当我们在 docker-compose 文件里面设置了 restart: always 时候,当容器崩溃的时候,docker 守护进程会重启容器。但是,如果容器的确在运行,但是容器里的应用不可用怎么办(比如容器里的 we...