내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
오프라인 환경에 배포된 여러 Java 애플리케이션으로 구성된 시스템은 테스트 단계에서 더 자주 릴리스되어야 합니다. 리소스 제약으로 인해 DevOps나 CICD 세트가 없으므로 릴리스용 jar로 간단히 패키징됩니다. 이전에 시작하기 위해 스크립트를 사용했습니다. 시작하기 전에 수신된 포트에 따라 프로세스를 종료해야 합니다. 그렇지 않으면 포트 충돌이 발생하고 시작이 실패하게 됩니다. 최적화 포인트 중 하나는 스크립트의 자동 재시작을 지원하는 것입니다. 해당 프로세스를 자동으로 찾은 다음 종료하고 다시 시작합니다. 또 다른 점은 로그 파일입니다. 다시 시작한 후에는 서비스 이름과 현재 시간을 기반으로 새 로그 파일이 생성됩니다. 로그를 쿼리할 때 접두사가 여러 개인 파일이 있는 경우 수동으로 선택해야 하는데 이는 번거로운 일입니다. . 기록 로그 파일을 현재 경로 아래의 백업 폴더에 보관하려고 생각했습니다.
우선, 나는 쉘 초보자이고 이 영역을 거의 사용하지 않는다는 점을 말씀드리고 싶습니다.
이를 위해 lsof 명령을 사용하는 것을 선호합니다. 예를 들어 포트 8080이 사용하는 프로세스를 쿼리하려면 다음 명령을 사용할 수 있습니다.
lsof -i:8080
여러분 모두 이것을 알아야 합니다. kill -9. 단순히 kill을 사용하지 마십시오. 예를 들어 프로세스 PID가 12345인 프로세스를 종료하십시오.
kill -9 12345
이는 비교적 간단한 명령이며 이에 따라 함수의 매개변수가 사용됩니다.$1
,$2
,$3
…받다
여러 Java 서비스가 있고 재사용이라는 아이디어도 고수했기 때문에 서비스를 다시 시작하는 공통 방법을 작성한 다음 여러 서비스에 해당하는 스크립트를 작성하여 해당 서비스 이름, 포트 및 기타 정보를 기록하는 것을 생각했습니다. 서비스의 각 스크립트에서 중간 단계 매개변수는 공통 서비스 시작 또는 다시 시작 방법을 호출합니다.
공통 서비스 시작 또는 다시 시작 스크립트 run.sh
#!/bin/bash
start_app(){
# 接收参数
APP_NAME=$1;
APP_PORT=$2;
MEM=$3
ACTION=$4;
CURRENT_TIME=`date +"%Y%m%d%H%M%S"`
#检查程序是否在运行
APP_STATUS=`netstat -nlt|grep ${APP_PORT} |wc -l`;
RUNNING_PID=$(netstat -nlp | grep :$APP_PORT | awk '{print $7}' | awk -F"/" '{ print $1 }');
LOG_FILE=./logs/${APP_NAME}_${CURRENT_TIME}.log;
cd ..;
if [ "${APP_STATUS}" -eq 1 ]; then
if [ "${ACTION}"x == "restart"x ]; then
## 重启前先kill原进程
echo "kill the running app whose PID is ${RUNNING_PID} of ${APP_NAME}";
kill -9 "${RUNNING_PID}";
# 日志归档
cd logs;
for file in `ls ${APP_NAME}* -a`;
do
mv "${file}" backup/;
done
cd ..;
else
echo "exist running ${APP_NAME} and the PID is ${RUNNING_PID}";
exit 0;
fi
fi
echo "start ${APP_NAME} at $CURRENT_TIME";
## 启动程序
nohup java -Xms${MEM}m -Xmx${MEM}m -XX:PermSize=256m -XX:MaxPermSize=512m -jar -Dfile.encoding=utf-8 -Dserver.port=${APP_PORT} -Dspring.profiles.active=prod ${APP_NAME} > ${LOG_FILE} 2>&1 &
pid=`ps -ef|grep java|grep ${APP_NAME}`
echo "${APP_NAME} has started successfully at ${CURRENT_TIME},and the pid is ${pid}"
}
단일 서비스 시작 스크립트
#!/bin/bash
action=$1
## 引入通用服务启动脚本
source ./run.sh
#启动方法
start(){
# 执行通用服务脚本中的启动方法
start_app xxx.jar 8080 4096 ${action}
}
#程序主入口
start
매개 변수를 전달하지 않고 서비스 시작 스크립트를 직접 실행하면 서비스 포트가 점유되어 있는지 판단하고, 다시 시작하면 원래 서비스 프로세스가 종료된 후 다시 시작됩니다. 서비스가 시작되었습니다.
jar 패키지는 /opt/app 디렉터리에 있고, 스크립트는 /opt/app/run 디렉터리에 있으며, 로그는 /opt/app/logs 디렉터리에 있습니다. 현재 이 버전은 실행만 지원할 수 있습니다. 절대 경로를 사용하는 경우 이 방법은 절대 경로를 사용하지 않는 스크립트의 일부 작성 방법으로 인해 발생할 수 있는 오류를 보고하므로 이를 유지하겠습니다. 지금은 솔루션.
테스트 중 마주친run.sh: xxx行 $'r' 附近有语法错误
오류가 발생하면 sed -i 's/r$//' run.sh 명령을 사용하여 변환하세요.