Shell脚本如何实现手动发布策略

wen 实用脚本 33

Shell脚本如何实现手动发布策略:从入门到生产级实战

目录导读

  1. 为什么需要手动发布策略?
  2. Shell手动发布脚本的核心设计原则
  3. 基础版手动发布脚本(单服务器)
  4. 进阶版:多服务器并行发布+回滚机制
  5. 常见问题与问答(Q&A)
  6. SEO优化建议:脚本中的元数据与注释

为什么需要手动发布策略?

在持续集成/持续部署(CI/CD)盛行的今天,手动发布依然在以下场景中不可替代:

Shell脚本如何实现手动发布策略

  • 灰度发布:仅对特定服务器或用户群体先更新代码
  • 故障应急回滚:当自动流水线失败时,需要人工介入修复
  • 资源受限环境:云服务器配置低,自动化工具(如Jenkins)无法部署
  • 安全合规要求:生产环境禁止自动部署,需审批后手动执行

核心矛盾:手动操作容易因步骤遗漏导致故障,而Shell脚本可以将多步操作封装为原子级命令,减少人为失误。


Shell手动发布脚本的核心设计原则

原则 说明 反例
幂等性 脚本多次执行结果一致 rm -rf /app && deploy 会清空现有数据
回滚优先 执行前必须保存当前版本快照 没有备份直接覆盖
状态提示 每一步输出带时间戳的操作日志 静默执行难以排查
参数化 通过参数控制发布目标、版本、环境 硬编码服务器IP

黄金法则

手动发布脚本 = 一个带“确认开关”的自动化流程


基础版手动发布脚本(单服务器)

以下是一个可直接使用的示例,适用于小型项目(如Node.js/Python应用):

#!/bin/bash
# 手动发布脚本 v2.0
# 功能:从Git仓库拉取代码 -> 构建 -> 部署到目标目录
# 注意:该脚本需要具备SSH密钥访问权限
set -euo pipefail  # 遇到错误立即退出,避免连锁故障
APP_NAME="my-web-service"
REPO_URL="https://git.example.com/team/${APP_NAME}.git"
DEPLOY_DIR="/var/www/${APP_NAME}"
BACKUP_DIR="/backup/${APP_NAME}_$(date +%Y%m%d_%H%M%S)"
BRANCH=${1:-main}  # 默认发布main分支,也可通过参数指定
# 步骤1: 确认操作
read -p "即将发布 ${APP_NAME} 到 ${DEPLOY_DIR},确认请输入 'yes': " confirm
if [[ "$confirm" != "yes" ]]; then
    echo "操作取消"
    exit 1
