# ERP Java Backend 部署文档

## 📁 目录结构

```
erp-java-backend/
├── docker-compose.yml                    # 全量Docker Compose（本地开发/测试）
├── infrastructure/
│   ├── kubernetes/
│   │   ├── erp-global-infra.yaml        # 全局K8s配置（ConfigMap/Secret/Ingress）
│   │   ├── erp-db-init-job.yaml         # 数据库初始化Job
│   │   └── kustomization.yaml           # Kustomization配置
│   └── mysql/
│       └── init.sql                      # 数据库初始化SQL
├── gateway/
│   └── docker/
│       ├── Dockerfile                    # API网关Dockerfile
│       └── docker-compose.yml            # 网关独立部署
└── services/
    ├── {service-name}/
    │   ├── Dockerfile                    # 多阶段构建Dockerfile
    │   ├── docker-compose.yml           # 服务独立部署
    │   └── k8s/
    │       └── deployment.yaml          # K8s完整部署（含HPA/PDB/Ingress）
```

## 🚀 快速开始

### 1. 本地Docker Compose启动（推荐开发测试用）

```bash
cd erp-java-backend

# 启动所有基础设施服务
docker-compose up -d mysql redis nacos

# 启动网关
docker-compose up -d gateway

# 按需启动业务服务
docker-compose up -d user-service product-service order-service
```

### 2. 本地构建并启动

```bash
# 构建所有服务镜像
docker-compose build

# 启动全部服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f user-service
```

### 3. 单服务独立部署

```bash
cd services/user-service

# 构建镜像
docker build -t erp-user-service:1.0.0 -f Dockerfile ../..

# 启动服务
docker-compose up -d

# 查看日志
docker logs -f erp-user-service
```

## ☸️ Kubernetes部署

### 前置要求
- Kubernetes 1.25+
- kubectl configured
- Ingress Controller (nginx-ingress)
- StorageClass (用于持久化存储)

### 部署步骤

```bash
# 1. 创建命名空间
kubectl apply -f infrastructure/kubernetes/erp-global-infra.yaml

# 2. 部署基础设施（MySQL/Redis/Nacos等）
#    参考 infrastructure/kubernetes/ 下的各服务配置

# 3. 部署业务服务
for svc in user product order inventory tenant; do
  kubectl apply -f services/${svc}-service/k8s/deployment.yaml
done

# 4. 使用Kustomization一键部署
kubectl apply -k infrastructure/kubernetes/

# 5. 验证部署
kubectl get pods -n erp-prod
kubectl get svc -n erp-prod
kubectl get ingress -n erp-prod
```

### HPA自动扩缩容

所有服务均已配置HPA，基于CPU和内存利用率自动扩缩：

```yaml
# 示例：user-service HPA配置
spec:
  minReplicas: 3      # 最小3个副本
  maxReplicas: 10    # 最大10个副本
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70   # CPU 70%时扩容
```

### PDB保护

所有服务配置了PodDisruptionBudget，保证滚动更新时最小可用副本数：

```bash
kubectl get pdb -n erp-prod
```

## 🔧 服务端口映射

| 服务 | 端口 | K8s Service | Ingress域名 |
|------|------|-------------|-------------|
| gateway | 8080 | gateway | api.erpzbbh.cn |
| user-service | 8082 | user-service | user.erpzbbh.cn |
| admin-service | 8081 | admin-service | admin.erpzbbh.cn |
| product-service | 8083 | product-service | product.erpzbbh.cn |
| tenant-service | 8083 | tenant-service | tenant.erpzbbh.cn |
| permission-service | 8084 | permission-service | permission.erpzbbh.cn |
| inventory-service | 8084 | inventory-service | inventory.erpzbbh.cn |
| order-service | 8082 | order-service | order.erpzbbh.cn |
| file-service | 8082 | file-service | file.erpzbbh.cn |
| scheduled-task-service | 8088 | scheduled-task-service | task.erpzbbh.cn |
| approval-flow-service | 8086 | approval-flow-service | approval.erpzbbh.cn |
| customer-service | 8086 | customer-service | customer.erpzbbh.cn |
| supplier-service | 8086 | supplier-service | supplier.erpzbbh.cn |
| invoice-service | 8086 | invoice-service | invoice.erpzbbh.cn |
| logistics-service | 8086 | logistics-service | logistics.erpzbbh.cn |
| waybill-service | 8086 | waybill-service | waybill.erpzbbh.cn |
| dashboard-service | 8086 | dashboard-service | dashboard.erpzbbh.cn |
| finance-service | 8007 | finance-service | finance.erpzbbh.cn |
| purchase-service | 8010 | purchase-service | purchase.erpzbbh.cn |
| reconciliation-service | 8018 | reconciliation-service | reconciliation.erpzbbh.cn |
| report-service | 8084 | report-service | report.erpzbbh.cn |
| sku-match-service | 8084 | sku-match-service | skumatch.erpzbbh.cn |
| notification-service | 8087 | notification-service | notification.erpzbbh.cn |
| system-tool-service | 8087 | system-tool-service | systemtool.erpzbbh.cn |
| print-service | 8089 | print-service | print.erpzbbh.cn |
| aftersale-service | 8087 | aftersale-service | aftersale.erpzbbh.cn |
| audit-log-service | 8098 | audit-log-service | audit.erpzbbh.cn |
| category-service | 8085 | category-service | category.erpzbbh.cn |
| data-import-export-service | 8088 | data-import-export-service | dataie.erpzbbh.cn |
| warehouse-service | 8084 | warehouse-service | warehouse.erpzbbh.cn |
| ai-service | 8087 | ai-service | ai.erpzbbh.cn |

