本文目录导读:

我来详细介绍Shell脚本实现自动发布策略的方法。
基础发布脚本框架
#!/bin/bash
# 自动发布脚本
set -e # 出错即停止
# 配置变量
PROJECT_NAME="myapp"
DEPLOY_DIR="/opt/app/${PROJECT_NAME}"
BACKUP_DIR="/opt/backup/${PROJECT_NAME}"
GIT_REPO="git@github.com:user/${PROJECT_NAME}.git"
BRANCH="main"
BUILD_COMMAND="npm run build" # 或 mvn package, make 等
SERVICE_NAME="${PROJECT_NAME}"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}
error() {
echo -e "${RED}[ERROR] $1${NC}"
exit 1
}
warning() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
# 1. 代码获取与更新
fetch_code() {
log "Fetching latest code from ${BRANCH}..."
if [ ! -d "${DEPLOY_DIR}/.git" ]; then
git clone -b ${BRANCH} ${GIT_REPO} ${DEPLOY_DIR}
else
cd ${DEPLOY_DIR}
git fetch origin
git checkout ${BRANCH}
git rebase origin/${BRANCH}
fi
# 获取最新commit信息
COMMIT_ID=$(git rev-parse --short HEAD)
log "Latest commit: ${COMMIT_ID}"
}
# 2. 构建项目
build_project() {
log "Building project..."
cd ${DEPLOY_DIR}
# 安装依赖
if [ -f "package.json" ]; then
npm install --production
elif [ -f "pom.xml" ]; then
mvn clean package -DskipTests
elif [ -f "Makefile" ]; then
make build
fi
# 执行构建命令
eval ${BUILD_COMMAND}
log "Build completed"
}
# 3. 备份当前版本
backup_current() {
log "Backing up current version..."
# 创建备份目录
BACKUP_PATH="${BACKUP_DIR}/$(date '+%Y%m%d_%H%M%S')_${COMMIT_ID}"
mkdir -p ${BACKUP_PATH}
# 备份配置文件
if [ -f "${DEPLOY_DIR}/config/application.yml" ]; then
cp -r ${DEPLOY_DIR}/config ${BACKUP_PATH}/
fi
# 备份数据目录
if [ -d "${DEPLOY_DIR}/data" ]; then
cp -r ${DEPLOY_DIR}/data ${BACKUP_PATH}/
fi
log "Backup saved to: ${BACKUP_PATH}"
}
# 4. 停止服务
stop_service() {
log "Stopping service..."
if systemctl is-active --quiet ${SERVICE_NAME}; then
systemctl stop ${SERVICE_NAME}
log "Service stopped"
else
warning "Service not running"
fi
# 等待进程完全退出
sleep 3
}
# 5. 部署新版本
deploy_new_version() {
log "Deploying new version..."
# 复制构建产物到部署目录
# 根据具体项目结构调整
cp -r ${DEPLOY_DIR}/dist/* ${DEPLOY_DIR}/release/
# 处理配置文件(保留原配置)
if [ -f "${BACKUP_PATH}/config/application.yml" ]; then
cp ${BACKUP_PATH}/config/application.yml ${DEPLOY_DIR}/release/config/
fi
log "Deployment files ready"
}
# 6. 启动服务
start_service() {
log "Starting service..."
systemctl daemon-reload
systemctl start ${SERVICE_NAME}
# 等待服务启动
sleep 5
if systemctl is-active --quiet ${SERVICE_NAME}; then
log "Service started successfully"
else
error "Failed to start service"
fi
}
# 7. 健康检查
health_check() {
log "Performing health check..."
# HTTP健康检查
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health)
if [ "${HTTP_CODE}" = "200" ]; then
log "Health check passed (HTTP ${HTTP_CODE})"
else
# 回滚到上一版本
rollback
error "Health check failed (HTTP ${HTTP_CODE})"
fi
}
# 8. 回滚函数
rollback() {
log "Rolling back to previous version..."
# 停止当前服务
stop_service
# 恢复备份
LATEST_BACKUP=$(ls -t ${BACKUP_DIR} | head -1)
if [ -n "${LATEST_BACKUP}" ]; then
cp -r ${BACKUP_DIR}/${LATEST_BACKUP}/* ${DEPLOY_DIR}/
log "Rolled back to: ${LATEST_BACKUP}"
else
error "No backup available for rollback"
fi
# 启动服务
start_service
}
# 主发布流程
main() {
log "Starting deployment for ${PROJECT_NAME}"
fetch_code
build_project
backup_current
stop_service
deploy_new_version
start_service
health_check
log "Deployment completed successfully!"
}
# 执行主函数
main "$@"
高级发布策略
蓝绿部署
#!/bin/bash
# 蓝绿部署脚本
BLUE_PORT=8081
GREEN_PORT=8082
NGINX_CONF="/etc/nginx/conf.d/app.conf"
APP_DIR="/opt/app"
deploy_blue_green() {
# 确定当前活动环境
if curl -s http://localhost:${BLUE_PORT}/health > /dev/null 2>&1; then
ACTIVE="blue"
INACTIVE="green"
INACTIVE_PORT=${GREEN_PORT}
else
ACTIVE="green"
INACTIVE="blue"
INACTIVE_PORT=${BLUE_PORT}
fi
log "Current active: ${ACTIVE}, deploying to: ${INACTIVE}"
# 部署到非活动环境
cp -r ${APP_DIR}/release/* ${APP_DIR}/${INACTIVE}/
# 启动非活动环境
systemctl start app-${INACTIVE}
# 健康检查新环境
sleep 10
if curl -s http://localhost:${INACTIVE_PORT}/health > /dev/null 2>&1; then
log "New environment healthy, switching traffic"
# 更新Nginx配置切换流量
sed -i "s/proxy_pass http:\/\/127.0.0.1:${ACTIVE_PORT}/proxy_pass http:\/\/127.0.0.1:${INACTIVE_PORT}/" ${NGINX_CONF}
nginx -s reload
# 停止旧环境
systemctl stop app-${ACTIVE}
log "Deployment successful, traffic switched to ${INACTIVE}"
else
error "New environment failed health check"
systemctl stop app-${INACTIVE}
fi
}
滚动更新
#!/bin/bash
# 滚动更新脚本
SERVERS=("node1" "node2" "node3")
SSH_USER="deploy"
SSH_KEY="/home/deploy/.ssh/id_rsa"
rolling_update() {
log "Starting rolling update..."
for SERVER in "${SERVERS[@]}"; do
log "Updating ${SERVER}..."
# 从负载均衡移除
remove_from_lb "${SERVER}"
# 远程执行更新
ssh -i ${SSH_KEY} ${SSH_USER}@${SERVER} "
systemctl stop app
cp -r /tmp/release/* /opt/app/
systemctl start app
"
# 等待服务就绪
sleep 15
# 健康检查
if check_remote_health "${SERVER}"; then
# 添加回负载均衡
add_to_lb "${SERVER}"
log "${SERVER} updated successfully"
else
error "Failed to update ${SERVER}, rolling back..."
rollback_server "${SERVER}"
fi
done
log "Rolling update completed"
}
remove_from_lb() {
local server=$1
# 使用API从负载均衡器移除节点
curl -X POST "http://loadbalancer:8080/api/pool/remove?server=${server}"
}
add_to_lb() {
local server=$1
curl -X POST "http://loadbalancer:8080/api/pool/add?server=${server}"
}
check_remote_health() {
local server=$1
ssh -i ${SSH_KEY} ${SSH_USER}@${SERVER} "curl -s http://localhost:8080/health" | grep -q "ok"
}
完整的发布配置文件
# deploy-config.yml
project:
name: myapp
repo: git@github.com:user/myapp.git
branch: main
build_command: npm run build
environment:
production:
servers:
- 192.168.1.10
- 192.168.1.11
- 192.168.1.12
deploy_dir: /opt/app
backup_dir: /opt/backup
service_name: myapp
port: 8080
staging:
servers:
- 192.168.2.10
deploy_dir: /opt/staging/app
backup_dir: /opt/staging/backup
service_name: myapp-staging
port: 8081
health_check:
type: http
endpoint: /health
expected_status: 200
timeout: 30
retries: 3
rollback:
enabled: true
max_backups: 5
auto_rollback: true
使用示例
# 基本部署 ./deploy.sh # 指定环境 ./deploy.sh --env production # 指定版本 ./deploy.sh --tag v1.2.3 # 仅构建 ./deploy.sh --build-only # 跳过测试 ./deploy.sh --skip-tests # 强制部署(忽略错误) ./deploy.sh --force # 回滚到指定版本 ./deploy.sh --rollback v1.2.0
最佳实践建议
- 版本控制:使用Git标签管理版本
- 配置管理:分离配置和代码,使用环境变量
- 日志记录:记录详细部署日志
- 通知机制:集成Slack/邮件通知
- 自动化测试:部署前运行自动化测试
- 渐进式部署:先部署少量实例验证
- 监控告警:部署后持续监控服务状态
这样的自动发布策略可以显著提高部署效率,减少人为错误,并支持快速回滚。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播