How to add a delay in the `start.sh` script of AnQiCMS to ensure that the port is completely released before starting?
Ensure AnQiCMS graceful restart: instart.shAdd delay mechanism in the script
AnQiCMS with its efficient and concise features developed based on the Go language provides strong support for content operators.It is simple to deploy and fast to execute, making content management and website operation very skillful.However, even such a high-performance system, in certain specific operation and maintenance scenarios, such as frequent restarts, updates and deployments, or when the server resources are tight, you may accidentally encounter a pesky problem: the program fails to start and prompts "Address already in use" (the address is already in use).
This is not usually a defect of AnQiCMS itself, but a common phenomenon of Linux/Unix systems in handling process termination and port release. When a program is stopped (especially throughkill -9This forced method), the operating system will not immediately release all the resources it occupies, including network ports. These ports may enterTIME_WAITThe status will be available after a period of time. If your startup script tries to start a new process immediately after the old process is killed, the new process may fail to start because the port is still occupied.
To ensure that AnQiCMS can start smoothly and elegantly every time, we can do it in itsstart.shAdd a simple delay mechanism to the startup script. This is like giving the system a moment to breathe, allowing it to thoroughly clean up the ports left by old processes, and prepare for new processes.
Understandingstart.shThe working principle of the script
During the deployment of AnQiCMS,start.shThe script plays an important role. It is usually configured as a scheduled task (crontabResponsible for regularly checking if the AnQiCMS process is running. If it finds that the process is not running, it will start AnQiCMS. Let's review a typicalstart.shScript core logic:
#!/bin/bash
BINNAME=anqicms
BINPATH=/www/wwwroot/anqicms # 您的实际路径可能不同
# 检查 anqicms 进程是否存在
exists=`ps -ef | grep '\<anqicms\>' |grep -v grep |wc -l`
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME PID check: $exists" >> $BINPATH/check.log
if [ $exists -eq 0 ]; then
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME NOT running, attempting to start..." >> $BINPATH/check.log
# 在这里,AnQiCMS 进程将会被启动
cd $BINPATH && nohup $BINPATH/$BINNAME >> $BINPATH/running.log 2>&1 &
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME started." >> $BINPATH/check.log
else
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME is already running." >> $BINPATH/check.log
fi
As you can see, the script first usesps -ef | grepcommands to judgeanqicmswhether the process exists. IfexistsVariable is0(indicating that the process does not exist), it willcdGo to the specified directory and usenohupcommand to start in the backgroundanqicmsExecutable file.
Insert a delay to solve the port occupation problem
The crux of the problem lies in ifanqicmsThe process has just beenstop.shKilled by script or manual command, andstart.shIt is triggered and detected immediatelyexistsWith0Then, in the case that the old port has not been fully released, the newanqicmsprocess will try to bind to the same port, resulting in a failure to start.
To avoid this situation, we canstart.shadd a simple command before the script startssleepcommand.sleepThe command will pause the script's execution for the specified number of seconds, providing necessary buffer time for the system.
The following has been modifiedstart.shScript, the key change is insleep 5This line:
#!/bin/bash
BINNAME=anqicms
BINPATH=/www/wwwroot/anqicms # 您的实际路径可能不同
# 检查 anqicms 进程是否存在
exists=`ps -ef | grep '\<anqicms\>' |grep -v grep |wc -l`
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME PID check: $exists" >> $BINPATH/check.log
if [ $exists -eq 0 ]; then
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME NOT running, attempting to start..." >> $BINPATH/check.log
# 新增:加入延时,等待端口完全释放
sleep 5
cd $BINPATH && nohup $BINPATH/$BINNAME >> $BINPATH/running.log 2>&1 &
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME started." >> $BINPATH/check.log
else
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME is already running." >> $BINPATH/check.log
fi
Operation steps:
- Find
start.shFile:Generally located in your AnQiCMS deployment directory (for example/www/wwwroot/anqicms/start.sh) - Edit file:Use
vi/nanoor open the file manager on Baota panelstart.sh. - Insert
sleep 5:Inif [ $exists -eq 0 ]; thenInside the code block,紧接着echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME NOT running, attempting to start..."After this line,nohupInsert before the actual command starts,sleep 5. - Save and exit.
With this small change, you have gained several precious seconds for AnQiCMS to clean up the environment. Whenstart.shDetected that the process needs to start, it will pause for 5 seconds first, and then try to start AnQiCMS, which greatly reduces the probability of failure to start due to port occupation.
Think and **practice
- Duration extended:
sleep 5Provided a reasonable starting value. In most cases, 5 seconds is enough for the operating system to release the port