Detailed explanation of Shell script controlling docker container startup sequence
- 2021-10-13 09:12:38
- OfStack
1. Problems encountered
In the process of distributed project deployment, it is often required that applications (including databases) can be automatically restored after the server is restarted. Although using
docker update --restart=always containerid
The container can be automatically started with docker, but it cannot be guaranteed to start after the database is started. If the database is not started, it will lead to application startup failure; Another solution on the Internet is to control the startup sequence through docker-compose container arrangement, which is less studied by this blogger.
2. Solutions
Using Shell script control, the idea is roughly as follows
After the database is started successfully, the ports of the configuration center and the service registry center are probed to verify whether the database is started successfully. When the database and the configuration center are started, other micro-service applications are started again.
3. Port probing
The command used for port probing is
nc -w 1 host port </dev/null && echo "200"
host: ip for the target host
port: Port on which the service listens
This command returns 200 if the service is started, and null if it is not started.
4. Shell script
The code is pasted directly, and the configuration center used is nacos
#!/bin/bash
#chkconfig: 2345 80 90
#description:autoStartMaintenanceService.sh
#
# Premise :
#1.docker Must be able to boot and start
#2.docker Able to start operation and maintenance services normally
#3. This script must run on the machine where the microservice is located
#
## Configuration that needs to be modified ----- Begin
## The machine where the database is located IP
DATABASE_HOST=192.169.1.52
## Port on which the database listens
DATABASE_PORT=3306
## The machine where the microservice is located IP
LOCAL_HOST=192.169.1.46
## Microservice access port
Maintenance_Port=8180
##NACOS Of the machine where it is located ip
NACOS_HOST=192.169.1.82
##NACOS Listening port of
NACOS_PORT=8848
## Microservice container name (NAMES Column )
Maintenance_Container_Name="umc-maintenance"
## The log path generated by this script
Log_Path=/home/test/log
## Configuration that needs to be modified ----- End
##
## Cyclic delay time (s) Seconds
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 the log path does not exist, create
if [ ! -d "$Log_Path" ]; then
mkdir -p $Log_Path
fi
while true; do
## Determine whether the database is started
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
}
## Judge Nacos Whether to start
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
}
## Start micro-service
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 input and output redirection
When writing this script, it also makes bloggers more familiar with Shell input and output redirection
1 Typically, each Unix/Linux command runs with three files open:
Standard input file (stdin): The file descriptor for stdin is 0, and the Unix program reads data from stdin by default. Standard output file (stdout): The file descriptor of stdout is 1, and the Unix program outputs data to stdout by default. Standard error file (stderr): stderr has a file descriptor of 2, and the Unix program writes error messages to the stderr stream.
Command description
command
>
file redirects output to file and overrides file
command
<
file redirects input to file
command
>
>
file redirects the output to file as an append
command 2
>
file outputs errors to file and overwrites file
command 2
>
>
file redirects errors as appends to file
<
<
tag takes the contents between the opening tag tag and the closing tag tag as input
If you want to merge stdout and stderr and redirect them to file (that is, output both correct and error information to file), you can write this:
command > file 2>&1
Or
command >> file 2>&1
/dev/null File
/dev/null is a special file, and the contents written to it will be discarded; If you try to read from the file, you can't read anything. However, the/dev/null file is very useful, and redirecting the output of the command to it will have the effect of prohibiting the output
command > /dev/null 2>&1
stdout and stderr can be masked
Reference
Rookie Tutorial-Shell