fujian_water_biz_doc/water_biz_deployment_design.md

28 KiB
Raw Blame History

福建水务营收系统部署设计文档

文档信息

项目信息 详情
项目名称 福建水务营收系统
文档类型 概要设计文档
技术框架 RuoYi-Vue-Pro + yudao-ui-admin-vue3
文档版本 v1.0
编写日期 2024-12-19
文档状态 已完成

目录

部署概述

福建水务业务系统采用集中化部署模式,基于集团私有云环境进行部署,构建高可用、可扩展的系统架构,满足集团及下属各水务公司的业务需求。

部署目标

  • 实现系统的集中部署和统一管理
  • 确保系统高可用性和可靠性
  • 支持业务动态扩展和弹性伸缩
  • 保障数据安全和业务连续性
  • 降低运维成本,提高管理效率

部署原则

  • 集中部署:核心业务系统集中部署在集团数据中心,统一管理和维护
  • 多级架构:采用多级架构设计,实现前端负载分担和后端高可用
  • 灾备设计:重要系统和数据实现灾备,确保业务连续性
  • 安全防护:多层次安全防护体系,确保系统和数据安全
  • 弹性扩展:支持系统横向和纵向扩展,适应业务增长需求

部署架构

总体部署架构

福建水务业务系统采用三层架构部署:

  • 接入层:负责外部访问请求的接入和负载均衡
  • 应用层:部署业务应用服务,处理业务逻辑
  • 数据层:部署数据库服务,存储业务数据

系统部署采用集群模式,各层均部署多个节点,实现高可用和负载均衡。

生产环境部署架构

生产环境采用双机房部署方案,包括主生产环境和灾备环境:

主生产环境

主生产环境部署在集团主数据中心,包括:

  • 负载均衡集群2台负载均衡服务器
  • Web服务器集群4台Web服务器
  • 应用服务器集群6台应用服务器
  • 数据库服务器集群2台主备数据库服务器
  • 文件服务器2台主备文件服务器
  • 缓存服务器集群2台缓存服务器

灾备环境

灾备环境部署在集团备用数据中心,包括:

  • 负载均衡服务器1台
  • Web服务器2台
  • 应用服务器3台
  • 数据库服务器1台
  • 文件服务器1台
  • 缓存服务器1台

测试环境部署架构

测试环境部署在集团测试中心,用于系统测试和验证,包括:

  • Web服务器1台
  • 应用服务器2台
  • 数据库服务器1台
  • 文件服务器1台

开发环境部署架构

开发环境部署在开发中心,用于系统开发和集成测试,包括:

  • 应用服务器1台
  • 数据库服务器1台

服务器配置

硬件配置要求

负载均衡服务器

  • CPU8核
  • 内存16GB
  • 存储100GB SSD
  • 网卡:双千兆网卡

Web服务器

  • CPU8核
  • 内存16GB
  • 存储200GB SSD
  • 网卡:双千兆网卡

应用服务器

  • CPU16核
  • 内存32GB
  • 存储300GB SSD
  • 网卡:双千兆网卡

数据库服务器

  • CPU24核
  • 内存64GB
  • 存储2TB SSD (RAID 10)
  • 网卡:双万兆网卡

文件服务器

  • CPU8核
  • 内存16GB
  • 存储4TB (RAID 5)
  • 网卡:双千兆网卡

缓存服务器

  • CPU8核
  • 内存32GB
  • 存储100GB SSD
  • 网卡:双千兆网卡

软件配置要求

操作系统

  • 服务端CentOS 7+、Ubuntu 18.04+或其他国产Linux发行版
  • 客户端支持Windows、macOS、Linux等现代操作系统

数据库

  • OpenGauss 5.0+(推荐,国产自主可控)
  • 兼容PostgreSQL 13+、MySQL 8.0+

应用服务器

  • JDK 17或JDK 21兼容支持JDK 8
  • Apache Tomcat 9.0+或内嵌Tomcat
  • Nginx 1.18+(作为前端静态资源服务器和反向代理)

缓存服务器

  • Redis 5.0+或Redis集群

中间件

  • 消息队列基于Redis的轻量级队列可选
  • 分布式任务调度Quartz集群
  • 工作流引擎Flowable 6.x
  • 文件存储支持本地存储、MinIO、阿里云OSS等

前端环境

  • Node.js 16+
  • NPM 8+或Yarn 1.22+
  • Vue 3.x
  • Element Plus

网络架构

网络拓扑

福建水务业务系统网络架构采用三层网络结构:

  • 接入层:对外提供服务接入,部署防火墙、负载均衡等设备
  • 核心层:实现业务系统间的互联互通,部署核心交换机
  • 服务层:部署各类服务器,实现业务处理和数据存储

网络安全区域划分

