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监控,需要新的端口去访问,但是映射时没有映射多余端口,此时, ...
随机推荐
- PowerShell随笔4---变量
全局变量 输入$global:后按ctrl+space,我们就可以看到所有的全局变量. 比如我们可以查看PowerShell的版本: 我们可以在在编写脚本代码的时候使用这些变量,globle可以省略, ...
- 一道思维题 &&递归改循环
思路: 比如5 2 12345--> 1245 从3开始,这时候5变成了1.剩下4512,对应1234.只需要找到现在n-1,k中的数对应原来的编号的映射. 比如1-->3 是1+2 mo ...
- MS16-032 windows本地提权
试用系统:Tested on x32 Win7, x64 Win8, x64 2k12R2 提权powershell脚本: https://github.com/FuzzySecurity/Power ...
- LWIP再探----内存池管理
这这里是接上一篇内存池管理部分的,这里如果读者一打开memp.c的话会感觉特别那一理解原作者在干嘛,但是看懂了就明白原作者是怎么巧妙的使用了宏.废话不多说先说了下我分析是一下宏的条件是 前提条件MEM ...
- cookie & maxAge & expires
cookie & maxAge & expires Expires (timestamp) & Max-Age (seconds) https://developer.mozi ...
- macOS 显示/隐藏 AirPlay
macOS 显示/隐藏 AirPlay AirPlay Sidecar 必须用相同的 Apple ID 登录 mac 和 ipad, 才能使用! https://www.apple.com/macos ...
- Enums & JavasScript & TypeScript
Enums & JavasScript & TypeScript ES6 & TS https://www.typescriptlang.org/docs/handbook/e ...
- 「NGK每日快讯」11.18日NGK公链第15期官方快讯
- BGV暴涨千倍,未来或将超越YFI领跑DeFi全场!
毫无疑问,YFI在2020年上半年以一己之力掀翻了DeFi市场的热潮.迄今为止,YFI的新鲜资讯从不缺席,最近也是频频登上各大知名媒体热搜.其币价远远超过比特币价格,也让资本市场注意到DeFi市场原来 ...
- 【目标检测】用Fast R-CNN训练自己的数据集超详细全过程
目录: 一.环境准备 二.训练步骤 三.测试过程 四.计算mAP 寒假在家下载了Fast R-CNN的源码进行学习,于是使用自己的数据集对这个算法进行实验,下面介绍训练的全过程. 一.环境准备 我这里 ...