fi
# 步骤2: 备份旧版本
echo "[$(date)] 备份旧版本到 ${BACKUP_DIR}..."
cp -r ${DEPLOY_DIR} ${BACKUP_DIR} 2>/dev/null || echo "备份目录不存在"
# 步骤3: 拉取代码
cd /tmp
git clone --depth 1 -b ${BRANCH} ${REPO_URL} ${APP_NAME}_release
cd ${APP_NAME}_release
# 步骤4: 构建(此处以npm为例)
npm install --production
npm run build
# 步骤5: 复制到部署目录
rm -rf ${DEPLOY_DIR}/*
cp -r dist/* ${DEPLOY_DIR}/
# 步骤6: 重启服务
systemctl restart nginx
echo "[$(date)] 部署完成!当前版本: $(git log --oneline -1)"
echo "若需回滚执行: ./rollback.sh ${BACKUP_DIR}"

使用方式
./deploy.sh feature-3.2 # 发布feature分支


进阶版:多服务器并行发布+回滚机制

生产环境通常有3台以上服务器,手动逐台操作耗时且易错,以下脚本通过SSH批量执行并内置回滚:

#!/bin/bash
# 文件名:publish_multi.sh
# 支持同时发布到多台服务器,失败时自动回滚
SERVERS=("192.168.1.10" "192.168.1.11" "192.168.1.12")
REMOTE_USER="deploy"
TIMEOUT=60  # 单台服务器超时时间
# 远程执行命令的统一函数
run_remote() {
    local host=$1
    local cmd=$2
    ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 \
        ${REMOTE_USER}@${host} "${cmd}"
}
# 发布单台服务器
deploy_node() {
    local host=$1
    echo ">>> 开始部署 ${host} ..."
    # 远程执行备份与部署(此处为简化示例)
    cmd="cd /app && tar czf /backup/$(date +%Y%m%d%H%M%S).tgz . && \
         git pull origin main && npm install && npm run build"
    run_remote ${host} "${cmd}"
    if [[ $? -ne 0 ]]; then
        echo "[ERROR] ${host} 部署失败!"
        return 1
    fi
}
# 并行发布所有服务器
node_count=${#SERVERS[@]}
echo "即将发布到 ${node_count} 台服务器,确认?(yes/no)"
read confirm
if [[ "$confirm" != "yes" ]]; then exit 0; fi
# 使用后台进程实现并行
failed_list=()
for host in "${SERVERS[@]}"; do
    (deploy_node ${host} || echo "FAIL_${host}" > /tmp/fail_${host%.*}) &
done
wait # 等待所有进程完成
# 检查失败节点
for host in "${SERVERS[@]}"; do
    if [[ -f /tmp/fail_${host%.*} ]]; then
        failed_list+=("${host}")
        rm -f /tmp/fail_${host%.*}
    fi
done
# 自动回滚失败的节点
if [[ ${#failed_list[@]} -gt 0 ]]; then
    echo "以下服务器部署失败,正在回滚: ${failed_list[*]}"
    for host in "${failed_list[@]}"; do
        echo "回滚 ${host} ..."
        # 此处可调用回滚脚本(略)
    done
fi

关键优化点

  • 使用set -e确保任何步骤失败后中断
  • 通过read二次确认避免误操作
  • 失败自动回滚但保留成功节点(避免全量回滚阻塞业务)

常见问题与问答(Q&A)

Q1: 如果发布过程中网络中断,脚本会怎样?
A: 基础版脚本因set -e会立即退出,但不会自动清理临时文件,建议在脚本开头加入trap "rm -rf /tmp/${APP_NAME}_release; exit" INT TERM,捕获中断信号后清理,进阶版使用后台进程,需在wait时捕获信号。

Q2: 脚本如何记录操作日志以便审计?
A: 在脚本顶部添加 exec > >(tee -a /var/log/deploy_$(date +%Y%m%d).log) 2>&1,同时输出到终端和日志文件。

Q3: 能否避免每次手动输入服务器IP?
A: 建议将服务器列表存储在独立的hosts.txt文件中,脚本通过readarray -t SERVERS < hosts.txt读取,避免修改脚本主体。

Q4: 如何对发布操作做权限控制?
A: 在脚本中添加白名单检测:

ALLOWED_USERS=("lihua" "wangwu")  
if [[ ! " ${ALLOWED_USERS[*]} " =~ "$(whoami)" ]]; then  
    echo "请授权用户执行"  
    exit 1  
fi

SEO优化建议:脚本中的元数据与注释

为了让搜索引擎更好地索引你的发布策略,建议在Shell脚本中加入以下结构化注释:

# @description 支持分支选择、回滚备份、定时任务防冲突的发布策略
# @author DevOps Team
# @version 2.0.1
# @license MIT
# @type Bash/Unix
# @tags deployment, shell-script, manual-publish

在博客或文档中,建议针对以下长尾关键词进行优化:

  • “Shell脚本自动化部署避免人工误操作”
  • “生产环境手动回滚脚本示例”
  • “多服务器滚动发布Shell实现”

手动发布并非落后的选择,而是成熟的运维体系中的战术手段,好的Shell脚本让手动发布变成“一键式操作”,同时保留人工确认的安全防线,当你的团队需要从0搭建发布规范时,从本文的基础脚本开始,逐步加入环境隔离、健康检查和通知机制,就能构建适合自身业务的手动发布策略。

抱歉,评论功能暂时关闭!