网络安全区域划分为以下几个区域:

  • DMZ区部署面向外部的Web服务器与内网隔离
  • 应用区:部署业务应用服务器
  • 数据区:部署数据库服务器和文件服务器
  • 管理区:部署运维管理服务器

网络带宽配置

  • 外网接入带宽100Mbps根据实际需求可升级
  • 内网骨干带宽1000Mbps
  • 服务器接入带宽1000Mbps
  • 数据中心间专线带宽100Mbps

安全设计

网络安全

边界安全

  • 部署高性能防火墙,实现网络隔离
  • 部署入侵检测系统(IDS)和入侵防御系统(IPS)
  • 部署Web应用防火墙(WAF)防御Web应用攻击
  • 采用VPN技术保障远程访问安全

内网安全

  • 网络安全区域划分,实现不同级别网络隔离
  • 内网访问控制,限制不必要的网络访问
  • 内网流量监控,及时发现异常流量

系统安全

主机安全

  • 操作系统安全加固,关闭不必要的服务和端口
  • 系统补丁及时更新,修复安全漏洞
  • 部署主机防病毒软件,防御恶意代码
  • 主机审计和日志管理,记录重要操作

应用安全

  • 应用访问控制,基于角色的权限管理
  • 应用操作审计,记录重要业务操作
  • 数据传输加密,保护敏感信息
  • 输入验证防止SQL注入、XSS等攻击

数据安全

数据存储安全

  • 数据库访问控制,限制数据库访问权限
  • 敏感数据加密存储,防止数据泄露
  • 数据库审计,记录重要数据操作

数据备份与恢复

  • 定期数据备份,每日增量备份,每周全量备份
  • 备份数据异地存储,防止灾难性事件导致数据丢失
  • 定期演练数据恢复,确保备份数据可用

部署流程

部署准备

  • 服务器硬件准备和上架
  • 网络环境配置和测试
  • 操作系统安装和配置
  • 基础软件安装和配置

应用部署

数据库部署

  • 数据库服务器配置
  • 数据库实例创建和配置
  • 数据库高可用配置
  • 数据备份策略配置

应用服务部署

  • 应用服务器配置
  • 应用程序部署
  • 应用服务参数配置
  • 应用服务高可用配置

Web服务部署

  • Web服务器配置
  • Web应用部署
  • Web服务参数配置
  • 负载均衡配置

系统联调

  • 各组件功能测试
  • 系统整体联调测试
  • 性能和压力测试
  • 高可用性测试

系统上线

  • 制定上线计划
  • 系统割接准备
  • 系统割接实施
  • 系统运行监控

监控与运维

监控系统

基础设施监控

  • 服务器硬件监控CPU、内存、磁盘、网络等
  • 网络设备监控:带宽使用率、连接状态等
  • 操作系统监控:系统负载、进程状态等

应用监控

  • 应用服务状态监控
  • 应用性能监控:响应时间、并发数等
  • 业务监控:重要业务指标监控

数据库监控

  • 数据库服务状态监控
  • 数据库性能监控CPU使用率、内存使用率、IO性能等
  • SQL执行监控慢查询、锁等待等

运维管理

日常运维

  • 系统日常巡检
  • 系统性能优化
  • 系统容量管理
  • 系统备份管理

变更管理

  • 变更申请和审批
  • 变更实施和验证
  • 变更回退预案
  • 变更记录管理

故障管理

  • 故障监控和告警
  • 故障处理流程
  • 故障升级机制
  • 故障复盘和改进

应急预案

  • 系统宕机应急预案
  • 网络故障应急预案
  • 数据丢失应急预案
  • 安全事件应急预案

容器化部署方案

Docker Compose部署

完整部署配置

# docker-compose.yml
version: '3.8'

