#!/usr/bin/env bash # 须用 bash 执行 [ -n "${BASH_VERSION:-}" ] || exec /usr/bin/env bash "$0" ${1+"$@"} # 在 chat_web_backend 执行 mvn package,将产物复制为 backend/chat_web_yj.jar(与 backend-restart.sh 一致) # 日志:gangyan/logs/backend-pack.log set -euo pipefail source "$(cd "$(dirname "$0")" && pwd)/common-restart.sh" LOG_FILE="$LOG_DIR/backend-pack.log" if ! ( umask 022; : >>"$LOG_FILE" ) 2>/dev/null; then mkdir -p "${HOME}/.gangyan/logs" LOG_FILE="${HOME}/.gangyan/logs/backend-pack.log" fi export JAVA_HOME="${JAVA_HOME:-/usr/lib/jvm/java-11-openjdk-amd64}" export PATH="$JAVA_HOME/bin:$PATH" BACKEND_SRC="$GANGYAN_ROOT/chat_web_backend" JAR_BUILD="$BACKEND_SRC/target/chat_web_backend.jar" JAR_RUN="$GANGYAN_ROOT/backend/chat_web_yj.jar" log_tee() { log_line "$@" | tee -a "$LOG_FILE" } log_tee "======== 编译打包 Java 后端 ========" log_tee "JAVA_HOME=$JAVA_HOME" if ! command -v mvn >/dev/null 2>&1; then log_tee "错误: 未找到 mvn,请先安装 Maven 并加入 PATH" exit 1 fi if [ ! -f "$BACKEND_SRC/pom.xml" ]; then log_tee "错误: 未找到 $BACKEND_SRC/pom.xml" exit 1 fi mkdir -p "$GANGYAN_ROOT/backend" cd "$BACKEND_SRC" # 目标目录若被 root 生成,会导致普通用户无法写入(常见表现:Error while storing the mojo status)。 # 这里提前检测并给出可执行修复命令。 if [ -d "$BACKEND_SRC/target" ] && [ ! -w "$BACKEND_SRC/target" ]; then log_tee "错误: $BACKEND_SRC/target 不可写(可能之前用 root 打过包)。" log_tee "请执行其一后重试:" log_tee " 1) sudo chown -R $(id -un):$(id -gn) \"$BACKEND_SRC/target\"" log_tee " 2) sudo rm -rf \"$BACKEND_SRC/target\"" exit 1 fi # Maven 自身 JVM:内存过小会频繁 GC;可用 export MAVEN_OPTS='...' 覆盖 export MAVEN_OPTS="${MAVEN_OPTS:--Xmx1536m -XX:+TieredCompilation -XX:TieredStopAtLevel=1}" # 依赖已缓存在 ~/.m2 时: export MAVEN_OFFLINE=1(不访问远程仓库,失败则去掉再跑) MVN_OFFLINE=() if [ "${MAVEN_OFFLINE:-}" = "1" ]; then MVN_OFFLINE=(-o) log_tee "MAVEN_OFFLINE=1:使用 mvn -o(缓存不全会失败,去掉环境变量再跑一次)" fi # -------- 远程仓库预检:中央仓库/镜像太慢或不可达则直接退出,避免 mvn 长时间卡在 Downloading -------- # 跳过预检: export SKIP_MAVEN_NETCHECK=1 # 测速地址(默认与 pom 首选源一致:华为云): export MAVEN_NETCHECK_URL='https://mirrors.tencent.com/nexus/...' # 总耗时超过即视为过慢(秒): export MAVEN_NETCHECK_MAX_SEC=15 if [ "${MAVEN_OFFLINE:-}" != "1" ] && [ "${SKIP_MAVEN_NETCHECK:-}" != "1" ]; then if command -v curl >/dev/null 2>&1; then NET_URL="${MAVEN_NETCHECK_URL:-https://repo.huaweicloud.com/repository/maven/org/apache/maven/apache-maven/maven-metadata.xml}" # 判定「过慢」的耗时上限(秒);curl 单次请求上限单独设大些,便于测出真实耗时 MAX_SEC="${MAVEN_NETCHECK_MAX_SEC:-15}" CURL_MAX="${MAVEN_NETCHECK_CURL_MAX_SEC:-60}" log_tee "Maven 仓库预检(样本下载总耗时 > ${MAX_SEC}s 则中止;curl 上限 ${CURL_MAX}s): $NET_URL" # shellcheck disable=SC2086 OUT=$(curl -sS -o /dev/null -w '%{http_code} %{time_total} %{speed_download} %{size_download}' \ --connect-timeout 10 --max-time "$CURL_MAX" "$NET_URL" 2>/dev/null) || OUT="000 999 0 0" read -r CODE T_SEC SPD SZ <<< "$OUT" CODE=${CODE:-000} T_SEC=${T_SEC:-999} SPD=${SPD:-0} SZ=${SZ:-0} if [ "$CODE" != "200" ]; then log_tee "预检失败:HTTP $CODE,无法稳定访问该仓库。" log_tee "可选:① 配置 ~/.m2/settings.xml 镜像后设 MAVEN_NETCHECK_URL 指向镜像测速;② 依赖已在 ~/.m2 时 export MAVEN_OFFLINE=1 再打包;③ 仍要尝试 export SKIP_MAVEN_NETCHECK=1" exit 1 fi # 小文件平均速度易受握手影响,以「总耗时」为主;大文件再参考速度 if awk -v t="$T_SEC" -v m="$MAX_SEC" 'BEGIN { exit !(t + 0 > m + 0) }'; then log_tee "预检失败:下载耗时 ${T_SEC}s,超过 ${MAX_SEC}s(当前渠道过慢)。" log_tee "可选:① 换网络或配置国内镜像;② export MAVEN_OFFLINE=1(仅用本地缓存);③ export SKIP_MAVEN_NETCHECK=1 强制继续" exit 1 fi if awk -v sz="$SZ" -v spd="$SPD" 'BEGIN { exit !((sz + 0 > 8000) && (spd + 0 < 15000)) }'; then log_tee "预检失败:约 ${SZ}B 的样本下载平均仅 ${SPD} B/s,持续过慢。" log_tee "可选:配置镜像、MAVEN_OFFLINE=1 或 SKIP_MAVEN_NETCHECK=1(同上)" exit 1 fi log_tee "预检通过:HTTP $CODE,耗时 ${T_SEC}s,样本 ${SZ}B。" else log_tee "未找到 curl,跳过仓库预检(建议安装 curl,或设置 SKIP_MAVEN_NETCHECK=1)" fi elif [ "${MAVEN_OFFLINE:-}" = "1" ]; then log_tee "已 MAVEN_OFFLINE=1,跳过仓库网速预检。" elif [ "${SKIP_MAVEN_NETCHECK:-}" = "1" ]; then log_tee "已 SKIP_MAVEN_NETCHECK=1,跳过仓库网速预检。" fi # 默认跳过测试源码编译与执行(比仅 -DskipTests 更快)。要编译测试: export MAVEN_SKIP_TEST_COMPILE=0 if [ "${MAVEN_SKIP_TEST_COMPILE:-1}" = "1" ]; then TEST_SKIP=(-Dmaven.test.skip=true) log_tee "MAVEN_SKIP_TEST_COMPILE=1:使用 -Dmaven.test.skip=true(不编译 test 源码)" else TEST_SKIP=(-DskipTests) log_tee "MAVEN_SKIP_TEST_COMPILE=0:仅 -DskipTests(仍编译 test 源码)" fi # -T 1C:多核并行构建;单模块也有少量收益 # 无 javadoc/source 插件时跳过属性无害 # 依赖解析缓存“找不到”时可强制刷新:export MAVEN_FORCE_UPDATE=1(等价 mvn -U) MVN_UPDATE=() if [ "${MAVEN_FORCE_UPDATE:-0}" = "1" ]; then MVN_UPDATE=(-U) log_tee "MAVEN_FORCE_UPDATE=1:使用 mvn -U(强制刷新依赖解析缓存)" fi log_tee "执行: mvn ${MVN_OFFLINE[*]} ${MVN_UPDATE[*]} -T 1C ${TEST_SKIP[*]} -Dmaven.javadoc.skip=true -Dmaven.source.skip=true package" set -o pipefail mvn "${MVN_OFFLINE[@]}" "${MVN_UPDATE[@]}" -T 1C "${TEST_SKIP[@]}" -Dmaven.javadoc.skip=true -Dmaven.source.skip=true package 2>&1 | tee -a "$LOG_FILE" if [ ! -f "$JAR_BUILD" ]; then log_tee "错误: 未生成 $JAR_BUILD" exit 1 fi cp -f "$JAR_BUILD" "$JAR_RUN" log_tee "已复制: $JAR_BUILD -> $JAR_RUN" ls -lh "$JAR_RUN" | tee -a "$LOG_FILE" log_tee "完成。需要重启进程请执行: ./backend-restart.sh"