## 🐳 Dockerfile规范

所有Dockerfile统一使用多阶段构建：

```dockerfile
# Stage 1: Build
FROM maven:3.9-eclipse-temurin-17-alpine AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline -B   # 利用Docker缓存
COPY . .
WORKDIR /app/services/{service}
RUN mvn clean package -DskipTests -B

# Stage 2: Runtime
FROM eclipse-temurin:17-jre-alpine
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/services/{service}/target/*.jar app.jar
RUN chown appuser:appgroup app.jar
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC"
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
    CMD wget -q --spider http://localhost:{port}/actuator/health || exit 1
EXPOSE {port}
USER appuser
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
```

## 🔍 健康检查

所有服务暴露以下健康检查端点：

- `/actuator/health` - 基础健康检查
- `/actuator/health/liveness` - K8s livenessProbe
- `/actuator/health/readiness` - K8s readinessProbe
- `/actuator/prometheus` - Prometheus监控指标

## 📊 资源限制

| 服务类型 | CPU Request | CPU Limit | Memory Request | Memory Limit |
|---------|-------------|-----------|----------------|--------------|
| 重量级服务 | 250m | 1000m | 512Mi | 1Gi |
| 轻量级服务 | 100m | 500m | 256Mi | 512Mi |
| 基础设施 | 100m | 500m | 256Mi | 512Mi |

## 🔐 安全配置

- 所有容器以非root用户运行 (UID 1001)
- 使用Alpine轻量级基础镜像
- 敏感配置通过K8s Secret注入
- 生产环境建议使用外部密钥管理（Vault/AWS Secrets Manager）

## 📝 数据库迁移

### K8s Job方式（推荐生产）

```bash
# 部署数据库初始化Job
kubectl apply -f infrastructure/kubernetes/erp-db-init-job.yaml

# 查看Job状态
kubectl get job erp-db-init -n erp-prod
kubectl logs job/erp-db-init -n erp-prod
```

### Docker Compose方式

```bash
# 初始化脚本会自动执行 init.sql
docker-compose up -d mysql
```

## 🌐 Ingress配置

所有服务均配置了TLS Ingress，示例：

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: user-service-ingress
  namespace: erp-prod
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - user-service.erpzbbh.cn
      secretName: user-service-tls
  rules:
    - host: user-service.erpzbbh.cn
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: user-service
                port:
                  name: http
```

## 🔧 故障排查

```bash
# 查看Pod日志
kubectl logs -f deployment/user-service -n erp-prod

# 进入Pod调试
kubectl exec -it deployment/user-service -n erp-prod -- sh

# 查看Pod事件
kubectl describe pod -n erp-prod -l app=user-service

# 查看资源使用
kubectl top pod -n erp-prod

# 重启Deployment
kubectl rollout restart deployment/user-service -n erp-prod

# 回滚到上一版本
kubectl rollout undo deployment/user-service -n erp-prod
```

## 📋 环境变量参考

| 变量名 | 说明 | 示例值 |
|--------|------|--------|
| SPRING_PROFILES_ACTIVE | 激活的配置环境 | prod |
| NACOS_SERVER_ADDR | Nacos地址 | nacos:8848 |
| NACOS_NAMESPACE | Nacos命名空间 | prod |
| DB_HOST | 数据库主机 | mysql |
| DB_PORT | 数据库端口 | 3306 |
| DB_NAME | 数据库名 | erp_java |
| DB_USERNAME | 数据库用户名 | erp_user |
| DB_PASSWORD | 数据库密码 | * |
| REDIS_HOST | Redis主机 | redis |
| REDIS_PORT | Redis端口 | 6379 |
| REDIS_PASSWORD | Redis密码 | * |
| JAVA_OPTS | JVM参数 | -Xms512m -Xmx1024m |
