#!/bin/bash # 集群发布脚本:发布中枢从 git 拉 release,再分发到各 worker。 # 前提:代码已 push 到 origin/release;发布中枢的部署目录是 git 仓库(首次初始化见下方检测提示)。 # # 挂 DS 手动触发,任务体(在 DS worker 上执行): # ssh bigdata@cdhmaster02 "bash /home/bigdata/release/poyee-data-warehouse/publish.sh" # # 五个动作,缺一不可: # 1. 发布中枢 git 更新到 release(checkout . 丢弃开发期 rsync 推进来的脏改动) # 2. rsync 项目到各 worker(worker 不建 git 仓库,只做镜像) # 3. rsync datasource 到各 worker(不入 git,git pull 拿不到) # 4. 删所有节点的 dw_base.zip —— 发布环境下该文件存在就复用,不删则 Spark 作业继续跑旧代码 # (见 dw_base/spark/spark_sql.py 的 IS_RUN_IN_RELEASE_DIR 分支) # 5. chmod bin/ 保证入口可执行 # # 与 workspace/bin/sync-all.sh 的关系:那个从开发机 rsync 推、绕过 git,用于开发期快速迭代; # 本脚本以 git release 分支为唯一发布源。两者可共存——第 1 步的 checkout . 会把 # 开发期推进来的改动还原成 release 版本。 set -euo pipefail BRANCH='release' # 节点硬编码(与 workspace/bin/sync-all.sh 保持一致);增删节点改这两行 RELEASE_HOST='cdhmaster02' WORKER_HOSTS=(cdhnode01 cdhnode02 cdhnode03) log() { echo "$(date '+%Y-%m-%d %H:%M:%S') $*" } die() { echo "$(date '+%Y-%m-%d %H:%M:%S') [失败] $*" >&2 exit 1 } # root 发布会把文件属主改成 root,之后 bigdata 写不动 [ "root" = "$(whoami)" ] && die '禁止用 root 发布' PROJECT_ROOT=$(cd "$(dirname "$(realpath "$0")")" && pwd) PROJECT_NAME=$(basename "${PROJECT_ROOT}") # shellcheck source=conf/env.sh . "${PROJECT_ROOT}/conf/env.sh" CURRENT_HOST=$(hostname -s) [ "${CURRENT_HOST}" = "${RELEASE_HOST}" ] || die \ "本脚本只能在发布中枢 ${RELEASE_HOST} 上执行,当前在 ${CURRENT_HOST}; DS 任务请用:ssh ${RELEASE_USER}@${RELEASE_HOST} \"bash ${PROJECT_ROOT}/publish.sh\"" DEPLOY_DIR="${RELEASE_ROOT_DIR}/${PROJECT_NAME}" DATASOURCE_DIR="${RELEASE_ROOT_DIR}/datasource" log "发布中枢 ${RELEASE_HOST},目标节点:${WORKER_HOSTS[*]}" log "部署目录 ${DEPLOY_DIR}" # ---------- 1. 中枢 git 更新到 release ---------- [ -d "${DEPLOY_DIR}/.git" ] || die \ "部署目录不是 git 仓库:${DEPLOY_DIR} 首次需手工初始化(会丢弃现有目录内 gitignore 的内容,如 workspace/): cd ${RELEASE_ROOT_DIR} mv ${PROJECT_NAME} ${PROJECT_NAME}.bak git clone -b ${BRANCH} <仓库地址> ${PROJECT_NAME}" cd "${DEPLOY_DIR}" log "[1/5] git 更新到 ${BRANCH}" git checkout . # 丢弃开发期 rsync 推进来的脏改动 git fetch --prune git checkout "${BRANCH}" git pull --ff-only log " 当前版本 $(git rev-parse --short HEAD) $(git log -1 --format='%s')" # ---------- 2. 项目分发到各 worker ---------- log "[2/5] 分发项目到各 worker" for host in "${WORKER_HOSTS[@]}"; do log " -> ${host}" sudo rsync -az --delete \ --exclude='.git/' \ --exclude='__pycache__/' \ --exclude='*.pyc' \ --exclude='workspace/' \ --exclude='sessions/' \ --exclude='conf/datax/generated/' \ --exclude='conf/bak/' \ --exclude='launch-pad/' \ "${DEPLOY_DIR}/" "root@${host}:${DEPLOY_DIR}/" done # ---------- 3. datasource 分发(不入 git,只能靠 rsync) ---------- log "[3/5] 分发 datasource" [ -d "${DATASOURCE_DIR}" ] || die "datasource 目录不存在:${DATASOURCE_DIR}" for host in "${WORKER_HOSTS[@]}"; do log " -> ${host}" sudo rsync -az --delete "${DATASOURCE_DIR}/" "root@${host}:${DATASOURCE_DIR}/" done # ---------- 4. 清 dw_base.zip 缓存 ---------- log "[4/5] 清 dw_base.zip 缓存" rm -f "${DEPLOY_DIR}/dw_base.zip" for host in "${WORKER_HOSTS[@]}"; do sudo ssh "root@${host}" "rm -f ${DEPLOY_DIR}/dw_base.zip" done # ---------- 5. 权限 + 校验 ---------- log "[5/5] 修权限并校验各节点目录大小" chmod 775 "${DEPLOY_DIR}/publish.sh" chmod -R 775 "${DEPLOY_DIR}/bin" for host in "${WORKER_HOSTS[@]}"; do sudo ssh "root@${host}" "chmod -R 775 ${DEPLOY_DIR}/bin" done printf '%-16s %s\n' "${RELEASE_HOST}" "$(du -sh "${DEPLOY_DIR}" | cut -f1)" for host in "${WORKER_HOSTS[@]}"; do printf '%-16s %s\n' "${host}" "$(sudo ssh "root@${host}" "du -sh ${DEPLOY_DIR} | cut -f1")" done log "发布完毕:${BRANCH} @ $(git rev-parse --short HEAD)"