моя контактная информация
Почтамезофия@protonmail.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 для ее преобразования.