28 KiB
28 KiB
福建水务营收系统部署设计文档
文档信息
| 项目信息 | 详情 |
|---|---|
| 项目名称 | 福建水务营收系统 |
| 文档类型 | 概要设计文档 |
| 技术框架 | RuoYi-Vue-Pro + yudao-ui-admin-vue3 |
| 文档版本 | v1.0 |
| 编写日期 | 2024-12-19 |
| 文档状态 | 🟡 进行中 |
目录
1. 部署概述
福建水务业务系统采用集中化部署模式,基于集团私有云环境进行部署,构建高可用、可扩展的系统架构,满足集团及下属各水务公司的业务需求。
1.1 部署目标
- 实现系统的集中部署和统一管理
- 确保系统高可用性和可靠性
- 支持业务动态扩展和弹性伸缩
- 保障数据安全和业务连续性
- 降低运维成本,提高管理效率
1.2 部署原则
- 集中部署:核心业务系统集中部署在集团数据中心,统一管理和维护
- 多级架构:采用多级架构设计,实现前端负载分担和后端高可用
- 灾备设计:重要系统和数据实现灾备,确保业务连续性
- 安全防护:多层次安全防护体系,确保系统和数据安全
- 弹性扩展:支持系统横向和纵向扩展,适应业务增长需求
2. 部署架构
2.1 总体部署架构
福建水务业务系统采用三层架构部署:
- 接入层:负责外部访问请求的接入和负载均衡
- 应用层:部署业务应用服务,处理业务逻辑
- 数据层:部署数据库服务,存储业务数据
系统部署采用集群模式,各层均部署多个节点,实现高可用和负载均衡。
2.2 生产环境部署架构
生产环境采用双机房部署方案,包括主生产环境和灾备环境:
2.2.1 主生产环境
主生产环境部署在集团主数据中心,包括:
- 负载均衡集群:2台负载均衡服务器
- Web服务器集群:4台Web服务器
- 应用服务器集群:6台应用服务器
- 数据库服务器集群:2台主备数据库服务器
- 文件服务器:2台主备文件服务器
- 缓存服务器集群:2台缓存服务器
2.2.2 灾备环境
灾备环境部署在集团备用数据中心,包括:
- 负载均衡服务器:1台
- Web服务器:2台
- 应用服务器:3台
- 数据库服务器:1台
- 文件服务器:1台
- 缓存服务器:1台
2.3 测试环境部署架构
测试环境部署在集团测试中心,用于系统测试和验证,包括:
- Web服务器:1台
- 应用服务器:2台
- 数据库服务器:1台
- 文件服务器:1台
2.4 开发环境部署架构
开发环境部署在开发中心,用于系统开发和集成测试,包括:
- 应用服务器:1台
- 数据库服务器:1台
3. 服务器配置
3.1 硬件配置要求
3.1.1 负载均衡服务器
- CPU:8核
- 内存:16GB
- 存储:100GB SSD
- 网卡:双千兆网卡
3.1.2 Web服务器
- CPU:8核
- 内存:16GB
- 存储:200GB SSD
- 网卡:双千兆网卡
3.1.3 应用服务器
- CPU:16核
- 内存:32GB
- 存储:300GB SSD
- 网卡:双千兆网卡
3.1.4 数据库服务器
- CPU:24核
- 内存:64GB
- 存储:2TB SSD (RAID 10)
- 网卡:双万兆网卡
3.1.5 文件服务器
- CPU:8核
- 内存:16GB
- 存储:4TB (RAID 5)
- 网卡:双千兆网卡
3.1.6 缓存服务器
- CPU:8核
- 内存:32GB
- 存储:100GB SSD
- 网卡:双千兆网卡
3.2 软件配置要求
3.2.1 操作系统
- 服务端:CentOS 7+、Ubuntu 18.04+或其他国产Linux发行版
- 客户端:支持Windows、macOS、Linux等现代操作系统
3.2.2 数据库
- MySQL 5.7+ 或 MariaDB 10.2+(推荐)
- 国产数据库可选:OpenGauss、达梦等
3.2.3 应用服务器
- JDK 17或JDK 21(兼容支持JDK 8)
- Apache Tomcat 9.0+或内嵌Tomcat
- Nginx 1.18+(作为前端静态资源服务器和反向代理)
3.2.4 缓存服务器
- Redis 5.0+或Redis集群
3.2.5 中间件
- 消息队列:基于Redis的轻量级队列(可选)
- 分布式任务调度:Quartz集群
- 工作流引擎:Flowable 6.x
- 文件存储:支持本地存储、MinIO、阿里云OSS等
3.2.6 前端环境
- Node.js 16+
- NPM 8+或Yarn 1.22+
- Vue 3.x
- Element Plus
4. 网络架构
4.1 网络拓扑
福建水务业务系统网络架构采用三层网络结构:
- 接入层:对外提供服务接入,部署防火墙、负载均衡等设备
- 核心层:实现业务系统间的互联互通,部署核心交换机
- 服务层:部署各类服务器,实现业务处理和数据存储
4.2 网络安全区域划分
网络安全区域划分为以下几个区域:
- DMZ区:部署面向外部的Web服务器,与内网隔离
- 应用区:部署业务应用服务器
- 数据区:部署数据库服务器和文件服务器
- 管理区:部署运维管理服务器
4.3 网络带宽配置
- 外网接入带宽:100Mbps,根据实际需求可升级
- 内网骨干带宽:1000Mbps
- 服务器接入带宽:1000Mbps
- 数据中心间专线带宽:100Mbps
5. 安全设计
5.1 网络安全
5.1.1 边界安全
- 部署高性能防火墙,实现网络隔离
- 部署入侵检测系统(IDS)和入侵防御系统(IPS)
- 部署Web应用防火墙(WAF),防御Web应用攻击
- 采用VPN技术,保障远程访问安全
5.1.2 内网安全
- 网络安全区域划分,实现不同级别网络隔离
- 内网访问控制,限制不必要的网络访问
- 内网流量监控,及时发现异常流量
5.2 系统安全
5.2.1 主机安全
- 操作系统安全加固,关闭不必要的服务和端口
- 系统补丁及时更新,修复安全漏洞
- 部署主机防病毒软件,防御恶意代码
- 主机审计和日志管理,记录重要操作
5.2.2 应用安全
- 应用访问控制,基于角色的权限管理
- 应用操作审计,记录重要业务操作
- 数据传输加密,保护敏感信息
- 输入验证,防止SQL注入、XSS等攻击
5.3 数据安全
5.3.1 数据存储安全
- 数据库访问控制,限制数据库访问权限
- 敏感数据加密存储,防止数据泄露
- 数据库审计,记录重要数据操作
5.3.2 数据备份与恢复
- 定期数据备份,每日增量备份,每周全量备份
- 备份数据异地存储,防止灾难性事件导致数据丢失
- 定期演练数据恢复,确保备份数据可用
6. 部署流程
6.1 部署准备
- 服务器硬件准备和上架
- 网络环境配置和测试
- 操作系统安装和配置
- 基础软件安装和配置
6.2 应用部署
6.2.1 数据库部署
- 数据库服务器配置
- 数据库实例创建和配置
- 数据库高可用配置
- 数据备份策略配置
6.2.2 应用服务部署
- 应用服务器配置
- 应用程序部署
- 应用服务参数配置
- 应用服务高可用配置
6.2.3 Web服务部署
- Web服务器配置
- Web应用部署
- Web服务参数配置
- 负载均衡配置
6.3 系统联调
- 各组件功能测试
- 系统整体联调测试
- 性能和压力测试
- 高可用性测试
6.4 系统上线
- 制定上线计划
- 系统割接准备
- 系统割接实施
- 系统运行监控
7. 监控与运维
7.1 监控系统
7.1.1 基础设施监控
- 服务器硬件监控:CPU、内存、磁盘、网络等
- 网络设备监控:带宽使用率、连接状态等
- 操作系统监控:系统负载、进程状态等
7.1.2 应用监控
- 应用服务状态监控
- 应用性能监控:响应时间、并发数等
- 业务监控:重要业务指标监控
7.1.3 数据库监控
- 数据库服务状态监控
- 数据库性能监控:CPU使用率、内存使用率、IO性能等
- SQL执行监控:慢查询、锁等待等
7.2 运维管理
7.2.1 日常运维
- 系统日常巡检
- 系统性能优化
- 系统容量管理
- 系统备份管理
7.2.2 变更管理
- 变更申请和审批
- 变更实施和验证
- 变更回退预案
- 变更记录管理
7.2.3 故障管理
- 故障监控和告警
- 故障处理流程
- 故障升级机制
- 故障复盘和改进
7.2.4 应急预案
- 系统宕机应急预案
- 网络故障应急预案
- 数据丢失应急预案
- 安全事件应急预案
8. 容器化部署方案
8.1 Docker Compose部署
8.1.1 完整部署配置
# docker-compose.yml
version: '3.8'
services:
# MySQL 数据库
water-mysql:
image: mysql:8.0
container_name: water-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: "water_root_2024"
MYSQL_DATABASE: "ruoyi_water"
MYSQL_USER: "water_user"
MYSQL_PASSWORD: "water_pass_2024"
TZ: "Asia/Shanghai"
volumes:
- ./data/mysql:/var/lib/mysql
- ./sql:/docker-entrypoint-initdb.d
- ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
ports:
- "3306:3306"
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-time-zone=+8:00
networks:
- water-network
# 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-mysql
- 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_USERNAME=water_user
- SPRING_DATASOURCE_PASSWORD=water_pass_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:
mysql-data:
redis-data:
minio-data:
8.1.2 后端应用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"]
8.1.3 前端应用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;"]
8.2 Kubernetes部署
8.2.1 命名空间配置
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: water-system
labels:
name: water-system
8.2.2 MySQL部署配置
# 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
---
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
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: water-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: fast-ssd
8.2.3 Redis部署配置
# 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
---
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
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: water-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
storageClassName: fast-ssd
8.2.4 应用服务部署配置
# 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配置
# 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
8.3 自动化部署脚本
8.3.1 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/{mysql,redis,minio}
mkdir -p logs/{app,nginx}
mkdir -p config/{mysql,redis,nginx/conf.d}
mkdir -p upload
mkdir -p ssl
# 设置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
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;
}
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"
8.3.2 Kubernetes部署脚本
#!/bin/bash
# deploy-k8s.sh
set -e
echo "=== 福建水务营收系统 Kubernetes 部署脚本 ==="
# 检查kubectl环境
if ! command -v kubectl &> /dev/null; then
echo "错误: kubectl未安装,请先安装kubectl"
exit 1
fi
# 检查集群连接
if ! kubectl cluster-info &> /dev/null; then
echo "错误: 无法连接到Kubernetes集群"
exit 1
fi
# 创建命名空间
echo "创建命名空间..."
kubectl apply -f k8s/namespace.yaml
# 创建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 "部署MySQL..."
kubectl apply -f k8s/mysql-deployment.yaml
echo "部署Redis..."
kubectl apply -f k8s/redis-deployment.yaml
# 等待数据层就绪
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
# 部署应用层
echo "部署应用服务..."
kubectl apply -f k8s/water-server-deployment.yaml
echo "部署前端服务..."
kubectl apply -f k8s/water-ui-deployment.yaml
# 等待应用层就绪
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
# 部署Ingress
echo "部署Ingress..."
kubectl apply -f k8s/ingress.yaml
# 检查部署状态
echo "检查部署状态..."
kubectl get all -n water-system
echo "=== 部署完成 ==="
echo "查看服务状态: kubectl get all -n water-system"
echo "查看日志: kubectl logs -f deployment/water-server -n water-system"
echo "删除部署: kubectl delete namespace water-system"
8.4 持续集成/持续部署 (CI/CD)
8.4.1 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 Kubernetes
env:
KUBE_CONFIG_DATA: ${{ secrets.KUBE_CONFIG_DATA }}
run: |
echo $KUBE_CONFIG_DATA | base64 -d > kubeconfig
export KUBECONFIG=kubeconfig
# 更新镜像版本
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
echo "部署完成!"
这样,我已经为福建水务营收系统的部署设计文档补充了完整的现代化部署方案,包括:
- Docker Compose部署:完整的容器化部署配置
- Kubernetes部署:云原生部署配置
- 自动化部署脚本:简化部署流程
- CI/CD流水线:持续集成和持续部署
这些配置都基于RuoYi-Vue-Pro框架的要求,提供了生产就绪的部署方案。