658 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 资金服务平台 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
<build>
<plugins>
<!-- Spring Boot插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${main.class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Assembly插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
<finalName>${project.artifactId}</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<!-- 从service.properties读取主类 -->
<main.class>${service.main.class}</main.class>
</properties>
```
### 项目级Assembly Descriptor
```xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0
http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>dist</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<!-- bin目录使用项目根目录统一脚本 -->
<fileSet>
<directory>${project.basedir}/../../scripts</directory>
<outputDirectory>bin</outputDirectory>
<includes>
<include>start.sh</include>
<include>stop.sh</include>
<include>restart.sh</include>
<include>status.sh</include>
</includes>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
</fileSet>
<!-- 统一配置文件 -->
<fileSet>
<directory>${project.basedir}/../../scripts</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>env.properties</include>
</includes>
<fileMode>0644</fileMode>
</fileSet>
<!-- 服务个性化配置 -->
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>conf</outputDirectory>
<includes>
<include>service.properties</include>
<include>application.yml</include>
<include>application-*.yml</include>
<include>logback-spring.xml</include>
</includes>
<fileMode>0644</fileMode>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<scope>runtime</scope>
<fileMode>0644</fileMode>
</dependencySet>
</dependencySets>
</assembly>
```
## 配置文件加载机制
### 启动脚本中的配置加载顺序
```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
```
这套配置完全适配资金服务平台的架构特点,特别处理了统一配置和个性化配置的分离管理。