diff --git a/docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md b/docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md index 45f2cd3..f4addb5 100644 --- a/docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md +++ b/docs/design/03_Technical_Design/08_Integrated_Deployment_Design_PlanB.md @@ -57,7 +57,7 @@ retrieval_priority: P1 5. 两台业务应用节点内均部署 `Spring Boot Gateway`,作为微服务集群统一接入入口,并同时承载业务服务。 6. 中间件集中部署在 1 台主机上。 7. 数据库控制组件与中间件部署在同一台主机上。 -8. `MinIO` 作为静态存储与对象存储统一入口,与中间件同机部署。 +8. `RustFS` 作为静态存储与对象存储统一入口,与中间件同机部署。 9. 一期口径下,原“数据与中间件节点”和“文件存储节点”合并为 1 台综合节点。 10. 银行文件交换采用独立 `SFTP/FTP` 文件交换服务器,作为银行送盘、回盘、对账文件交换专用前置机。 11. 当前已知可用于本方案的业务与基础设施主机资源如下: @@ -88,11 +88,18 @@ flowchart LR classDef access fill:#fff7ed,stroke:#ea580c,stroke-width:1.4px,color:#7c2d12; classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.4px,color:#1e3a8a; - U1[PC 端用户]:::source - U2[移动端用户]:::source - U3[第三方系统]:::source - G1[公网入口薄转发]:::access - G2[内网 Nginx]:::access + subgraph OUTER[公网域] + direction TB + U2[移动端用户]:::source + U3[第三方系统]:::source + G1[公网接入代理]:::access + end + + subgraph INNER[内部网络域] + direction TB + U1[PC 端用户]:::source + G2[内网 Nginx]:::access + end subgraph APP1[业务应用节点 1] direction TB @@ -109,7 +116,7 @@ flowchart LR U1 -->|内网访问| G2 U2 -->|HTTPS 443| G1 U3 -->|接口访问| G1 - G1 -->|开放 API 转发| G2 + G1 -->|跨公网/内网边界转发| G2 G2 -->|负载到节点 1| A1G G2 -->|负载到节点 2| A2G A1G --> A1B @@ -118,11 +125,12 @@ flowchart LR 图说明: -1. PC 端用户通过内网直接访问内网 Nginx。 -2. 移动端用户和第三方系统先经公网入口薄转发,再由公网入口转发到内网 Nginx。 -3. 内网 Nginx 将开放 API 端点负载到两台业务应用节点。 -4. 两台业务应用节点内均部署 Spring Boot Gateway,作为微服务集群统一接入入口。 -5. 每台业务应用节点内的 Gateway 再向本节点业务服务转发请求。 +1. 图中已明确区分公网域与内部网络域。 +2. PC 端用户通过内网直接访问内部网络域中的内网 Nginx。 +3. 移动端用户和第三方系统位于公网域,先经公网接入代理,再跨边界转发到内部网络域中的内网 Nginx。 +4. 内网 Nginx 将开放 API 端点负载到两台业务应用节点。 +5. 两台业务应用节点内均部署 Spring Boot Gateway,作为微服务集群统一接入入口。 +6. 每台业务应用节点内的 Gateway 再向本节点业务服务转发请求。 **图 4-2 综合服务软件拓扑图** @@ -136,7 +144,7 @@ flowchart TB subgraph M[综合节点] direction TB - M2[Redis / Nacos / MinIO]:::service + M2[Redis / Nacos / RustFS]:::service M3[HAProxy / PgBouncer / Patroni]:::service end @@ -160,7 +168,7 @@ flowchart LR classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.4px,color:#78350f; classDef bank fill:#fef2f2,stroke:#dc2626,stroke-width:1.4px,color:#7f1d1d; - M2[MinIO / 附件文件]:::service + M2[RustFS / 文件归档]:::service M3[HAProxy / PgBouncer / Patroni]:::service F1[SFTP / FTP 文件交换服务器]:::bank D1[(PostgreSQL 主库)]:::data @@ -181,7 +189,7 @@ flowchart LR 1. 数据库控制组件经由主库提供数据库访问能力。 2. 主库与热备之间通过同步复制保持一致性。 3. 银行文件交换服务器承接送盘、回盘、对账文件交换能力。 -4. MinIO 与银行文件交换服务器分别将各自数据归档到备份归档存储。 +4. RustFS 与银行文件交换服务器分别将各自数据归档到备份归档存储。 ## 主机部署图 @@ -217,7 +225,7 @@ flowchart LR 1. 内网 Nginx 入口节点作为我方统一接入入口,承接 API 转发与内部负载均衡能力。 2. 业务应用节点 1 和业务应用节点 2 组成应用主机集群,节点内同时部署 Spring Boot Gateway 与核心业务服务。 -3. 综合节点集中承载 Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni,并同时访问数据库主库与热备服务器。 +3. 综合节点集中承载 Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni,并同时访问数据库主库与热备服务器。 4. 独立的 SFTP/FTP 文件交换服务器承接银行送盘、回盘、对账文件交换,并由业务应用节点直接访问。 5. 数据库主库服务器与数据库热备服务器独立部署,满足数据库高可用要求。 @@ -225,7 +233,7 @@ flowchart LR 1. 内网 Nginx 入口节点部署 `Nginx`,负责开放 API 转发和内部负载均衡。 2. 两台业务应用节点分别部署 `Spring Boot Gateway` 与业务服务实例。 -3. 综合节点部署 `Redis`、`Nacos`、`MinIO`、`HAProxy`、`PgBouncer`、`Patroni`,并负责访问数据库主库与热备服务器。 +3. 综合节点部署 `Redis`、`Nacos`、`RustFS`、`HAProxy`、`PgBouncer`、`Patroni`,并负责访问数据库主库与热备服务器。 4. SFTP/FTP 文件交换服务器部署银行文件交换服务及送盘、回盘、对账目录,由业务应用节点直接访问。 5. 数据库主库服务器部署 PostgreSQL 主库实例,数据库热备服务器部署 PostgreSQL 热备实例。 @@ -268,107 +276,165 @@ flowchart LR flowchart LR DB1[(PostgreSQL 主库)] --> BK[备份归档存储] DB2[(PostgreSQL 热备)] --> BK - MID[综合节点 / MinIO] --> BK + MID[综合节点 / RustFS] --> BK BK --> REC[恢复与演练入口] ``` 图说明: 1. 主库和热备均向备份归档存储输出备份数据。 -2. 综合节点中的 MinIO 文件数据也纳入备份范围。 +2. 综合节点中的 RustFS 文件数据也纳入备份范围。 3. 备份归档存储作为数据库恢复与文件恢复的统一入口。 ## 网络拓扑图 -**图 4-7 网络拓扑图** +> 说明:如需生成正式网络分区图与网络连接图,统一以 `scripts/generate_planb_diagrams.py` 生成的产物为准;其他脚本仅用于布局试验,不作为正式交付依据。 + +**图 4-7 网络分区图** + +```mermaid +flowchart LR + classDef user fill:#ecfeff,stroke:#0891b2,stroke-width:1.2px,color:#083344; + classDef edge fill:#fff7ed,stroke:#ea580c,stroke-width:1.2px,color:#7c2d12; + classDef zone fill:#f8fafc,stroke:#94a3b8,stroke-width:1.2px,color:#0f172a; + classDef svc fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.2px,color:#4c1d95; + classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.2px,color:#064e3b; + classDef bank fill:#fef2f2,stroke:#dc2626,stroke-width:1.2px,color:#7f1d1d; + classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.2px,color:#78350f; + + U[用户与外部系统]:::user + PGW[公网接入代理]:::edge + + subgraph Z1[内网接入区] + IGW[内网 Nginx] + end + + subgraph Z2[应用区] + APP[业务应用集群] + end + + subgraph Z3[综合服务区] + MID[综合节点] + end + + subgraph Z4[数据区] + DBM[(PostgreSQL 主库)] + DBS[(PostgreSQL 热备)] + end + + subgraph Z6[互联网银行交换区] + FX[SFTP / FTP 文件交换服务器] + end + + subgraph Z5[机房接入区] + BK[备份归档存储] + end + + class Z1,Z2,Z3,Z4,Z5,Z6 zone; + class IGW edge; + class APP svc; + class MID svc; + class DBM,DBS data; + class FX bank; + class BK backup; + + U --> PGW + U --> IGW + PGW --> IGW + IGW --> APP + APP --> FX + APP --> MID + MID --> DBM + MID --> DBS + DBM --> BK + DBS --> BK + MID --> BK +``` + +图说明: + +1. 公网接入代理不纳入我方主机资源,但作为公网访问进入内网的前置接入层予以保留。 +2. 网络分区图按服务器和服务器集群粒度表达,不展开单机内部软件组件。 +3. PC 端用户可直接通过内网访问内网 Nginx;移动端和第三方系统经公网接入代理后进入内网 Nginx。 +4. 业务应用集群、综合服务区、数据区、机房接入区、互联网银行交换区相互隔离,通过授权链路互通。 + +**图 4-8 网络连接图** ```mermaid flowchart TB classDef user fill:#ecfeff,stroke:#0891b2,stroke-width:1.2px,color:#083344; classDef access fill:#fff7ed,stroke:#ea580c,stroke-width:1.2px,color:#7c2d12; classDef app fill:#eff6ff,stroke:#2563eb,stroke-width:1.2px,color:#1e3a8a; - classDef ext fill:#fef3c7,stroke:#d97706,stroke-width:1.2px,color:#78350f; classDef middle fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.2px,color:#4c1d95; classDef data fill:#ecfdf5,stroke:#059669,stroke-width:1.2px,color:#064e3b; - classDef backup fill:#fdf2f8,stroke:#db2777,stroke-width:1.2px,color:#831843; + classDef backup fill:#fffbeb,stroke:#d97706,stroke-width:1.2px,color:#78350f; + classDef bank fill:#fef2f2,stroke:#dc2626,stroke-width:1.2px,color:#7f1d1d; - subgraph U[访问来源] + subgraph OUTER[公网域] direction LR - PC[PC 端用户] - M[移动端用户] - T[第三方系统] + M[移动端用户]:::user + T[第三方系统]:::user + FX[SFTP/FTP文件交换服务器]:::bank end - subgraph A[接入层] + subgraph INNER[内部网络域] direction TB - PGW[公网入口薄转发] - IGW[内网 Nginx] + subgraph CLIENT[客户端] + PC[PC 端用户]:::user + end + + subgraph ACCESS[接入层] + PGW[公网接入代理]:::access + IGW[内网 Nginx]:::access + end + + subgraph SVC[应用与中间件层] + APP[业务应用集群
Spring Boot Gateway + Biz]:::app + CACHE[Redis / Nacos / RustFS]:::middle + CTRL[HAProxy / PgBouncer / Patroni]:::middle + end + + subgraph DATA[数据层] + DBM[(PostgreSQL 主库)]:::data + DBS[(PostgreSQL 热备)]:::data + end + + subgraph STORAGE[存储层] + STORE[备份归档存储]:::backup + end end - subgraph B[应用层] - direction LR - APP1[业务应用节点 1
Spring Boot Gateway] - APP2[业务应用节点 2
Spring Boot Gateway] - end - - subgraph E[外部交换区] - direction TB - FX[SFTP/FTP 文件交换服务器] - end - - subgraph C[综合服务层] - direction TB - MID[综合节点] - end - - subgraph D[数据层] - direction LR - DBM[(PostgreSQL 主库)] - DBS[(PostgreSQL 热备)] - end - - subgraph BK[备份归档层] - direction TB - STORE[备份归档存储] - end + %% 公网访问链路 + M -->|HTTPS 443| PGW + T -->|HTTPS 443 / 接口| PGW + PGW -->|请求转发| IGW + %% 内网访问链路 PC -->|内网访问| IGW - M -->|公网 HTTPS| PGW - T -->|公网 HTTPS/接口| PGW - PGW -->|转发| IGW + IGW -->|网关/应用端口| APP - IGW -->|负载均衡| APP1 - IGW -->|负载均衡| APP2 - - APP1 -->|文件交换| FX - APP2 -->|文件交换| FX - - APP1 -->|业务访问| MID - APP2 -->|业务访问| MID - - MID -->|数据库访问| DBM - MID -->|状态感知/只读访问| DBS + %% 应用层依赖 + APP -->|6379 / 8848 / 9000| CACHE + APP -->|文件传输| FX + APP -->|6432 / 5000| CTRL + CTRL -->|5432| DBM + CTRL -.->|5432 状态探测| DBS DBM -->|主备同步| DBS - DBM -->|备份/WAL 归档| STORE - DBS -->|备份副本| STORE - MID -->|文件归档| STORE - - class PC,M,T user; - class PGW,IGW access; - class APP1,APP2 app; - class FX ext; - class MID middle; - class DBM,DBS data; - class STORE backup; + %% 数据备份与归档 + CACHE -->|归档文件| STORE + DBM -->|备份 / WAL 归档| STORE + DBS -.->|备份副本| STORE + ``` 图说明: -1. PC 端用户通过内网直接访问内网 Nginx,移动端用户和第三方系统通过公网入口薄转发,再转发至内网 Nginx。 -2. 内网 Nginx 统一负载到两台业务应用节点,两台节点内部均部署 Spring Boot Gateway。 -3. 业务应用节点一方面直接访问 SFTP/FTP 文件交换服务器,另一方面访问综合节点获取缓存、配置、文件和数据库代理能力。 -4. 综合节点访问 PostgreSQL 主库与热备,数据库主备及综合节点均接入备份归档存储。 +1. 图中已明确区分公网域与内部网络域,公网访问通过公网接入代理跨边界进入内部网络。 +2. PC 端用户位于内部网络域,直接访问内网 Nginx;移动端和第三方系统位于公网域。 +3. 内网 Nginx 统一将 API / Gateway 请求负载到业务应用集群。 +4. 业务应用集群分别访问综合服务、银行文件交换服务器和数据库控制组件。 +5. 综合服务中的数据库控制组件同时访问 PostgreSQL 主库与热备;数据库与综合服务均向备份归档存储输出归档数据。 ## 主机角色与部署内容 @@ -376,7 +442,7 @@ flowchart TB |---|---|---:|---|---| | 接入层 | 内网 Nginx 入口节点 | 1 台 | Nginx、API 转发、内部负载均衡 | 作为我方统一内网接入入口,承接开放 API 转发 | | 应用层 | 业务应用节点(主) | 2 台 | Spring Boot Gateway、Spring Boot 业务服务 | 承载微服务集群接入与表务、抄表、收费、账务、发票、报表等核心应用服务 | -| 综合支撑层 | 数据、中间件与文件存储综合节点 | 1 台 | Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni | 中间件、数据库控制与文件存储同机部署 | +| 综合支撑层 | 数据、中间件与文件存储综合节点 | 1 台 | Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni | 中间件、数据库控制与文件存储同机部署 | | 银行交换层 | SFTP/FTP 文件交换服务器 | 1 台 | SFTP/FTP 服务、送盘目录、回盘目录、对账目录、归档目录 | 作为银行文件交换专用前置机 | | 数据库层 | PostgreSQL 主库服务器 | 1 台 | PostgreSQL 16 Primary | 部署在可用区 A | | 数据库层 | PostgreSQL 热备服务器 | 1 台 | PostgreSQL 16 Standby | 部署在可用区 B | @@ -419,7 +485,7 @@ flowchart TB |---|---:|---:|---|---|---|---| | 1 | 内网 Nginx 入口节点 | 1 台 | 8 核 CPU / 16 GB 内存 / 300 GB 存储 | Nginx、API 转发、内部负载均衡 | 我方统一内网接入入口 | 可利旧优先 | | 2 | 业务应用节点(主) | 2 台 | 32 核 CPU / 64 GB 内存 / 300 GB 存储 | Spring Boot Gateway、Spring Boot 核心业务服务 | 承载微服务接入与核心业务服务 | 现有资源纳入正式方案 | -| 3 | 数据、中间件与文件存储综合节点 | 1 台 | 16 核 CPU / 32 GB 内存 / 2300 GB 存储 | Redis、Nacos、MinIO、HAProxy、PgBouncer、Patroni | 承载缓存、配置治理、数据库控制、图片、附件、导出文件等能力 | 现有资源纳入正式方案 | +| 3 | 数据、中间件与文件存储综合节点 | 1 台 | 16 核 CPU / 32 GB 内存 / 2300 GB 存储 | Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni | 承载缓存、配置治理、数据库控制、图片、附件、导出文件等能力 | 现有资源纳入正式方案 | | 4 | SFTP/FTP 文件交换服务器 | 1 台 | 2 核 CPU / 8 GB 内存 / 200 GB 存储 | SFTP/FTP 服务、送盘/回盘/对账目录、归档目录 | 承载银行文件交换与目录隔离 | 按最节约一期规划建议新增或单独利旧 | | 5 | PostgreSQL 主库服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | PostgreSQL 16 Primary | 承载生产写入 | 建议单独配置 | | 6 | PostgreSQL 热备服务器 | 1 台 | 24 核 CPU / 48 GB 内存 / 1 TB NVMe SSD | PostgreSQL 16 Standby | 承载正式切换接管 | 建议单独配置 | @@ -436,7 +502,7 @@ flowchart TB | 类别 | 软件名称 | 建议版本 | 部署位置 | 说明 | |---|---|---|---|---| -| 操作系统 | Linux 发行版 | openEuler 20.03+ / CentOS 7.9+ | 全部服务器 | 按甲方基础环境标准选定 | +| 操作系统 | Linux 发行版 | 银河麒麟(Kylin V10)X86 | 全部服务器 | 按甲方当前基础环境标准选定 | | 运行环境 | JDK | 17 | 业务应用节点 | Spring Boot 运行环境 | | 接入层 | Nginx | 1.20+ | 内网 Nginx 入口节点 | 内网 API 转发、内部负载均衡 | | 网关服务 | Spring Boot Gateway | 3.x | 业务应用节点 | 微服务集群统一接入 | @@ -445,7 +511,7 @@ flowchart TB | 数据库 | PostgreSQL | 16 | 主库、热备库 | 主备数据库部署 | | 缓存 | Redis | 6.2+ | 综合节点 | 缓存、会话、轻量级消息能力 | | 配置中心 | Nacos | 2.x | 综合节点 | 配置治理与注册管理 | -| 对象存储 | MinIO | RELEASE 稳定版 | 综合节点 | 图片、附件、导出文件存储 | +| 对象存储 | RustFS | 以项目实际版本为准 | 综合节点 | 图片、附件、导出文件存储 | | 数据库代理 | HAProxy | 2.x | 综合节点 | 数据库读写入口代理 | | 连接池 | PgBouncer | 1.2x+ | 综合节点 | 统一数据库连接池 | | 高可用控制 | Patroni | 稳定版 | 综合节点 | 主备状态管理与切换 | @@ -474,7 +540,7 @@ flowchart TB | HAProxy | 综合节点 | Docker 部署 | 是,优先建议 | 作为数据库代理入口,适合 `host` 模式 | | PgBouncer | 综合节点 | Docker 部署 | 是,优先建议 | 作为数据库连接池入口,适合 `host` 模式 | | Patroni | 综合节点 | 物理机/虚拟机直接部署 | 否 | 建议与系统服务集成,便于运维与切换控制 | -| MinIO | 综合节点 | Docker 部署 | 否 | 更关注数据盘挂载与对象存储目录管理 | +| RustFS | 综合节点 | Docker 部署 | 否 | 更关注数据盘挂载与对象存储目录管理 | | PostgreSQL 主库 | 主库服务器 | 物理机/虚拟机直接部署 | 否 | 核心数据库本体不建议容器化 | | PostgreSQL 热备 | 热备服务器 | 物理机/虚拟机直接部署 | 否 | 高可用数据库本体不建议容器化 | @@ -497,7 +563,7 @@ flowchart TB 以下组件不建议采用 `Docker + host` 模式: 1. `Spring Boot` 业务应用:应保留容器网络隔离,便于扩容和端口治理。 -2. `MinIO`:应以存储挂载与数据目录管理为重点,不依赖 `host` 模式。 +2. `RustFS`:应以存储挂载与数据目录管理为重点,不依赖 `host` 模式。 3. `PostgreSQL 主库 / 热备`:数据库本体优先直接部署,不建议容器化。 4. `Patroni`:建议直接部署,便于与数据库高可用控制链路协同。 @@ -509,7 +575,7 @@ flowchart TB |---|---|---| | 公网接入区 | 公网入口薄转发 | 对外提供 HTTPS 访问,不纳入我方主机资源 | | 应用区 | 业务应用节点 | 仅允许内网接入区与运维区访问 | -| 中间件与文件存储区 | Redis、Nacos、MinIO、数据库控制组件 | 仅允许业务应用节点与运维区访问 | +| 中间件与文件存储区 | Redis、Nacos、RustFS、数据库控制组件 | 仅允许业务应用节点与运维区访问 | | 银行文件交换区 | SFTP/FTP 文件交换服务器 | 仅允许业务应用节点、银行专线或授权外联链路访问 | | 数据区 | PostgreSQL 主库、热备库、备份存储 | 严格限制,仅允许中间件控制主机和运维区访问 | @@ -535,7 +601,7 @@ flowchart TB | 对外访问 | 开通 443 端口 | 提供统一 HTTPS 入口 | | 公网入口薄转发访问内网 Nginx | 开通公网入口到内网 Nginx 的转发端口 | 仅授权链路访问 | | 内网 Nginx 访问应用 | 开通内网 Nginx 到业务应用的 API / 网关端口 | 仅内网访问 | -| 应用访问综合节点 | 开通 Redis、Nacos、MinIO、PgBouncer 相关端口 | 仅应用区访问 | +| 应用访问综合节点 | 开通 Redis、Nacos、RustFS、PgBouncer 相关端口 | 仅应用区访问 | | 业务应用访问 SFTP/FTP 服务器 | 开通 SFTP/FTP 相关端口 | 用于银行文件送盘、回盘、对账交换 | | 银行链路访问 SFTP/FTP 服务器 | 开通 FTP/SFTP 服务端口 | 仅银行授权链路访问 | | 综合节点访问数据库 | 开通 PostgreSQL 5432 及健康检查相关端口 | 仅综合节点访问 | @@ -551,7 +617,7 @@ flowchart TB | 业务应用节点(主) | 综合节点 | TCP/6379 | Redis 访问 | 内网放通 | | 业务应用节点(主) | 综合节点 | TCP/8848 | Nacos 访问 | 内网放通 | | 业务应用节点(主) | 综合节点 | TCP/6432 | PgBouncer 访问 | 内网放通 | -| 业务应用节点(主) | 综合节点 | TCP/9000,9001 | MinIO 文件访问 | 内网放通 | +| 业务应用节点(主) | 综合节点 | RustFS 对象存储端口 | RustFS 文件访问 | 内网放通 | | 业务应用节点(主) | SFTP/FTP 文件交换服务器 | TCP/21 或 22 | 银行送盘、回盘、对账文件交换 | 内网放通 | | 银行专线或授权外联链路 | SFTP/FTP 文件交换服务器 | TCP/21 或 22 | 银行文件目录投递与回收 | 仅授权链路放通 | | 综合节点 | PostgreSQL 主库服务器 | TCP/5432 | 数据库代理与控制访问 | 内网放通 | @@ -569,7 +635,7 @@ flowchart TB | Spring Boot Gateway / 业务应用端口 | 项目自定义端口 | 仅内网 Nginx 与内网调用 | | Redis | 6379 | 仅业务应用与运维可访问 | | Nacos | 8848 | 仅业务应用与运维可访问 | -| MinIO | 9000/9001 | 仅业务应用与运维可访问 | +| RustFS | 按 RustFS 实际部署端口 | 仅业务应用与运维可访问 | | SFTP/FTP 服务 | 21 或 22 | 仅业务应用节点、运维和银行授权链路可访问 | | PgBouncer | 6432 | 仅业务应用可访问 | | HAProxy | 5000 或项目定义端口 | 仅 PgBouncer 与运维可访问 | @@ -588,7 +654,7 @@ flowchart TB 1. 安装操作系统并完成安全基线加固。 2. 在业务应用节点安装 JDK、部署业务运行环境。 3. 在内网 Nginx 入口节点安装 Nginx。 -4. 在综合节点安装 Redis、Nacos、HAProxy、PgBouncer、Patroni、MinIO。 +4. 在综合节点安装 Redis、Nacos、RustFS、HAProxy、PgBouncer、Patroni。 5. 在 SFTP/FTP 文件交换服务器安装 SFTP/FTP 服务并配置目录结构。 6. 在数据库主备节点安装 PostgreSQL 16。 @@ -604,9 +670,9 @@ flowchart TB 1. 在业务应用节点部署 Spring Boot Gateway 和业务应用服务。 2. 在内网 Nginx 入口节点配置 API 转发和内部负载均衡规则。 -3. 在综合节点初始化 MinIO 存储桶和访问策略。 +3. 在综合节点初始化 RustFS 存储桶和访问策略。 4. 在 SFTP/FTP 文件交换服务器配置送盘、回盘、对账、归档目录。 -5. 配置业务应用到 Redis、Nacos、PgBouncer、MinIO 的连接参数。 +5. 配置业务应用到 Redis、Nacos、RustFS、PgBouncer 的连接参数。 ### 5. 联调与演练 @@ -631,7 +697,7 @@ flowchart TB | 业务应用可用性 | 表务、抄表、收费、账务、发票、报表等核心服务正常 | 业务主流程可执行 | | Redis 可用性 | 缓存读写正常 | 中间件能力正常 | | Nacos 可用性 | 配置下发正常 | 配置治理能力正常 | -| MinIO 可用性 | 图片、附件上传下载正常 | 文件存储能力正常 | +| RustFS 可用性 | 图片、附件上传下载正常 | 文件存储能力正常 | | SFTP/FTP 文件交换 | 送盘、回盘、对账目录读写正常 | 银行文件交换能力正常 | | 数据库连接能力 | 业务应用可通过 PgBouncer 正常连接数据库 | 代理接入正常 | | PostgreSQL 主备同步 | 主备复制正常,无严重延迟 | 高可用基础正常 | @@ -647,7 +713,18 @@ flowchart TB 1. 公网入口薄转发不纳入我方主机资源;我方实际部署的统一接入入口为内网 Nginx 入口节点。 2. 2 台业务应用节点作为核心业务集群,节点内同时部署 Spring Boot Gateway 和业务服务,承接微服务统一接入与核心业务处理。 -3. 综合节点集中承载 Redis、Nacos、MinIO 及数据库控制组件,进一步压缩一期主机数量并降低部署复杂度。 +3. 综合节点集中承载 Redis、Nacos、RustFS 及数据库控制组件,进一步压缩一期主机数量并降低部署复杂度。 + +## RustFS 产品介绍与选型说明 + +RustFS 是一款支持私有化部署的 S3 兼容对象存储方案,可用于承接图片、附件、导出文件和归档文件等非结构化数据场景。结合本项目当前整体部署方案,RustFS 作为综合节点上的对象存储组件,可替代 MinIO 承接对象存储能力。 + +本项目采用 RustFS 的原因如下: + +1. RustFS 具备对象存储能力,适合图片、附件、导出文件和归档文件统一存储。 +2. RustFS 支持私有化部署,适合甲方对自主可控和本地化部署的要求。 +3. RustFS 可作为独立对象存储组件部署在综合节点中,与缓存、配置治理和数据库控制能力协同运行。 +4. 当前方案中,银行文件交换仍由独立的 SFTP/FTP 文件交换服务器承接,RustFS 不承担银行送盘、回盘和对账文件交换职责。 4. 新增 1 台 SFTP/FTP 文件交换服务器,作为银行送盘、回盘、对账文件交换专用前置机。 5. PostgreSQL 16 采用同城双可用区 1 主 1 热备部署,满足高可用要求。 6. 网络采用公网接入区、内网接入区、应用区、中间件与文件存储区、银行文件交换区、数据区分层隔离模式,以满足安全性、可维护性和资源审批要求。 diff --git a/output/08_Integrated_Deployment_Design_PlanB_含图表.docx b/output/08_Integrated_Deployment_Design_PlanB_含图表.docx index ffac4ff..c2fa72e 100644 Binary files a/output/08_Integrated_Deployment_Design_PlanB_含图表.docx and b/output/08_Integrated_Deployment_Design_PlanB_含图表.docx differ diff --git a/output/08_planb_network.drawio b/output/08_planb_network.drawio new file mode 100644 index 0000000..f807187 --- /dev/null +++ b/output/08_planb_network.drawio @@ -0,0 +1,419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/output/08_planb_network_engineering_canvas.html b/output/08_planb_network_engineering_canvas.html new file mode 100644 index 0000000..143a31c --- /dev/null +++ b/output/08_planb_network_engineering_canvas.html @@ -0,0 +1,74 @@ + + + + + + PlanB Network Security Zones + + + +

福建水务营收系统网络安全域图

+

按“互联网区(DMZ)/ 非互联网区”两大安全域重绘,仅保留应用系统相关对象。防火墙与路由器仅做抽象表达。

+
+ +
+ + + diff --git a/output/diagrams/planb_network_links.png b/output/diagrams/planb_network_links.png new file mode 100644 index 0000000..3b98d7e Binary files /dev/null and b/output/diagrams/planb_network_links.png differ diff --git a/output/diagrams/planb_network_zones.png b/output/diagrams/planb_network_zones.png new file mode 100644 index 0000000..55fbc8c Binary files /dev/null and b/output/diagrams/planb_network_zones.png differ diff --git a/output/diagrams_variants/planb_links_lr_balanced.png b/output/diagrams_variants/planb_links_lr_balanced.png new file mode 100644 index 0000000..53084c8 Binary files /dev/null and b/output/diagrams_variants/planb_links_lr_balanced.png differ diff --git a/output/diagrams_variants/planb_links_lr_compact.png b/output/diagrams_variants/planb_links_lr_compact.png new file mode 100644 index 0000000..ecb9f9f Binary files /dev/null and b/output/diagrams_variants/planb_links_lr_compact.png differ diff --git a/output/diagrams_variants/planb_links_tb_balanced.png b/output/diagrams_variants/planb_links_tb_balanced.png new file mode 100644 index 0000000..4d7e036 Binary files /dev/null and b/output/diagrams_variants/planb_links_tb_balanced.png differ diff --git a/output/diagrams_variants/planb_links_tb_compact.png b/output/diagrams_variants/planb_links_tb_compact.png new file mode 100644 index 0000000..9387464 Binary files /dev/null and b/output/diagrams_variants/planb_links_tb_compact.png differ diff --git a/scripts/generate_planb_diagrams.py b/scripts/generate_planb_diagrams.py new file mode 100644 index 0000000..1ce776b --- /dev/null +++ b/scripts/generate_planb_diagrams.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +""" +正式网络图生成脚本。 + +用途: +- 生成 PlanB 当前正式口径下的网络分区图与网络连接图 +- 作为 output/diagrams/ 下正式产物的唯一来源 + +说明: +- 如需试验不同布局,请使用 scripts/generate_planb_diagrams_variants.py +""" +from pathlib import Path + +from diagrams import Cluster, Diagram, Edge +from diagrams.generic.network import Router, Switch +from diagrams.onprem.compute import Server +from diagrams.onprem.network import HAProxy, Internet, Nginx +from diagrams.onprem.storage import Ceph + + +ROOT = Path(__file__).resolve().parents[1] +OUT = ROOT / "output" / "diagrams" +OUT.mkdir(parents=True, exist_ok=True) + + +GRAPH_ATTR = { + "fontsize": "20", + "bgcolor": "white", + "pad": "0.2", + "ranksep": "0.55", + "nodesep": "0.35", + "splines": "ortho", + "labelloc": "t", + "fontname": "PingFang SC", + "margin": "0.15", + "rankdir": "LR", + "newrank": "true", +} + +NODE_ATTR = { + "fontname": "PingFang SC", + "fontsize": "13", +} + +EDGE_ATTR = { + "fontname": "PingFang SC", + "fontsize": "11", +} + + +def zone_diagram(): + with Diagram( + "PlanB Network Zones", + filename=str(OUT / "planb_network_zones"), + outformat="png", + show=False, + graph_attr=GRAPH_ATTR, + node_attr=NODE_ATTR, + edge_attr=EDGE_ATTR, + ): + with Cluster("Untrust\n外网区域", graph_attr={"style": "rounded,filled", "color": "#ea580c", "fillcolor": "#fff7ed"}): + mobile = Internet("移动端用户") + third = Internet("第三方系统") + + with Cluster("DMZ\n对外服务区", graph_attr={"style": "rounded,filled", "color": "#d97706", "fillcolor": "#fffbeb"}): + nginx_entry = Nginx("Nginx 入口") + ftp_host = Server("SFTP/FTP 文件交换服务器") + + with Cluster("LAN\n办公与应用区", graph_attr={"style": "rounded,filled", "color": "#2563eb", "fillcolor": "#eff6ff"}): + office_pc = Server("PC 端用户\n办公网段") + app_sw = Switch("应用区交换") + app_cluster = Server("业务应用集群\n2 节点") + svc_host = Server("综合节点") + + with Cluster("Core\n核心数据区", graph_attr={"style": "rounded,filled", "color": "#059669", "fillcolor": "#ecfdf5"}): + db_primary = Server("PostgreSQL 主库") + db_standby = Server("PostgreSQL 热备") + backup = Ceph("备份归档存储") + + # enforce left-to-right zone order and keep the zone centers aligned + mobile - Edge(style="invis", weight="10") - nginx_entry + nginx_entry - Edge(style="invis", weight="10") - office_pc + office_pc - Edge(style="invis", weight="10") - db_primary + + mobile >> Edge(label="HTTPS 443") >> nginx_entry + third >> Edge(label="HTTPS / API") >> nginx_entry + office_pc >> Edge(label="办公网访问") >> nginx_entry + + nginx_entry >> app_sw >> app_cluster + app_cluster >> svc_host + app_cluster >> Edge(label="文件交换 21/22") >> ftp_host + svc_host >> Edge(label="数据库访问") >> db_primary + svc_host >> Edge(label="探测/控制") >> db_standby + db_primary >> Edge(label="主备同步") >> db_standby + db_primary >> Edge(label="备份/WAL") >> backup + db_standby >> Edge(label="备份副本") >> backup + svc_host >> Edge(label="文件归档") >> backup + + +def link_diagram(): + graph_attr = dict(GRAPH_ATTR) + graph_attr["ranksep"] = "0.75" + graph_attr["nodesep"] = "0.3" + with Diagram( + "PlanB Network Links", + filename=str(OUT / "planb_network_links"), + outformat="png", + show=False, + graph_attr=graph_attr, + node_attr=NODE_ATTR, + edge_attr=EDGE_ATTR, + ): + with Cluster("Untrust\n外网区域", graph_attr={"style": "rounded,filled", "color": "#ea580c", "fillcolor": "#fff7ed"}): + mobile = Internet("移动端用户") + third = Internet("第三方系统") + bank_net = Internet("银行系统\n公网/专线") + + with Cluster("DMZ\n对外服务区", graph_attr={"style": "rounded,filled", "color": "#d97706", "fillcolor": "#fffbeb"}): + nginx_entry = Nginx("Nginx 入口") + bank = Server("SFTP/FTP 文件交换服务器") + + with Cluster("LAN\n办公与应用区", graph_attr={"style": "rounded,filled", "color": "#2563eb", "fillcolor": "#eff6ff"}): + pc = Server("PC 端用户\n办公网段") + app_switch = Switch("应用区交换") + app1 = Server("业务应用节点 1\nGateway + Biz") + app2 = Server("业务应用节点 2\nGateway + Biz") + svc = Server("综合节点") + haproxy = HAProxy("HAProxy / PgBouncer / Patroni") + + with Cluster("Core\n核心数据区", graph_attr={"style": "rounded,filled", "color": "#059669", "fillcolor": "#ecfdf5"}): + dbm = Server("PostgreSQL 主库") + dbs = Server("PostgreSQL 热备") + backup = Ceph("备份归档存储") + + # enforce left-to-right zone order: Untrust -> DMZ -> LAN -> Core + mobile - Edge(style="invis", weight="10") - nginx_entry + nginx_entry - Edge(style="invis", weight="10") - pc + pc - Edge(style="invis", weight="10") - dbm + + mobile >> Edge(label="HTTPS 443") >> nginx_entry + third >> Edge(label="HTTPS / 接口") >> nginx_entry + bank_net >> Edge(label="21/22") >> bank + pc >> Edge(label="办公网访问") >> nginx_entry + + nginx_entry >> app_switch + app_switch >> Edge(label="Gateway / API") >> app1 + app_switch >> Edge(label="Gateway / API") >> app2 + app_switch >> Edge(label="业务访问") >> svc + app_switch >> Edge(label="文件交换 21/22") >> bank + svc >> Edge(label="缓存 / 配置 / 文件") >> haproxy + haproxy >> Edge(label="5432 写流量") >> dbm + haproxy >> Edge(label="5432 状态探测", style="dashed") >> dbs + dbm >> Edge(label="主备同步") >> dbs + svc >> Edge(label="文件归档") >> backup + dbm >> Edge(label="WAL / 备份") >> backup + dbs >> Edge(label="备份副本") >> backup + + +if __name__ == "__main__": + zone_diagram() + link_diagram() + print(OUT / "planb_network_zones.png") + print(OUT / "planb_network_links.png") diff --git a/scripts/generate_planb_diagrams_variants.py b/scripts/generate_planb_diagrams_variants.py new file mode 100644 index 0000000..e5e7e77 --- /dev/null +++ b/scripts/generate_planb_diagrams_variants.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +""" +试验版布局脚本。 + +用途: +- 仅用于对比不同 diagrams / graphviz 布局参数的效果 +- 不作为正式交付图的唯一来源 + +正式图来源: +- scripts/generate_planb_diagrams.py +""" +from pathlib import Path + +from diagrams import Cluster, Diagram, Edge +from diagrams.generic.network import Switch +from diagrams.onprem.compute import Server +from diagrams.onprem.network import HAProxy, Internet, Nginx +from diagrams.onprem.storage import Ceph + + +ROOT = Path(__file__).resolve().parents[1] +OUT = ROOT / "output" / "diagrams_variants" +OUT.mkdir(parents=True, exist_ok=True) + + +BASE_GRAPH_ATTR = { + "fontsize": "20", + "bgcolor": "white", + "pad": "0.18", + "ranksep": "0.65", + "nodesep": "0.35", + "splines": "ortho", + "labelloc": "t", + "fontname": "PingFang SC", + "margin": "0.12", + "newrank": "true", +} + +NODE_ATTR = { + "fontname": "PingFang SC", + "fontsize": "13", +} + +EDGE_ATTR = { + "fontname": "PingFang SC", + "fontsize": "11", +} + +ZONE_STYLE = { + "Untrust": {"style": "rounded,filled", "color": "#ea580c", "fillcolor": "#fff7ed"}, + "DMZ": {"style": "rounded,filled", "color": "#d97706", "fillcolor": "#fffbeb"}, + "LAN": {"style": "rounded,filled", "color": "#2563eb", "fillcolor": "#eff6ff"}, + "Core": {"style": "rounded,filled", "color": "#059669", "fillcolor": "#ecfdf5"}, +} + + +def build_nodes(): + with Cluster("Untrust\n外网区域", graph_attr=ZONE_STYLE["Untrust"]): + mobile = Internet("移动端用户") + third = Internet("第三方系统") + bank_net = Internet("银行系统\n公网/专线") + + with Cluster("DMZ\n对外服务区", graph_attr=ZONE_STYLE["DMZ"]): + nginx_entry = Nginx("Nginx 入口") + bank = Server("SFTP/FTP 文件交换服务器") + + with Cluster("LAN\n办公与应用区", graph_attr=ZONE_STYLE["LAN"]): + pc = Server("PC 端用户\n办公网段") + app_switch = Switch("应用区交换") + app1 = Server("业务应用节点 1\nGateway + Biz") + app2 = Server("业务应用节点 2\nGateway + Biz") + svc = Server("综合节点") + ctrl = HAProxy("HAProxy / PgBouncer / Patroni") + + with Cluster("Core\n核心数据区", graph_attr=ZONE_STYLE["Core"]): + dbm = Server("PostgreSQL 主库") + dbs = Server("PostgreSQL 热备") + backup = Ceph("备份归档存储") + + return mobile, third, bank_net, nginx_entry, bank, pc, app_switch, app1, app2, svc, ctrl, dbm, dbs, backup + + +def wire(nodes): + mobile, third, bank_net, nginx_entry, bank, pc, app_switch, app1, app2, svc, ctrl, dbm, dbs, backup = nodes + mobile >> Edge(label="HTTPS 443") >> nginx_entry + third >> Edge(label="HTTPS / 接口") >> nginx_entry + bank_net >> Edge(label="21/22") >> bank + pc >> Edge(label="办公网访问") >> nginx_entry + + nginx_entry >> app_switch + app_switch >> Edge(label="Gateway / API") >> app1 + app_switch >> Edge(label="Gateway / API") >> app2 + app_switch >> Edge(label="文件交换 21/22") >> bank + app_switch >> Edge(label="业务访问") >> svc + svc >> Edge(label="缓存 / 配置 / 文件") >> ctrl + ctrl >> Edge(label="5432 写流量") >> dbm + ctrl >> Edge(label="5432 状态探测", style="dashed") >> dbs + dbm >> Edge(label="主备同步") >> dbs + svc >> Edge(label="文件归档") >> backup + dbm >> Edge(label="WAL / 备份") >> backup + dbs >> Edge(label="备份副本") >> backup + + +def make_variant(name: str, rankdir: str, ranksep: str, nodesep: str): + graph_attr = dict(BASE_GRAPH_ATTR) + graph_attr["rankdir"] = rankdir + graph_attr["ranksep"] = ranksep + graph_attr["nodesep"] = nodesep + with Diagram( + f"PlanB {name}", + filename=str(OUT / name), + outformat="png", + show=False, + graph_attr=graph_attr, + node_attr=NODE_ATTR, + edge_attr=EDGE_ATTR, + ): + nodes = build_nodes() + wire(nodes) + + +if __name__ == "__main__": + variants = [ + ("planb_links_lr_compact", "LR", "0.65", "0.30"), + ("planb_links_lr_balanced", "LR", "0.9", "0.45"), + ("planb_links_tb_compact", "TB", "0.75", "0.35"), + ("planb_links_tb_balanced", "TB", "1.0", "0.45"), + ] + for name, rankdir, ranksep, nodesep in variants: + make_variant(name, rankdir, ranksep, nodesep) + print(OUT / f"{name}.png")