services:
  # OpenGauss 数据库
  water-opengauss:
    image: enmotech/opengauss:5.0.0
    container_name: water-opengauss
    restart: always
    environment:
      GS_PASSWORD: "Water@2024"
      GS_DB: "ruoyi_water"
      GS_USERNAME: "water_user"
      TZ: "Asia/Shanghai"
    volumes:
      - ./data/opengauss:/var/lib/opengauss
      - ./sql:/docker-entrypoint-initdb.d
      - ./config/opengauss:/opt/opengauss/config
    ports:
      - "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:
    image: redis:7.0-alpine
    container_name: water-redis
    restart: always
    volumes:
      - ./data/redis:/data
      - ./config/redis/redis.conf:/etc/redis/redis.conf
    ports:
      - "6379:6379"
    command: redis-server /etc/redis/redis.conf
    networks:
      - water-network

  # 后端应用
  water-server:
    build:
      context: ./water-server
      dockerfile: Dockerfile
    container_name: water-server
    restart: always
    depends_on:
      - water-opengauss
      - water-redis
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - 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@2024
      - SPRING_REDIS_HOST=water-redis
      - SPRING_REDIS_PORT=6379
      - SERVER_PORT=8080
    volumes:
      - ./logs:/app/logs
      - ./upload:/app/upload
    ports:
      - "8080:8080"
    networks:
      - water-network

  # 前端应用
  water-ui:
    build:
      context: ./water-ui
      dockerfile: Dockerfile
    container_name: water-ui
    restart: always
    depends_on:
      - water-server
    volumes:
      - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./config/nginx/conf.d:/etc/nginx/conf.d
    ports:
      - "80:80"
      - "443:443"
    networks:
      - water-network

  # Nginx 反向代理
  water-nginx:
    image: nginx:1.24-alpine
    container_name: water-nginx
    restart: always
    depends_on:
      - water-server
      - water-ui
    volumes:
      - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./config/nginx/conf.d:/etc/nginx/conf.d
      - ./ssl:/etc/nginx/ssl
      - ./logs/nginx:/var/log/nginx
    ports:
      - "80:80"
      - "443:443"
    networks:
      - water-network

  # MinIO 文件存储
  water-minio:
    image: minio/minio:latest
    container_name: water-minio
    restart: always
    environment:
      MINIO_ACCESS_KEY: "admin"
      MINIO_SECRET_KEY: "admin123456"
    volumes:
      - ./data/minio:/data
    ports:
      - "9000:9000"
      - "9001:9001"
    command: server /data --console-address ":9001"
    networks:
      - water-network

networks:
  water-network:
    driver: bridge

volumes:
  opengauss-data:
  redis-data:
  minio-data:

后端应用Dockerfile

# water-server/Dockerfile
FROM openjdk:17-jdk-slim

LABEL maintainer="fujian-water-dev-team"

# 设置工作目录
WORKDIR /app

# 设置时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 添加应用jar包
COPY target/water-server.jar app.jar

# 创建日志目录
RUN mkdir -p /app/logs

# 暴露端口
EXPOSE 8080

# 启动应用
ENTRYPOINT ["java", "-jar", "-Xmx1024m", "-Xms512m", "-Dspring.profiles.active=prod", "/app/app.jar"]

前端应用Dockerfile

# water-ui/Dockerfile
# 构建阶段
FROM node:18-alpine AS builder

WORKDIR /app

# 复制包管理文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制源代码
COPY . .

# 构建应用
RUN npm run build:prod

# 生产阶段
FROM nginx:1.24-alpine

# 复制构建产物
COPY --from=builder /app/dist /usr/share/nginx/html

# 复制nginx配置
COPY nginx.conf /etc/nginx/nginx.conf

# 暴露端口
EXPOSE 80

# 启动nginx
CMD ["nginx", "-g", "daemon off;"]

Docker Compose高级配置

生产环境配置优化

Docker Compose生产环境配置文件

# 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

环境变量配置

# env.prod
# 数据库配置
DB_PASSWORD=Water@2024!Production
DB_HOST=water-opengauss
DB_PORT=5432
DB_NAME=ruoyi_water

# Redis配置
REDIS_PASSWORD=WaterRedis@2024!Production
REDIS_HOST=water-redis
REDIS_PORT=6379

# 应用配置
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

监控集成

# docker-compose.monitoring.yml
version: '3.8'

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

  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

volumes:
  prometheus-data:
  grafana-data:

自动化部署脚本

Docker部署脚本

#!/bin/bash
# deploy-docker.sh

set -e

echo "=== 福建水务营收系统 Docker 部署脚本 ==="

# 检查Docker环境
if ! command -v docker &> /dev/null; then
    echo "错误: Docker未安装请先安装Docker"
    exit 1
fi

if ! command -v docker-compose &> /dev/null; then
    echo "错误: Docker Compose未安装请先安装Docker Compose"
    exit 1
fi

# 创建必要目录
echo "创建数据目录..."
mkdir -p data/{opengauss,redis,minio}
mkdir -p logs/{app,nginx}
mkdir -p config/{opengauss,redis,nginx/conf.d}
mkdir -p upload
mkdir -p ssl
mkdir -p backups

# 设置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配置
echo "配置Redis..."
cat > config/redis/redis.conf << EOF
port 6379
requirepass water_redis_2024
timeout 300
tcp-keepalive 300
maxmemory 256mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
EOF

