# 资金服务平台 Assembly 配置参考 ## 项目专用配置详解 ### 部署目录管理实践 **核心原则**:所有部署打包文件统一存储在项目根目录的 `deploy/` 目录下,实现开发代码与部署产物的物理分离。 ``` fundplatform/ ├── deploy/ # 部署产物目录(核心实践) │ ├── fund-gateway.tar.gz # 网关服务部署包 │ ├── fund-sys.tar.gz # 系统服务部署包 │ ├── fund-cust.tar.gz # 客户服务部署包 │ └── ... 其他服务部署包 ├── scripts/ # 统一脚本和配置 └── 各服务源代码目录 # 开发代码(与部署分离) ``` **实践优势**: - **物理分离**:开发代码与部署产物完全隔离 - **版本管理**:便于CI/CD流水线统一管理部署包 - **权限控制**:可以对部署目录设置不同的访问权限 - **清理维护**:易于批量清理旧版本部署包 ### 统一配置文件管理 #### scripts/env.properties 配置 这是所有服务共享的统一配置文件,包含基础设施配置: ```properties # ============================================ # 环境变量配置文件(所有服务共用) # ============================================ # Nacos配置 NACOS_SERVER_ADDR=localhost:8848 NACOS_NAMESPACE=fund-platform NACOS_GROUP=DEFAULT_GROUP NACOS_USERNAME=nacos NACOS_PASSWORD=nacos # Redis配置 REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=zjf@123456 REDIS_DATABASE=0 # 数据库连接池 HIKARI_MINIMUM_IDLE=5 HIKARI_CONNECTION_TIMEOUT=30000 # 日志配置 LOG_HOME=/datacfs/applogs LOG_LEVEL_ROOT=INFO LOG_LEVEL_APP=DEBUG # 多租户配置 TENANT_ROUTING_ENABLED=true DEFAULT_TENANT_ID=1 # 腾讯云COS COS_ENABLED=true COS_SECRET_ID=your-secret-id COS_SECRET_KEY=your-secret-key ``` #### 服务个性化配置 (service.properties) 每个服务必须包含的最小配置: ```properties # ============================================ # 服务个性化配置 # ============================================ # 必需参数 APP_NAME=fund-sys # 服务名称(必须) MAIN_CLASS=com.fundplatform.sys.SysApplication # 主启动类(必须) # 可选参数 INSTANCE_NAME= # 实例名称(默认等于APP_NAME) TENANT_ID= # 租户ID(空=共享实例) SERVER_PORT=8100 # 服务端口(可选) ``` ### 完整的pom.xml插件配置 ```xml org.springframework.boot spring-boot-maven-plugin ${main.class} ZIP repackage org.apache.maven.plugins maven-assembly-plugin 3.3.0 src/main/assembly/assembly.xml ${project.artifactId} false make-assembly package single ${service.main.class} ``` ### 项目级Assembly Descriptor ```xml dist tar.gz true ${project.basedir}/../../scripts bin start.sh stop.sh restart.sh status.sh 0755 0755 ${project.basedir}/../../scripts conf env.properties 0644 src/main/resources conf service.properties application.yml application-*.yml logback-spring.xml 0644 lib true true runtime 0644 ``` ## 配置文件加载机制 ### 启动脚本中的配置加载顺序 ```bash #!/bin/bash # 配置加载的核心逻辑 APP_HOME=$(cd "$(dirname "$0")/.." && pwd) # 1. 加载统一配置(基础环境) load_properties() { local file=$1 if [[ -f "$file" ]]; then while IFS='=' read -r key value; do # 跳过空行和注释 [[ -z "$key" || "$key" =~ ^[[:space:]]*# ]] && continue # 导出环境变量 export "$key=$value" done < "$file" fi } # 加载顺序:先统一配置,后个性化配置(后者覆盖前者) load_properties "${APP_HOME}/conf/env.properties" load_properties "${APP_HOME}/conf/service.properties" # 设置默认值 APP_NAME=${APP_NAME:-"unknown-service"} INSTANCE_NAME=${INSTANCE_NAME:-${APP_NAME}} TENANT_ID=${TENANT_ID:-""} ``` ### 配置验证脚本 ```bash #!/bin/bash # validate-service-config.sh APP_HOME=$(cd "$(dirname "$0")/.." && pwd) CONFIG_DIR="${APP_HOME}/conf" echo "=== 服务配置验证 ===" # 1. 检查配置文件存在性 CONFIG_FILES=("env.properties" "service.properties" "application.yml") for file in "${CONFIG_FILES[@]}"; do if [[ -f "${CONFIG_DIR}/${file}" ]]; then echo "✓ ${file}" else echo "✗ ${file} (缺失)" exit 1 fi done # 2. 验证service.properties必需参数 SERVICE_CONF="${CONFIG_DIR}/service.properties" REQUIRED_PARAMS=("APP_NAME" "MAIN_CLASS") echo "验证必需参数:" for param in "${REQUIRED_PARAMS[@]}"; do if grep -q "^${param}=" "${SERVICE_CONF}"; then value=$(grep "^${param}=" "${SERVICE_CONF}" | cut -d'=' -f2 | xargs) echo "✓ ${param}=${value}" else echo "✗ 缺少必需参数: ${param}" exit 1 fi done # 3. 验证JAR文件 JAR_PATTERN="${APP_NAME}*.jar" JAR_FILE=$(find "${APP_HOME}/lib" -name "${JAR_PATTERN}" 2>/dev/null | head -1) if [[ -n "$JAR_FILE" ]]; then echo "✓ 服务JAR: $(basename $JAR_FILE)" else echo "✗ 未找到服务JAR文件: ${JAR_PATTERN}" exit 1 fi echo "配置验证通过!" ``` ## 多租户配置支持 ### 共享实例配置 ```properties # service.properties APP_NAME=fund-sys INSTANCE_NAME=fund-sys TENANT_ID= ``` ### VIP专属实例配置 ```properties # service.properties APP_NAME=fund-sys INSTANCE_NAME=fund-sys-vip001 TENANT_ID=vip001 ``` ### 启动脚本多租户支持 ```bash # 根据TENANT_ID设置不同的Nacos元数据 if [[ -n "${TENANT_ID}" ]]; then JAVA_OPTS="$JAVA_OPTS -Dspring.cloud.nacos.discovery.metadata.tenant=${TENANT_ID}" echo "启动VIP实例: ${INSTANCE_NAME} (租户: ${TENANT_ID})" else echo "启动共享实例: ${INSTANCE_NAME}" fi ``` ## 构建自动化脚本 ### 批量构建脚本 (scripts/services-build.sh) ```bash #!/bin/bash # 资金服务平台批量构建脚本 - 统一输出到deploy目录 set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="${SCRIPT_DIR}" DEPLOY_DIR="${PROJECT_ROOT}/deploy" # 服务列表(按依赖顺序) SERVICES=( "fund-gateway" "fund-sys" "fund-cust" "fund-proj" "fund-exp" "fund-receipt" "fund-report" "fund-req" "fund-file" ) # 部署目录管理 setup_deploy_directory() { echo "=== 部署目录管理 ===" # 创建部署目录 mkdir -p "${DEPLOY_DIR}" echo "✓ 部署目录: ${DEPLOY_DIR}" # 显示当前部署包 echo "当前部署包:" if ls "${DEPLOY_DIR}"/*.tar.gz >/dev/null 2>&1; then ls -lh "${DEPLOY_DIR}"/*.tar.gz else echo " (无)" fi # 询问是否清理旧包 echo "" read -p "是否清理旧的部署包? (y/N): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then rm -f "${DEPLOY_DIR}"/*.tar.gz echo "✓ 已清理旧部署包" fi echo "" } # 构建单个服务 build_service() { local service=$1 local service_dir="${PROJECT_ROOT}/${service}" local start_time=$(date +%s) echo "=== 构建服务: ${service} ===" # 检查服务目录 if [ ! -d "${service_dir}" ]; then echo "警告: 服务目录不存在 ${service_dir}" return 1 fi cd "${service_dir}" # 清理并构建 echo "清理并构建..." mvn clean package -DskipTests -q # 查找生成的tar.gz文件 local tar_file=$(find target -name "${service}-*.tar.gz" | head -1) if [ -n "${tar_file}" ]; then # 复制到统一部署目录 cp "${tar_file}" "${DEPLOY_DIR}/" local end_time=$(date +%s) local duration=$((end_time - start_time)) local file_size=$(du -h "${tar_file}" | cut -f1) echo "✓ ${service} 构建成功 (${duration}秒, ${file_size})" echo " 输出到统一部署目录: ${DEPLOY_DIR}/$(basename ${tar_file})" else echo "✗ ${service} 构建失败:未找到tar.gz文件" return 1 fi } # 部署包验证 validate_deployment_packages() { echo "" echo "=== 部署包验证 ===" local package_count=0 local total_size=0 for tar_file in "${DEPLOY_DIR}"/*.tar.gz; do if [[ -f "${tar_file}" ]]; then local file_size=$(du -m "${tar_file}" | cut -f1) total_size=$((total_size + file_size)) ((package_count++)) # 基本验证 if tar -tzf "${tar_file}" >/dev/null 2>&1; then echo "✓ $(basename ${tar_file}) [${file_size}MB]" else echo "✗ $(basename ${tar_file}) [损坏]" return 1 fi fi done echo "" echo "总计: ${package_count}个部署包, ${total_size}MB" } # 主构建流程 main() { local total_start=$(date +%s) echo "=========================================" echo " 资金服务平台批量构建" echo " 部署目录: ${DEPLOY_DIR}" echo "=========================================" echo "项目根目录: ${PROJECT_ROOT}" echo "服务数量: ${#SERVICES[@]}" echo "" # 设置部署目录 setup_deploy_directory local success_count=0 local fail_count=0 # 逐个构建服务 for service in "${SERVICES[@]}"; do if build_service "${service}"; then ((success_count++)) else ((fail_count++)) fi echo "" done local total_end=$(date +%s) local total_duration=$((total_end - total_start)) echo "=========================================" echo "构建完成统计:" echo " 成功: ${success_count}" echo " 失败: ${fail_count}" echo " 总耗时: ${total_duration}秒" echo "" if [ ${fail_count} -eq 0 ]; then echo "✓ 所有服务构建成功!" validate_deployment_packages echo "" echo "部署包位置: ${DEPLOY_DIR}" ls -lh "${DEPLOY_DIR}"/*.tar.gz else echo "✗ ${fail_count}个服务构建失败" exit 1 fi } # 执行主函数 main "$@" ``` ## 部署包验证脚本 ### 完整性检查 (scripts/validate-deployment.sh) ```bash #!/bin/bash # 部署包完整性验证脚本 validate_package() { local tar_file=$1 local service_name=$(basename "${tar_file}" .tar.gz) echo "=== 验证部署包: ${service_name} ===" # 1. 检查基本结构 echo "目录结构检查:" local structure_ok=true local required_dirs=("bin" "lib" "conf") for dir in "${required_dirs[@]}"; do if tar -tzf "${tar_file}" | grep -q "^${service_name}/${dir}/"; then echo "✓ ${dir}/ 目录存在" else echo "✗ ${dir}/ 目录缺失" structure_ok=false fi done # 2. 检查必需文件 echo "必需文件检查:" local required_files=( "bin/start.sh" "bin/stop.sh" "conf/env.properties" "conf/service.properties" "conf/application.yml" "lib/${service_name}*.jar" ) local files_ok=true for file_pattern in "${required_files[@]}"; do if tar -tzf "${tar_file}" | grep -q "^${service_name}/${file_pattern}"; then echo "✓ ${file_pattern}" else echo "✗ ${file_pattern} (缺失)" files_ok=false fi done # 3. 检查脚本权限 echo "脚本权限检查:" local scripts=$(tar -tzf "${tar_file}" | grep "^${service_name}/bin/.*\.sh$") for script in ${scripts}; do echo "✓ ${script} (可执行)" done # 4. 验证配置参数 echo "配置参数验证:" local temp_dir=$(mktemp -d) tar -xzf "${tar_file}" -C "${temp_dir}" # 检查service.properties必需参数 local service_conf="${temp_dir}/${service_name}/conf/service.properties" if [[ -f "${service_conf}" ]]; then local required_params=("APP_NAME" "MAIN_CLASS") for param in "${required_params[@]}"; do if grep -q "^${param}=" "${service_conf}"; then local value=$(grep "^${param}=" "${service_conf}" | cut -d'=' -f2 | xargs) echo "✓ ${param}=${value}" else echo "✗ 缺少参数: ${param}" files_ok=false fi done fi # 清理临时目录 rm -rf "${temp_dir}" # 最终结果 if [[ "${structure_ok}" == true && "${files_ok}" == true ]]; then echo "" echo "✓ ${service_name} 部署包验证通过" return 0 else echo "" echo "✗ ${service_name} 部署包验证失败" return 1 fi } # 主函数 main() { local deploy_dir="/home/along/MyCode/wanjiabuluo/fundplatform/deploy" if [ ! -d "${deploy_dir}" ]; then echo "错误: 部署目录不存在 ${deploy_dir}" exit 1 fi echo "扫描部署包: ${deploy_dir}" echo "" local success_count=0 local fail_count=0 for tar_file in "${deploy_dir}"/*.tar.gz; do if [[ -f "${tar_file}" ]]; then if validate_package "${tar_file}"; then ((success_count++)) else ((fail_count++)) fi echo "" fi done echo "=== 验证完成 ===" echo "成功: ${success_count}" echo "失败: ${fail_count}" if [ ${fail_count} -gt 0 ]; then exit 1 fi } main "$@" ``` ## 故障排除指南 ### 常见问题及解决方案 1. **配置文件缺失** ```bash # 检查配置文件 find . -name "env.properties" find . -name "service.properties" # 验证必需参数 grep -E "^(APP_NAME|MAIN_CLASS)=" fund-*/src/main/resources/service.properties ``` 2. **构建失败** ```bash # 清理并重新构建 mvn clean compile -X # 详细日志 mvn dependency:tree # 检查依赖冲突 ``` 3. **部署包结构异常** ```bash # 检查tar.gz内容 tar -tzf target/fund-sys.tar.gz | head -20 # 验证目录结构 scripts/validate-deployment.sh ``` 4. **启动脚本问题** ```bash # 测试配置加载 bash -x bin/start.sh # 调试模式 # 检查环境变量 echo $APP_NAME echo $MAIN_CLASS ``` 这套配置完全适配资金服务平台的架构特点,特别处理了统一配置和个性化配置的分离管理。