Shell脚本控制docker容器启动顺序
1.遇到的问题
在分布式项目部署的过程中,经常要求服务器重启之后,应用(包括数据库)能够自动恢复使用.虽然使用docker update --restart=always containerid能够让容器自动随docker启动,但是并不能保证是在数据库启动之后启动,如果数据库未启动,那么将导致应用启动失败;网上还有一种解决方法是通过docker-compose容器编排来控制启动顺序,这个博主研究的比较少.
2.解决思路
使用Shell脚本来控制,思路大致如下
- 探测数据库端口来检验数据库是否启动成功.
- 数据库启动成功后,探测配置中心及服务注册中心的端口来检验其是否启动成功.
- 当数据库及配置中心都启动之后,再启动其他微服务应用.
3.端口探测
端口探测使用的命令是
nc -w 1 host port </dev/null && echo "200"
host:目标主机的ip
port:服务监听的端口
如果服务启动了 这条命令会返回 200,未启动则返回空.
4.Shell脚本
直接贴代码了,使用的配置中心是nacos
#!/bin/bash
#chkconfig: 2345 80 90
#description:autoStartMaintenanceService.sh
#
#前提:
#1.docker必须能开机自启
#2.docker能够正常启动运维服务
#3.此脚本须运行微服务所在的机器上
#
##需要修改的配置-----开始
##数据库所在的机器IP
DATABASE_HOST=192.169.1.52
##数据库监听的端口
DATABASE_PORT=3306
##微服务所在机器IP
LOCAL_HOST=192.169.1.46
##微服务访问端口
Maintenance_Port=8180
##NACOS所在机器的ip
NACOS_HOST=192.169.1.82
##NACOS的监听端口
NACOS_PORT=8848
##微服务容器名称(NAMES列)
Maintenance_Container_Name="umc-maintenance"
##该脚本生成的日志路径
Log_Path=/home/test/log
##需要修改的配置-----结束
##
##循环延时时间(s)秒
LOOP_TIME=5
at_time=""
at_date=""
getAtTime() {
at_time="$(date +%Y-%m-%d-%H:%M:%S) --- "
at_date=$(date +%Y-%m-%d)
}
autoStartWebService() {
##如果日志路径不存在则创建
if [ ! -d "$Log_Path" ]; then
mkdir -p $Log_Path
fi
while true; do
##判断数据库是否启动
req_message=$(nc -w 1 ${DATABASE_HOST} ${DATABASE_PORT} </dev/null && echo "200")
if [ -n "$req_message" ]; then
getAtTime
echo "$at_time Database is running" >>${Log_Path}/"$at_date"_autoStartMaintenanceService.log
waitNacosStarting
else
getAtTime
echo "$at_time Database is not running and please wait for Database starting" >>${Log_Path}/"$at_date"_autoStartMaintenanceService.log
sleep $LOOP_TIME
fi
done
}
##判断Nacos是否启动
waitNacosStarting() {
req_message=$(nc -w 1 ${NACOS_HOST} ${NACOS_PORT} </dev/null && echo "200")
if test $((req_message)) -eq 200; then
getAtTime
echo "$at_time Nacos is running" >>${Log_Path}/"$at_date"_autoStartMaintenanceService.log
startMaintenanceService
sleep $LOOP_TIME
else
getAtTime
echo "$at_time Nacos is not running and please wait for nacos starting" >>${Log_Path}/"$at_date"_autoStartMaintenanceService.log
sleep $LOOP_TIME
fi
}
##启动微服务
startMaintenanceService() {
req_message=$(nc -w 1 ${LOCAL_HOST} ${Maintenance_Port} </dev/null && echo "200")
if test $((req_message)) -eq 200; then
getAtTime
echo "$at_time Maintenance service is running" >>${Log_Path}/"$at_date"_autoStartMaintenanceService.log
else
container_id=$(docker ps -a | grep $Maintenance_Container_Name | grep -v grep | awk '{print $1}')
getAtTime
echo "$at_time Maintenance service container id is ${container_id}" >>${Log_Path}/"$at_date"_autoStartMaintenanceService.log
docker start ${container_id}
fi
}
autoStartWebService
5.Shell输入输出重定向
写这个脚本的时候,也让博主对Shell输入输出重定向更加熟悉
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:
- 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
- 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
- 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。
| 命令 | 说明 |
|---|---|
| command > file | 将输出重定向到 file且会覆盖file |
| command < file | 将输入重定向到 file |
| command >> file | 将输出以追加的方式重定向到file |
| command 2> file | 将错误输出到file且会覆盖file |
| command 2>> file | 将错误以追加的方式重定向到file |
| << tag | 将开始标记 tag 和结束标记 tag 之间的内容作为输入 |
如果希望将 stdout 和 stderr 合并后重定向到 file(即将正确信息和错误信息都输出到file),可以这样写:
command > file 2>&1
或者
command >> file 2>&1
/dev/null文件
/dev/null是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到禁止输出的效果
command > /dev/null 2>&1 可以屏蔽stdout和stderr
参考
Shell脚本控制docker容器启动顺序的更多相关文章
- shell 脚本控制命令的执行顺序
&&,||,(),{},& 五个符号的运用shell脚本执行命令的时候,有时候会依赖于前一个命令是否执行成功.而&&和||就是用来判断前一个命令执行效果的. 也 ...
- Docker容器启动时初始化Mysql数据库
1. 前言 Docker在开发中使用的越来越多了,最近搞了一个Spring Boot应用,为了方便部署将Mysql也放在Docker中运行.那么怎么初始化 SQL脚本以及数据呢? 我这里有两个传统方案 ...
- docker容器启动设置固定IP
docker安装以后的网络类型 [root@insure updev]# docker network ls NETWORK ID NAME DRIVER SCOPE 14da40175b01 bri ...
- Docker容器启动Mysql,Docker实现Mysql主从,读写分离
Docker容器启动Mysql,Docker实现Mysql主从,读写分离 一.Docker文件编排 二.配置主从复制 2.1 配置master 2.2 配置slave 三.验证主从复制 3.1 mas ...
- web容器启动顺序
web容器启动顺序: 第一:context-param 第二:Listerer 第三:Filter 第四:servlet
- docker容器启动几分钟之后自动退出
2018-11-06 问题: docker容器启动几分钟之后自动退出 log日志报错 WARNING: overlay2: the backing xfs filesystem is formatte ...
- 解决docker容器启动时候无法映射端口的问题
当我们停止防火墙后,docker容器启动映射端口可能无法映射端口,这个时候需要重建docker0网桥. 详细的错误是这样的: docker: Error response from daemon: d ...
- docker容器启动后添加端口映射
DOCKER 给运行中的容器添加映射端口 方法1 1.获得容器IP 将container_name 换成实际环境中的容器名 docker inspect `container_name` | grep ...
- Centos7 docker容器启动后添加端口映射
docker容器启动后添加端口映射的两种方法: 一.通过修改防火墙策略添加端口映射 docker容器已创建好,但是想在容器内配置tomcat监控,需要新的端口去访问,但是映射时没有映射多余端口,此时, ...
随机推荐
- Codeforces Round #550 (Div. 3) D. Equalize Them All (贪心,模拟)
题意:有一组数,可以选择某个数\(a_i\)相邻的一个数\(a_j\),然后可以让\(a_i\)加上或者减去\(|a_i-a_j|\),问最少操作多少次使得数组中所有数相同. 题解:不难发现,每次操作 ...
- C#中word导出功能骚操作
马上过牛年了,先祝大家新年好,身体好,心情好!!! 年前最后写一篇之前项目开发的一个功能,自己根据系统业务,想到的一个解决办法,效率还是不错的,废话不多说,开整!!! 需求:企业填报自己的企业信息到系 ...
- echart关系图平分节点删除时自动平衡问题
项目场景: 项目场景:Echarts关系图中(不是力图)一个节点x,y是固定的,为了同一列能居中显示,规定:当前列有奇数个元素新节点往下放,有偶数个节点时新节点往上放. 问题描述: 删除中间节点会有空 ...
- Kerberos原理经典对话
这是MIT(Massachusetts Institute of Technology)为了帮助人们理解Kerberos的原理而写的一篇对话集.里面有两个虚构的人物:Athena和Euripides, ...
- Java中多线程启动,为什么调用的是start方法,而不是run方法?
前言 大年初二,大家新年快乐,我又开始码字了.写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的ide ...
- TCP之“3次握手,4次挥手”问题——实例分析
上一篇我们分析了三次握手和四次握手的过程,但是理论分析难免枯燥难懂,下面这篇我们来看一个例子,就能更好地理解tcp链接了. 我们可以通过网络抓包的查看具体的流程: 比如我们服务器开启9502的端口.使 ...
- pyspark+anaconda配置
参考 https://www.e-learn.cn/content/python/786199 注意 所有的变量都放在环境变量而非用户变量.比如JAVA_HOME. 不然虽然pyspark没问题,但是 ...
- SPOJ LCS Longest Common Substring(后缀自动机)题解
题意: 求两个串的最大\(LCS\). 思路: 把第一个串建后缀自动机,第二个串跑后缀自动机,如果一个节点失配了,那么往父节点跑,期间更新答案即可. 代码: #include<set> # ...
- vue stop event bug
vue stop event bug [Vue warn]: Error in v-on handler: "TypeError: e.prevntDefault is not a func ...
- Flutter Hackathon 2020
Flutter Hackathon 2020 https://flutterhackathon.com/#/ Flutter Day https://mp.weixin.qq.com/s/ux17-A ...