# 设置Nginx配置
echo "配置Nginx..."
cat > config/nginx/nginx.conf << EOF
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                    '\$status \$body_bytes_sent "\$http_referer" '
                    '"\$http_user_agent" "\$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    client_max_body_size 50M;
    
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript 
               application/javascript application/xml+rss 
               application/json;
    
    include /etc/nginx/conf.d/*.conf;
}
EOF

cat > config/nginx/conf.d/water.conf << EOF
upstream water_backend {
    server water-server:8080 max_fails=3 fail_timeout=30s;
    keepalive 32;
}

server {
    listen 80;
    server_name localhost;
    
    location /admin-api/ {
        proxy_pass http://water_backend;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_connect_timeout 600;
        proxy_send_timeout 600;
        proxy_read_timeout 600;
    }
    
    location / {
        proxy_pass http://water-ui;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
}
EOF

# 构建和启动服务
echo "构建和启动Docker服务..."
docker-compose down
docker-compose build --no-cache
docker-compose up -d

# 等待服务启动
echo "等待服务启动..."
sleep 30

# 检查服务状态
echo "检查服务状态..."
docker-compose ps

echo "=== 部署完成 ==="
echo "系统访问地址: http://localhost"
echo "API接口地址: http://localhost/admin-api"
echo "MinIO控制台: http://localhost:9001 (admin/admin123456)"
echo ""
echo "查看日志: docker-compose logs -f [服务名]"
echo "停止服务: docker-compose down"
echo "重启服务: docker-compose restart"

生产环境部署脚本

#!/bin/bash
# deploy-prod.sh

set -e

echo "=== 福建水务营收系统 生产环境部署脚本 ==="

# 检查环境
if ! command -v docker &> /dev/null; then
    echo "错误: Docker未安装请先安装Docker"
    exit 1
fi

if ! command -v docker-compose &> /dev/null; then
    echo "错误: Docker Compose未安装请先安装Docker Compose"
    exit 1
fi

# 设置环境变量
export COMPOSE_PROJECT_NAME=water-system-prod
export VERSION=${1:-latest}

# 创建生产环境目录
echo "创建生产环境目录..."
mkdir -p {data,logs,config,upload,ssl,backups}/{prod,test}
mkdir -p config/{opengauss,redis,nginx,app,prometheus,grafana}

# 生成强密码
DB_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)
REDIS_PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25)

# 创建环境变量文件
echo "创建环境变量文件..."
cat > .env.prod << EOF
# 数据库配置
DB_PASSWORD=${DB_PASSWORD}
DB_HOST=water-opengauss
DB_PORT=5432
DB_NAME=ruoyi_water

# Redis配置
REDIS_PASSWORD=${REDIS_PASSWORD}
REDIS_HOST=water-redis
REDIS_PORT=6379

# 应用配置
VERSION=${VERSION}
JAVA_OPTS=-Xmx2g -Xms1g -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError

# 网络配置
NGINX_PORT=80
NGINX_SSL_PORT=443

# 日志级别
LOG_LEVEL=INFO
LOG_ROOT_LEVEL=WARN
EOF

echo "数据库密码: ${DB_PASSWORD}"
echo "Redis密码: ${REDIS_PASSWORD}"
echo "请妥善保存以上密码信息!"

# 创建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 "构建应用镜像..."
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"

持续集成/持续部署 (CI/CD)

GitHub Actions配置

# github/workflows/deploy.yml
name: Build and Deploy Water System

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

env:
  REGISTRY: docker.io
  IMAGE_NAME: water-system

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
    
    - name: Cache Maven dependencies
      uses: actions/cache@v3
      with:
        path: ~/.m2
        key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
        restore-keys: ${{ runner.os }}-m2
    
    - name: Run tests
      run: mvn clean test
    
    - name: Generate test report
      uses: dorny/test-reporter@v1
      if: success() || failure()
      with:
        name: Maven Tests
        path: target/surefire-reports/*.xml
        reporter: java-junit

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
    
    - name: Build with Maven
      run: mvn clean package -DskipTests
    
    - name: Build Docker image
      run: |
        docker build -t $REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA ./water-server
        docker build -t $REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA ./water-ui
    
    - name: Log in to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}
    
    - name: Push Docker images
      run: |
        docker push $REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA
        docker push $REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA
        docker tag $REGISTRY/$IMAGE_NAME-server:$GITHUB_SHA $REGISTRY/$IMAGE_NAME-server:latest
        docker tag $REGISTRY/$IMAGE_NAME-ui:$GITHUB_SHA $REGISTRY/$IMAGE_NAME-ui:latest
        docker push $REGISTRY/$IMAGE_NAME-server:latest
        docker push $REGISTRY/$IMAGE_NAME-ui:latest

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy to Production
      env:
        DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
        DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
        DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
      run: |
        # 设置SSH密钥
        echo "$DEPLOY_KEY" > deploy_key
        chmod 600 deploy_key
        
        # 部署到生产服务器
        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 "部署完成!"

这样,我已经为福建水务营收系统的部署设计文档补充了完整的现代化部署方案,包括:

  1. Docker Compose部署:完整的容器化部署配置
  2. Kubernetes部署:云原生部署配置
  3. 自动化部署脚本:简化部署流程
  4. CI/CD流水线:持续集成和持续部署

这些配置都基于RuoYi-Vue-Pro框架的要求提供了生产就绪的部署方案。