diff --git a/project_progress.md b/project_progress.md index cd7dc77..ea0ad2d 100644 --- a/project_progress.md +++ b/project_progress.md @@ -21,7 +21,7 @@ | `water_biz_module_design.md` | ✅ 已完成 | 100% | A级 | 2024-12-19 | 已完成代码示例优化,符合概要设计标准 | | `water_biz_database_design.md` | ✅ 已完成 | 100% | A+级 | 2024-12-19 | 已适配OpenGauss,完整DDL和安全设计 | | `water_biz_interface_design.md` | ✅ 已完成 | 100% | A级 | 2024-12-19 | 已补充详细接口参数、代码示例和安全设计 | -| `water_biz_deployment_design.md` | ✅ 已完成 | 100% | A级 | 2024-12-19 | 已补充容器化部署方案和自动化脚本 | +| `water_biz_deployment_design.md` | ✅ 已完成 | 100% | A级 | 2024-12-19 | 已适配OpenGauss,专注Docker Compose部署 | | `water_biz_security_design.md` | ✅ 已完成 | 100% | A级 | 2024-12-19 | 等保三级安全设计,基于OpenGauss | ### 补充文档 (可选交付) @@ -113,6 +113,8 @@ | 2024-12-19 | 需求调整 | 移除代码示例相关要求 | 甲方明确不需要代码示例 | 正面影响,聚焦架构设计 | | 2024-12-19 | 文档优化 | 优化模块设计文档,清理过于详细的代码示例 | 概要设计应保持适当抽象层次 | 正面影响,符合概要设计标准 | | 2024-12-19 | 项目完成 | 所有核心文档已完成并达到A级标准 | 按计划完成所有交付物 | 正面影响,项目成功交付 | +| 2024-12-19 | 架构统一 | 部署设计文档统一使用OpenGauss数据库 | 确保文档架构一致性 | 正面影响,提升技术方案统一性 | +| 2024-12-19 | 部署优化 | 移除Kubernetes配置,专注Docker Compose | 甲方需求简化部署方案 | 正面影响,降低部署复杂度 | ## 项目完成总结 diff --git a/water_biz_deployment_design.md b/water_biz_deployment_design.md index bda559e..a0779d1 100644 --- a/water_biz_deployment_design.md +++ b/water_biz_deployment_design.md @@ -8,7 +8,7 @@ | **技术框架** | RuoYi-Vue-Pro + yudao-ui-admin-vue3 | | **文档版本** | v1.0 | | **编写日期** | 2024-12-19 | -| **文档状态** | 🟡 进行中 | +| **文档状态** | ✅ 已完成 | ## 目录 - [1. 部署概述](#1-部署概述) @@ -148,8 +148,8 @@ #### 3.2.2 数据库 -- MySQL 5.7+ 或 MariaDB 10.2+(推荐) -- 国产数据库可选:OpenGauss、达梦等 +- OpenGauss 5.0+(推荐,国产自主可控) +- 兼容:PostgreSQL 13+、MySQL 8.0+ #### 3.2.3 应用服务器 @@ -357,29 +357,29 @@ version: '3.8' services: - # MySQL 数据库 - water-mysql: - image: mysql:8.0 - container_name: water-mysql + # OpenGauss 数据库 + water-opengauss: + image: enmotech/opengauss:5.0.0 + container_name: water-opengauss restart: always environment: - MYSQL_ROOT_PASSWORD: "water_root_2024" - MYSQL_DATABASE: "ruoyi_water" - MYSQL_USER: "water_user" - MYSQL_PASSWORD: "water_pass_2024" + GS_PASSWORD: "Water@2024" + GS_DB: "ruoyi_water" + GS_USERNAME: "water_user" TZ: "Asia/Shanghai" volumes: - - ./data/mysql:/var/lib/mysql + - ./data/opengauss:/var/lib/opengauss - ./sql:/docker-entrypoint-initdb.d - - ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf + - ./config/opengauss:/opt/opengauss/config ports: - - "3306:3306" - command: - - --character-set-server=utf8mb4 - - --collation-server=utf8mb4_unicode_ci - - --default-time-zone=+8:00 + - "5432:5432" networks: - water-network + healthcheck: + test: ["CMD-SHELL", "gs_ctl status -D /var/lib/opengauss/data"] + interval: 30s + timeout: 10s + retries: 3 # Redis 缓存 water-redis: @@ -403,13 +403,13 @@ services: container_name: water-server restart: always depends_on: - - water-mysql + - water-opengauss - water-redis environment: - SPRING_PROFILES_ACTIVE=prod - - SPRING_DATASOURCE_URL=jdbc:mysql://water-mysql:3306/ruoyi_water?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + - SPRING_DATASOURCE_URL=jdbc:opengauss://water-opengauss:5432/ruoyi_water?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 - SPRING_DATASOURCE_USERNAME=water_user - - SPRING_DATASOURCE_PASSWORD=water_pass_2024 + - SPRING_DATASOURCE_PASSWORD=Water@2024 - SPRING_REDIS_HOST=water-redis - SPRING_REDIS_PORT=6379 - SERVER_PORT=8080 @@ -480,7 +480,7 @@ networks: driver: bridge volumes: - mysql-data: + opengauss-data: redis-data: minio-data: ``` @@ -550,301 +550,206 @@ EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` -### 8.2 Kubernetes部署 +### 8.2 Docker Compose高级配置 -#### 8.2.1 命名空间配置 +#### 8.2.1 生产环境配置优化 + +**Docker Compose生产环境配置文件**: ```yaml -# k8s/namespace.yaml -apiVersion: v1 -kind: Namespace -metadata: - name: water-system - labels: - name: water-system +# docker-compose.prod.yml +version: '3.8' + +services: + water-opengauss: + image: enmotech/opengauss:5.0.0 + container_name: water-opengauss-prod + restart: unless-stopped + environment: + GS_PASSWORD: "${DB_PASSWORD:-Water@2024!}" + GS_DB: "ruoyi_water" + GS_USERNAME: "water_user" + TZ: "Asia/Shanghai" + volumes: + - opengauss-prod-data:/var/lib/opengauss + - ./config/opengauss/prod:/opt/opengauss/config + - ./backups:/backups + ports: + - "5432:5432" + networks: + - water-prod-network + deploy: + resources: + limits: + memory: 2G + cpus: '2.0' + healthcheck: + test: ["CMD-SHELL", "gs_ctl status -D /var/lib/opengauss/data"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + + water-redis: + image: redis:7.0-alpine + container_name: water-redis-prod + restart: unless-stopped + command: redis-server /etc/redis/redis.conf --requirepass ${REDIS_PASSWORD:-water_redis_2024} + volumes: + - redis-prod-data:/data + - ./config/redis/prod.conf:/etc/redis/redis.conf + ports: + - "6379:6379" + networks: + - water-prod-network + deploy: + resources: + limits: + memory: 512M + cpus: '1.0' + + water-server: + image: water-server:${VERSION:-latest} + container_name: water-server-prod + restart: unless-stopped + depends_on: + water-opengauss: + condition: service_healthy + water-redis: + condition: service_started + environment: + - SPRING_PROFILES_ACTIVE=prod + - SPRING_DATASOURCE_URL=jdbc:opengauss://water-opengauss:5432/ruoyi_water + - SPRING_DATASOURCE_USERNAME=water_user + - SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD:-Water@2024!} + - SPRING_REDIS_HOST=water-redis + - SPRING_REDIS_PASSWORD=${REDIS_PASSWORD:-water_redis_2024} + - SERVER_PORT=8080 + - JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC + volumes: + - ./logs/prod:/app/logs + - ./upload/prod:/app/upload + - ./config/app:/app/config + networks: + - water-prod-network + deploy: + resources: + limits: + memory: 3G + cpus: '2.0' + replicas: 2 + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] + interval: 30s + timeout: 10s + retries: 3 + + water-nginx: + image: nginx:1.24-alpine + container_name: water-nginx-prod + restart: unless-stopped + depends_on: + - water-server + volumes: + - ./config/nginx/prod.conf:/etc/nginx/nginx.conf + - ./config/nginx/conf.d:/etc/nginx/conf.d + - ./ssl:/etc/nginx/ssl + - ./logs/nginx:/var/log/nginx + - ./static:/usr/share/nginx/html + ports: + - "80:80" + - "443:443" + networks: + - water-prod-network + deploy: + resources: + limits: + memory: 256M + cpus: '0.5' + +networks: + water-prod-network: + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 + +volumes: + opengauss-prod-data: + driver: local + redis-prod-data: + driver: local ``` -#### 8.2.2 MySQL部署配置 +#### 8.2.2 环境变量配置 -```yaml -# k8s/mysql-deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: water-mysql - namespace: water-system -spec: - replicas: 1 - selector: - matchLabels: - app: water-mysql - template: - metadata: - labels: - app: water-mysql - spec: - containers: - - name: mysql - image: mysql:8.0 - env: - - name: MYSQL_ROOT_PASSWORD - value: "water_root_2024" - - name: MYSQL_DATABASE - value: "ruoyi_water" - - name: MYSQL_USER - value: "water_user" - - name: MYSQL_PASSWORD - value: "water_pass_2024" - - name: TZ - value: "Asia/Shanghai" - ports: - - containerPort: 3306 - volumeMounts: - - name: mysql-storage - mountPath: /var/lib/mysql - - name: mysql-config - mountPath: /etc/mysql/conf.d - volumes: - - name: mysql-storage - persistentVolumeClaim: - claimName: mysql-pvc - - name: mysql-config - configMap: - name: mysql-config +```bash +# .env.prod +# 数据库配置 +DB_PASSWORD=Water@2024!Production +DB_HOST=water-opengauss +DB_PORT=5432 +DB_NAME=ruoyi_water ---- -apiVersion: v1 -kind: Service -metadata: - name: water-mysql-service - namespace: water-system -spec: - selector: - app: water-mysql - ports: - - protocol: TCP - port: 3306 - targetPort: 3306 - type: ClusterIP +# Redis配置 +REDIS_PASSWORD=WaterRedis@2024!Production +REDIS_HOST=water-redis +REDIS_PORT=6379 ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: mysql-pvc - namespace: water-system -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 20Gi - storageClassName: fast-ssd +# 应用配置 +APP_VERSION=1.0.0 +JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError + +# 网络配置 +NGINX_PORT=80 +NGINX_SSL_PORT=443 + +# 日志级别 +LOG_LEVEL=INFO +LOG_ROOT_LEVEL=WARN ``` -#### 8.2.3 Redis部署配置 +#### 8.2.3 监控集成 ```yaml -# k8s/redis-deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: water-redis - namespace: water-system -spec: - replicas: 1 - selector: - matchLabels: - app: water-redis - template: - metadata: - labels: - app: water-redis - spec: - containers: - - name: redis - image: redis:7.0-alpine - ports: - - containerPort: 6379 - volumeMounts: - - name: redis-storage - mountPath: /data - - name: redis-config - mountPath: /etc/redis - command: - - redis-server - - /etc/redis/redis.conf - volumes: - - name: redis-storage - persistentVolumeClaim: - claimName: redis-pvc - - name: redis-config - configMap: - name: redis-config +# docker-compose.monitoring.yml +version: '3.8' ---- -apiVersion: v1 -kind: Service -metadata: - name: water-redis-service - namespace: water-system -spec: - selector: - app: water-redis - ports: - - protocol: TCP - port: 6379 - targetPort: 6379 - type: ClusterIP +services: + prometheus: + image: prom/prometheus:latest + container_name: water-prometheus + restart: unless-stopped + volumes: + - ./config/prometheus:/etc/prometheus + - prometheus-data:/prometheus + ports: + - "9090:9090" + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--web.console.libraries=/etc/prometheus/console_libraries' + - '--web.console.templates=/etc/prometheus/consoles' + networks: + - water-network ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: redis-pvc - namespace: water-system -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi - storageClassName: fast-ssd -``` + grafana: + image: grafana/grafana:latest + container_name: water-grafana + restart: unless-stopped + environment: + - GF_SECURITY_ADMIN_PASSWORD=admin123 + volumes: + - grafana-data:/var/lib/grafana + - ./config/grafana:/etc/grafana/provisioning + ports: + - "3000:3000" + networks: + - water-network -#### 8.2.4 应用服务部署配置 - -```yaml -# k8s/water-server-deployment.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: water-server - namespace: water-system -spec: - replicas: 3 - selector: - matchLabels: - app: water-server - template: - metadata: - labels: - app: water-server - spec: - containers: - - name: water-server - image: water-server:latest - ports: - - containerPort: 8080 - env: - - name: SPRING_PROFILES_ACTIVE - value: "k8s" - - name: SPRING_DATASOURCE_URL - value: "jdbc:mysql://water-mysql-service:3306/ruoyi_water?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" - - name: SPRING_DATASOURCE_USERNAME - value: "water_user" - - name: SPRING_DATASOURCE_PASSWORD - value: "water_pass_2024" - - name: SPRING_REDIS_HOST - value: "water-redis-service" - - name: SPRING_REDIS_PORT - value: "6379" - resources: - requests: - memory: "512Mi" - cpu: "250m" - limits: - memory: "1Gi" - cpu: "500m" - livenessProbe: - httpGet: - path: /actuator/health - port: 8080 - initialDelaySeconds: 60 - periodSeconds: 30 - readinessProbe: - httpGet: - path: /actuator/health - port: 8080 - initialDelaySeconds: 30 - periodSeconds: 10 - volumeMounts: - - name: upload-storage - mountPath: /app/upload - volumes: - - name: upload-storage - persistentVolumeClaim: - claimName: upload-pvc - ---- -apiVersion: v1 -kind: Service -metadata: - name: water-server-service - namespace: water-system -spec: - selector: - app: water-server - ports: - - protocol: TCP - port: 8080 - targetPort: 8080 - type: ClusterIP - ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: upload-pvc - namespace: water-system -spec: - accessModes: - - ReadWriteMany - resources: - requests: - storage: 10Gi - storageClassName: standard -``` - -#### 8.2.5 Ingress配置 - -```yaml -# k8s/ingress.yaml -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: water-system-ingress - namespace: water-system - annotations: - kubernetes.io/ingress.class: nginx - nginx.ingress.kubernetes.io/ssl-redirect: "true" - nginx.ingress.kubernetes.io/proxy-body-size: 50m - nginx.ingress.kubernetes.io/proxy-connect-timeout: "600" - nginx.ingress.kubernetes.io/proxy-send-timeout: "600" - nginx.ingress.kubernetes.io/proxy-read-timeout: "600" -spec: - tls: - - hosts: - - water.example.com - secretName: water-tls-secret - rules: - - host: water.example.com - http: - paths: - - path: /admin-api - pathType: Prefix - backend: - service: - name: water-server-service - port: - number: 8080 - - path: / - pathType: Prefix - backend: - service: - name: water-ui-service - port: - number: 80 +volumes: + prometheus-data: + grafana-data: ``` ### 8.3 自动化部署脚本 @@ -872,25 +777,50 @@ fi # 创建必要目录 echo "创建数据目录..." -mkdir -p data/{mysql,redis,minio} +mkdir -p data/{opengauss,redis,minio} mkdir -p logs/{app,nginx} -mkdir -p config/{mysql,redis,nginx/conf.d} +mkdir -p config/{opengauss,redis,nginx/conf.d} mkdir -p upload mkdir -p ssl +mkdir -p backups -# 设置MySQL配置 -echo "配置MySQL..." -cat > config/mysql/my.cnf << EOF -[mysqld] -character-set-server=utf8mb4 -collation-server=utf8mb4_unicode_ci -default-time-zone='+8:00' -max_connections=1000 -innodb_buffer_pool_size=512M -innodb_log_file_size=128M -slow_query_log=1 -slow_query_log_file=/var/lib/mysql/slow.log -long_query_time=3 +# 设置OpenGauss配置 +echo "配置OpenGauss..." +cat > config/opengauss/postgresql.conf << EOF +# 数据库连接配置 +max_connections = 1000 +port = 5432 +listen_addresses = '*' + +# 内存配置 +shared_buffers = 512MB +work_mem = 4MB +maintenance_work_mem = 128MB + +# WAL配置 +wal_level = replica +max_wal_size = 2GB +min_wal_size = 128MB + +# 日志配置 +log_destination = 'stderr' +logging_collector = on +log_directory = 'pg_log' +log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' +log_min_duration_statement = 3000 + +# 性能优化 +effective_cache_size = 1GB +random_page_cost = 1.1 +seq_page_cost = 1.0 +EOF + +cat > config/opengauss/pg_hba.conf << EOF +# TYPE DATABASE USER ADDRESS METHOD +local all all trust +host all all 127.0.0.1/32 md5 +host all all ::1/128 md5 +host all all 0.0.0.0/0 md5 EOF # 设置Redis配置 @@ -951,7 +881,8 @@ EOF cat > config/nginx/conf.d/water.conf << EOF upstream water_backend { - server water-server:8080; + server water-server:8080 max_fails=3 fail_timeout=30s; + keepalive 32; } server { @@ -1003,73 +934,129 @@ echo "停止服务: docker-compose down" echo "重启服务: docker-compose restart" ``` -#### 8.3.2 Kubernetes部署脚本 +#### 8.3.2 生产环境部署脚本 ```bash #!/bin/bash -# deploy-k8s.sh +# deploy-prod.sh set -e -echo "=== 福建水务营收系统 Kubernetes 部署脚本 ===" +echo "=== 福建水务营收系统 生产环境部署脚本 ===" -# 检查kubectl环境 -if ! command -v kubectl &> /dev/null; then - echo "错误: kubectl未安装,请先安装kubectl" +# 检查环境 +if ! command -v docker &> /dev/null; then + echo "错误: Docker未安装,请先安装Docker" exit 1 fi -# 检查集群连接 -if ! kubectl cluster-info &> /dev/null; then - echo "错误: 无法连接到Kubernetes集群" +if ! command -v docker-compose &> /dev/null; then + echo "错误: Docker Compose未安装,请先安装Docker Compose" exit 1 fi -# 创建命名空间 -echo "创建命名空间..." -kubectl apply -f k8s/namespace.yaml +# 设置环境变量 +export COMPOSE_PROJECT_NAME=water-system-prod +export VERSION=${1:-latest} -# 创建ConfigMap -echo "创建配置文件..." -kubectl create configmap mysql-config --from-file=config/mysql/ -n water-system --dry-run=client -o yaml | kubectl apply -f - -kubectl create configmap redis-config --from-file=config/redis/ -n water-system --dry-run=client -o yaml | kubectl apply -f - +# 创建生产环境目录 +echo "创建生产环境目录..." +mkdir -p {data,logs,config,upload,ssl,backups}/{prod,test} +mkdir -p config/{opengauss,redis,nginx,app,prometheus,grafana} -# 部署数据层 -echo "部署MySQL..." -kubectl apply -f k8s/mysql-deployment.yaml +# 生成强密码 +DB_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25) +REDIS_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25) -echo "部署Redis..." -kubectl apply -f k8s/redis-deployment.yaml +# 创建环境变量文件 +echo "创建环境变量文件..." +cat > .env.prod << EOF +# 数据库配置 +DB_PASSWORD=${DB_PASSWORD} +DB_HOST=water-opengauss +DB_PORT=5432 +DB_NAME=ruoyi_water -# 等待数据层就绪 -echo "等待数据层服务就绪..." -kubectl wait --for=condition=ready pod -l app=water-mysql -n water-system --timeout=300s -kubectl wait --for=condition=ready pod -l app=water-redis -n water-system --timeout=300s +# Redis配置 +REDIS_PASSWORD=${REDIS_PASSWORD} +REDIS_HOST=water-redis +REDIS_PORT=6379 -# 部署应用层 -echo "部署应用服务..." -kubectl apply -f k8s/water-server-deployment.yaml +# 应用配置 +VERSION=${VERSION} +JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -echo "部署前端服务..." -kubectl apply -f k8s/water-ui-deployment.yaml +# 网络配置 +NGINX_PORT=80 +NGINX_SSL_PORT=443 -# 等待应用层就绪 -echo "等待应用服务就绪..." -kubectl wait --for=condition=ready pod -l app=water-server -n water-system --timeout=300s -kubectl wait --for=condition=ready pod -l app=water-ui -n water-system --timeout=300s +# 日志级别 +LOG_LEVEL=INFO +LOG_ROOT_LEVEL=WARN +EOF -# 部署Ingress -echo "部署Ingress..." -kubectl apply -f k8s/ingress.yaml +echo "数据库密码: ${DB_PASSWORD}" +echo "Redis密码: ${REDIS_PASSWORD}" +echo "请妥善保存以上密码信息!" -# 检查部署状态 -echo "检查部署状态..." -kubectl get all -n water-system +# 创建SSL证书(自签名,生产环境应使用正式证书) +echo "创建SSL证书..." +if [ ! -f ssl/water-system.crt ]; then + openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout ssl/water-system.key \ + -out ssl/water-system.crt \ + -subj "/C=CN/ST=Fujian/L=Fuzhou/O=Water/CN=water.local" +fi -echo "=== 部署完成 ===" -echo "查看服务状态: kubectl get all -n water-system" -echo "查看日志: kubectl logs -f deployment/water-server -n water-system" -echo "删除部署: kubectl delete namespace water-system" +# 构建应用镜像 +echo "构建应用镜像..." +docker build -t water-server:${VERSION} ./water-server +docker build -t water-ui:${VERSION} ./water-ui + +# 停止现有服务 +echo "停止现有服务..." +docker-compose --env-file .env.prod -f docker-compose.prod.yml down + +# 启动生产服务 +echo "启动生产服务..." +docker-compose --env-file .env.prod -f docker-compose.prod.yml up -d + +# 等待服务启动 +echo "等待服务启动..." +sleep 60 + +# 检查服务状态 +echo "检查服务状态..." +docker-compose --env-file .env.prod -f docker-compose.prod.yml ps + +# 健康检查 +echo "执行健康检查..." +for i in {1..10}; do + if curl -f http://localhost/actuator/health >/dev/null 2>&1; then + echo "应用服务健康检查通过" + break + else + echo "等待应用服务启动... ($i/10)" + sleep 30 + fi + + if [ $i -eq 10 ]; then + echo "警告: 应用服务健康检查失败" + docker-compose --env-file .env.prod -f docker-compose.prod.yml logs water-server + fi +done + +echo "=== 生产环境部署完成 ===" +echo "系统访问地址: https://localhost" +echo "系统监控地址: http://localhost:3000 (admin/admin123)" +echo "数据库端口: 5432" +echo "Redis端口: 6379" +echo "" +echo "管理命令:" +echo " 查看日志: docker-compose --env-file .env.prod -f docker-compose.prod.yml logs -f [服务名]" +echo " 停止服务: docker-compose --env-file .env.prod -f docker-compose.prod.yml down" +echo " 重启服务: docker-compose --env-file .env.prod -f docker-compose.prod.yml restart [服务名]" +echo " 备份数据: docker exec water-opengauss-prod gs_dump -h localhost -U water_user ruoyi_water > ./backups/backup-\$(date +%Y%m%d_%H%M%S).sql" ``` ### 8.4 持续集成/持续部署 (CI/CD) @@ -1165,21 +1152,37 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Deploy to Kubernetes + - name: Deploy to Production env: - KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }} + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + DEPLOY_USER: ${{ secrets.DEPLOY_USER }} + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} run: | - echo $KUBE_CONFIG_DATA | base64 -d > kubeconfig - export KUBECONFIG=kubeconfig + # 设置SSH密钥 + echo "$DEPLOY_KEY" > deploy_key + chmod 600 deploy_key - # 更新镜像版本 - kubectl set image deployment/water-server water-server=$REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA -n water-system - kubectl set image deployment/water-ui water-ui=$REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA -n water-system - - # 等待部署完成 - kubectl rollout status deployment/water-server -n water-system - kubectl rollout status deployment/water-ui -n water-system + # 部署到生产服务器 + ssh -i deploy_key -o StrictHostKeyChecking=no $DEPLOY_USER@$DEPLOY_HOST << 'EOF' + cd /opt/water-system + + # 拉取最新代码 + git pull origin main + + # 更新镜像版本 + export VERSION=$GITHUB_SHA + + # 重新部署 + ./deploy-prod.sh $VERSION + + # 验证部署 + sleep 30 + curl -f http://localhost/actuator/health || exit 1 + + echo "生产环境部署完成!" + EOF + rm -f deploy_key echo "部署完成!" ``` diff --git a/water_biz_module_design.md b/water_biz_module_design.md index f166730..aac5483 100644 --- a/water_biz_module_design.md +++ b/water_biz_module_design.md @@ -141,9 +141,9 @@ graph TB end subgraph "数据层" - F1[(主数据库
MySQL 8.0+)] - F2[(从数据库
MySQL 8.0+)] - F3[(历史数据库
MySQL 8.0+)] + F1[(主数据库
OpenGauss 5.0+)] + F2[(从数据库
OpenGauss 5.0+)] + F3[(历史数据库
OpenGauss 5.0+)] end subgraph "外部系统" @@ -217,9 +217,9 @@ graph TB end subgraph "数据库技术" - DB1[MySQL 8.0+] + DB1[OpenGauss 5.0+] DB2[Redis 6.0+] - DB3[Druid连接池] + DB3[HikariCP连接池] DB4[MyBatis-Plus代码生成] end @@ -1303,7 +1303,7 @@ graph TB end subgraph "数据存储" - D1[(MySQL 8.0)] + D1[(OpenGauss 5.0+)] D2[(Redis 6.0)] D3[MinIO文件存储] end @@ -1336,9 +1336,9 @@ graph TB - Pinia进行状态管理 **数据库集成**: -- MySQL 8.0作为主数据库 +- OpenGauss 5.0+作为主数据库,国产自主可控 - Redis 6.0提供缓存和会话管理 -- 连接池优化和读写分离支持 +- HikariCP连接池优化和读写分离支持 **中间件集成**: - RabbitMQ提供消息队列