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