springboot实战电商我的项目mall4j (https://gitee.com/gz-yami/mall4j)
java商城零碎源码
以下探讨基于Docker Compose的V2版本:
当初容器编排应用宽泛,大家都在用docker-compose进行网站部署,在部署的过程中,会应用到Mysql,Redis,JAVA后端程序,PHP后端程序之类的,会波及到一个程序的启动先后问题,个别的解决方案都是在Compose文件中,增加depends_on参数,例如:
version: "2.4"
services:
xxl-job-mysql:
container_name: xxl-job-mysql
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123456
image: mysql:5.7
networks:
xxl-job-network:
ipv4_address: 192.168.189.2
ports:
- 3306:3306
restart: always
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/initdb:/docker-entrypoint-initdb.d
xxl-job-admin:
container_name: xxl-job-admin
environment:
- PARAMS=--spring.datasource.url=jdbc:mysql://xxl-job-mysql:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=123456 \
--xxl.job.accessToken=
image: xuxueli/xxl-job-admin:2.3.0
networks:
xxl-job-network:
ipv4_address: 192.168.189.3
ports:
- 8080:8080
restart: always
# 依赖于数据库,先启动数据库再启动JAVA程序
depends_on:
- xxl-job-mysql
networks:
xxl-job-network:
driver: bridge
ipam:
config:
- subnet: 192.168.189.0/24
name: xxl-job-network
以上编排文件如同看起来没什么问题,但理论执行的时候,在数据库启动后,因为depends_on参数,会在启动数据库后马上启动JAVA程序。不论Mysql是否曾经启动实现。这时候就可能呈现数据库还没启动好,JAVA程序就曾经启动实现,并尝试去连贯数据库,造成连贯失败,JAVA程序报错。所以说,depends_on并没有真正的期待上一个程序启动实现。这个在docker官网文档也有阐明:https://docs.docker.com/compo…
外面有一句”However, for startup Compose does not wait until a container is “ready” (whatever that means for your particular application) – only until it’s running. There’s a good reason for this.”
所以,官网举荐了一些TCP检测的小工具,用于检测程序端口是否畅通,一旦畅通代表程序曾经启动实现。
上面,咱们来应用wait-for-it小工具:https://github.com/vishnubob/… 来检测数据库是否曾经启动实现
xxl-job-admin的java程序的dockerfile内容如下:
FROM openjdk:8-jre-slim
MAINTAINER xuxueli
ENV PARAMS=""
ENV TZ=PRC
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD target/xxl-job-admin-*.jar /app.jar
ENTRYPOINT ["sh","-c","java -jar $JAVA_OPTS /app.jar $PARAMS"]
xxl-job-admin:
container_name: xxl-job-admin
environment:
- PARAMS=--spring.datasource.url=jdbc:mysql://xxl-job-mysql:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=123456 \
--xxl.job.accessToken=
image: xuxueli/xxl-job-admin:2.3.0
networks:
xxl-job-network:
ipv4_address: 192.168.189.3
ports:
- 8080:8080
restart: always
# 依赖于数据库,先启动数据库再启动JAVA程序
depends_on:
- xxl-job-mysql
volumes:
# 把wait-for-it脚本挂载到容器内根目录,
# 因为查看xxl-job-admin的dockerfile得悉app.jar也在根目录,所以放在同一个目录下
- ./wait-for-it.sh:/wait-for-it.sh
# 应用command命令,先执行wait-for-it期待数据库启动实现,而后执行java -jar app.jar
command: ["/wait-for-it.sh", "xxl-job-mysql:3306", "--", "sh", "-c", "java -jar $JAVA_OPTS /app.jar $PARAMS"]
残缺代码如下:
version: "2.4"
services:
xxl-job-mysql:
container_name: xxl-job-mysql
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123456
image: mysql:5.7
networks:
xxl-job-network:
ipv4_address: 192.168.189.2
ports:
- 3306:3306
restart: always
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/initdb:/docker-entrypoint-initdb.d
xxl-job-admin:
container_name: xxl-job-admin
environment:
- PARAMS=--spring.datasource.url=jdbc:mysql://xxl-job-mysql:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=123456 \
--xxl.job.accessToken=
image: xuxueli/xxl-job-admin:2.3.0
networks:
xxl-job-network:
ipv4_address: 192.168.189.3
ports:
- 8080:8080
restart: always
# 依赖于数据库,先启动数据库再启动JAVA程序
depends_on:
- xxl-job-mysql
volumes:
# 把wait-for-it脚本挂载到容器内根目录,
# 因为查看xxl-job-admin的dockerfile得悉app.jar也在根目录,所以放在同一个目录下
- ./wait-for-it.sh:/wait-for-it.sh
# 应用command命令,先执行wait-for-it期待数据库启动实现,而后执行java -jar app.jar
command: ["/wait-for-it.sh", "xxl-job-mysql:3306", "--", "sh", "-c", "java -jar $JAVA_OPTS /app.jar $PARAMS"]
networks:
xxl-job-network:
driver: bridge
ipam:
config:
- subnet: 192.168.189.0/24
name: xxl-job-network
除了官网举荐的TCP检测的小工具以外,官网还提供了一个办法,healthcheck,衰弱检测,文档连贯:https://docs.docker.com/engin…
依据文档意思,咱们增加healthcheck参数,代码如下:
xxl-job-admin:
# 减少healthcheck参数:执行'mysqladmin ping -h localhost'命令
# 执行工夫设定为10秒,超时时常设定为20秒,重试次数为10次,如果能ping通,阐明数据库启动实现
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
interval: 10s
timeout: 20s
retries: 10
xxl-job-mysql:
depends_on:
xxl-job-mysql:
# java容器在mysql容器状态为衰弱前不会启动
condition: service_healthy
残缺代码如下:
version: "2.4"
services:
xxl-job-mysql:
container_name: xxl-job-mysql
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123456
image: mysql:5.7
networks:
xxl-job-network:
ipv4_address: 192.168.189.2
ports:
- 3306:3306
restart: always
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/initdb:/docker-entrypoint-initdb.d
# 减少healthcheck参数:执行'mysqladmin ping -h localhost'命令
# 执行工夫设定为10秒,超时时常设定为20秒,重试次数为10次,如果能ping通,阐明数据库启动实现
healthcheck:
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
interval: 10s
timeout: 20s
retries: 10
xxl-job-admin:
container_name: xxl-job-admin
environment:
- PARAMS=--spring.datasource.url=jdbc:mysql://xxl-job-mysql:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=123456 \
--xxl.job.accessToken=
image: xuxueli/xxl-job-admin:2.3.0
networks:
xxl-job-network:
ipv4_address: 192.168.189.3
ports:
- 8080:8080
restart: always
depends_on:
xxl-job-mysql:
# java容器在mysql容器状态为衰弱前不会启动,须要留神的是:ondition: service_healthy,在V3版本的Compose中已废除
condition: service_healthy
networks:
xxl-job-network:
driver: bridge
ipam:
config:
- subnet: 192.168.189.0/24
name: xxl-job-network
那么,到此为止,问题是否曾经解决了呢?然而,只是解决了一部分,因为在Mysql的启动脚本中,有一段命令,启动时会检测/docker-entrypoint-initdb.d文件夹中是否存在初始化sql脚本,如果存在,就会在第一次启动时执行sql,对数据库进行初始化,链接如下:https://github.com/docker-lib… 如果初始化脚本很大,就会呈现一种状况,mysql的3306端口曾经能够ping通,但sql还在执行中,app容器就认为他曾经启动实现,从而进行数据库连贯,所以,咱们须要针对检测形式进行改良一下:将mysqladmin ping -h localhost替换成/usr/bin/mysql –user=root –password=123456 –execute “SHOW DATABASE;”
代码如下:
xxl-job-mysql:
container_name: xxl-job-mysql
environment:
- TZ=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123456
image: mysql:5.7
networks:
xxl-job-network:
ipv4_address: 192.168.189.2
ports:
- 3306:3306
restart: always
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/initdb:/docker-entrypoint-initdb.d
# 减少healthcheck参数:执行'/usr/bin/mysql --user=root --password=123456 --execute "SHOW DATABASES;"'命令
# 执行工夫设定为10秒,超时时常设定为20秒,重试次数为10次,如果数据库能登陆并且能够查问时,阐明数据库启动实现
healthcheck:
# 只有真正能执行查问命令,才算启动实现
test: '/usr/bin/mysql --user=root --password=123456 --execute "SHOW DATABASES;"'
interval: 10s
timeout: 20s
retries: 10
总结:
1,只存在depends_on时肯定是不牢靠的
2,当初始化脚本比拟大时,能ping通不肯定代表数据库初始化实现
3, 当数据库能登陆并且能够查问时,才算真正的启动实现
springboot实战电商我的项目mall4j (https://gitee.com/gz-yami/mall4j)
java商城零碎源码
发表回复