stock_fundamentals/manage-instances.sh

218 lines
6.1 KiB
Bash
Raw Permalink Normal View History

2025-05-14 08:54:56 +08:00
#!/bin/bash
# 函数:显示帮助信息
show_help() {
echo "股票基础分析应用管理脚本"
echo ""
echo "用法: $0 [命令] [参数]"
echo ""
echo "命令:"
echo " list 列出所有运行的实例"
echo " start [实例ID] 启动指定实例或所有实例"
echo " stop [实例ID] 停止指定实例或所有实例"
echo " restart [实例ID] 重启指定实例或所有实例"
echo " logs [实例ID] 查看指定实例的日志"
echo " status 显示实例状态概览"
echo " remove [实例ID] 删除指定实例或所有实例"
echo " rebuild [数量] 重新构建镜像并部署指定数量的实例"
echo " update 热更新代码不重建镜像仅复制src目录"
echo ""
echo "示例:"
echo " $0 list 列出所有实例"
echo " $0 start 2 启动实例2"
echo " $0 stop all 停止所有实例"
echo " $0 logs 1 查看实例1的日志"
echo " $0 rebuild 2 重新构建并部署2个实例"
echo " $0 update 热更新所有实例的代码"
exit 1
}
# 函数:列出所有实例
list_instances() {
echo "正在运行的实例:"
docker ps --filter "name=stock-app-" --format "表格 {{.Names}}\t{{.Status}}\t{{.Ports}}"
}
# 函数:启动实例
start_instance() {
if [ "$1" = "all" ]; then
echo "启动所有实例..."
docker start $(docker ps -a --filter "name=stock-app-" -q)
else
echo "启动实例 $1..."
docker start stock-app-$1
fi
}
# 函数:停止实例
stop_instance() {
if [ "$1" = "all" ]; then
echo "停止所有实例..."
docker stop $(docker ps --filter "name=stock-app-" -q)
else
echo "停止实例 $1..."
docker stop stock-app-$1
fi
}
# 函数:重启实例
restart_instance() {
if [ "$1" = "all" ]; then
echo "重启所有实例..."
docker restart $(docker ps --filter "name=stock-app-" -q)
else
echo "重启实例 $1..."
docker restart stock-app-$1
fi
}
# 函数:查看实例日志
view_logs() {
echo "实例 $1 的日志:"
docker logs stock-app-$1
}
# 函数:显示状态概览
show_status() {
echo "实例状态概览:"
echo "-----------------"
echo "实例总数: $(docker ps -a --filter "name=stock-app-" --format "{{.Names}}" | wc -l)"
echo "运行中: $(docker ps --filter "name=stock-app-" --format "{{.Names}}" | wc -l)"
echo "已停止: $(docker ps -a --filter "name=stock-app-" --filter "status=exited" --format "{{.Names}}" | wc -l)"
echo "-----------------"
docker ps -a --filter "name=stock-app-" --format "表格 {{.Names}}\t{{.Status}}\t{{.Ports}}"
}
# 函数:删除实例
remove_instance() {
if [ "$1" = "all" ]; then
echo "删除所有实例..."
docker rm -f $(docker ps -a --filter "name=stock-app-" -q)
else
echo "删除实例 $1..."
docker rm -f stock-app-$1
fi
}
# 函数:重新构建并部署
rebuild_instances() {
NUM_INSTANCES=$1
echo "开始全面重建流程..."
# 1. 停止所有实例
echo "停止所有实例..."
docker stop $(docker ps --filter "name=stock-app-" -q) 2>/dev/null
# 2. 删除所有实例
echo "删除所有实例..."
docker rm -f $(docker ps -a --filter "name=stock-app-" -q) 2>/dev/null
# 3. 重新构建镜像
echo "重新构建镜像..."
docker-compose build
# 4. 部署新实例
echo "部署 $NUM_INSTANCES 个新实例..."
./deploy-multiple.sh $NUM_INSTANCES
echo "重建完成!"
}
# 函数:热更新代码
update_code() {
# 获取所有正在运行的实例
RUNNING_INSTANCES=$(docker ps --filter "name=stock-app-" -q)
if [ -z "$RUNNING_INSTANCES" ]; then
echo "没有发现正在运行的实例!"
return 1
fi
echo "发现 $(echo "$RUNNING_INSTANCES" | wc -l) 个实例需要更新..."
# 更新每个实例的代码
for CONTAINER_ID in $RUNNING_INSTANCES; do
CONTAINER_NAME=$(docker inspect --format='{{.Name}}' $CONTAINER_ID | sed 's/\///')
echo "更新 $CONTAINER_NAME 的代码..."
# 复制 src 目录到容器
docker cp ./src/. $CONTAINER_ID:/app/src/
# 重启 Flask 应用如果使用的是gunicorn等进程管理器需要向进程发送信号
echo "重启 $CONTAINER_NAME 中的应用..."
docker exec $CONTAINER_ID sh -c "pkill -f 'python src/app.py' && nohup python src/app.py > /app/logs/app.log 2>&1 &"
done
echo "所有实例代码已更新,并尝试重启应用!"
echo "注意:如果应用启动方式不是 'python src/app.py',可能需要手动重启容器:"
echo "./manage-instances.sh restart all"
}
# 主逻辑
if [ "$#" -lt 1 ]; then
show_help
fi
case "$1" in
list)
list_instances
;;
start)
if [ "$#" -lt 2 ]; then
echo "错误: 缺少实例ID参数"
show_help
fi
start_instance $2
;;
stop)
if [ "$#" -lt 2 ]; then
echo "错误: 缺少实例ID参数"
show_help
fi
stop_instance $2
;;
restart)
if [ "$#" -lt 2 ]; then
echo "错误: 缺少实例ID参数"
show_help
fi
restart_instance $2
;;
logs)
if [ "$#" -lt 2 ]; then
echo "错误: 缺少实例ID参数"
show_help
fi
view_logs $2
;;
status)
show_status
;;
remove)
if [ "$#" -lt 2 ]; then
echo "错误: 缺少实例ID参数"
show_help
fi
remove_instance $2
;;
rebuild)
if [ "$#" -lt 2 ]; then
echo "错误: 缺少实例数量参数"
show_help
fi
rebuild_instances $2
;;
update)
update_code
;;
help|--help|-h)
show_help
;;
*)
echo "错误: 未知命令 '$1'"
show_help
;;
esac
exit 0