# 资金服务平台 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
```
这套配置完全适配资金服务平台的架构特点,特别处理了统一配置和个性化配置的分离管理。