# 环境管理 **本文引用的文件** - [application.yaml](file://fms-api/src/main/resources/application.yaml) - [README.md](file://fms-api/config/dbconfigs/README.md) - [G3HD.properties](file://fms-api/config/dbconfigs/G3HD.properties) - [G3HY2025.properties](file://fms-api/config/dbconfigs/G3HY2025.properties) - [OrgDataSourceFactory.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java) - [OrgDatabaseConfigLoader.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java) - [OrgRoutingDataSource.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java) - [OrgContext.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgContext.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向FMS环境管理系统,聚焦多环境配置管理策略与数据库动态切换机制。内容涵盖开发、测试、预发布、生产环境的差异化管理方式;环境变量在不同环境中的定义与使用;按机构动态加载数据库连接;敏感信息的安全管理(密钥、密码、访问控制);环境切换的最佳实践(配置校验、回滚策略、部署自动化);以及环境特定的调试工具与监控配置建议。 ## 项目结构 后端服务基于Spring Boot,应用级配置集中在application.yaml中,包含服务器端口、上下文路径、JWT密钥来源、数据库连接池参数、文件存储类型等。数据库连接采用“按机构”的独立配置文件模式,位于config/dbconfigs目录下,每个机构一个properties文件,运行时由配置加载器读取并创建数据源。 ```mermaid graph TB A["应用配置
application.yaml"] --> B["数据库连接池参数
pool.*"] A --> C["JWT密钥来源
环境变量注入"] A --> D["文件存储配置
storage-type/local/oss"] E["机构数据库配置目录
config/dbconfigs/*.properties"] --> F["配置加载器
OrgDatabaseConfigLoader"] F --> G["数据源工厂
OrgDataSourceFactory"] G --> H["路由数据源
OrgRoutingDataSource"] H --> I["业务代码通过JDBC访问"] ``` 图表来源 - [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34) - [OrgDatabaseConfigLoader.java:31-65](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L31-L65) - [OrgDataSourceFactory.java:15-50](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L15-L50) - [OrgRoutingDataSource.java:11-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L11-L27) 章节来源 - [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34) - [README.md:1-28](file://fms-api/config/dbconfigs/README.md#L1-L28) ## 核心组件 - 应用配置中心:application.yaml集中声明服务端口、上下文路径、JWT密钥来源、数据库连接池参数、文件存储策略等。 - 机构数据库配置加载器:从指定目录读取{ORG_ID}.properties,校验并解析为连接信息。 - 数据源工厂:根据配置创建Druid连接池,设置连接池参数与健康检查策略。 - 路由数据源:将当前线程的机构上下文映射到对应数据源,实现多租户隔离。 - 上下文管理:ThreadLocal维护当前请求的机构ID与用户ID,确保数据源路由正确。 章节来源 - [application.yaml:10-34](file://fms-api/src/main/resources/application.yaml#L10-L34) - [OrgDatabaseConfigLoader.java:19-104](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L19-L104) - [OrgDataSourceFactory.java:9-53](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L53) - [OrgRoutingDataSource.java:11-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L11-L27) - [OrgContext.java:3-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgContext.java#L3-L55) ## 架构总览 下图展示了从应用启动到按机构路由访问数据库的整体流程,包括配置加载、数据源创建与选择。 ```mermaid sequenceDiagram participant App as "应用" participant Loader as "配置加载器" participant Factory as "数据源工厂" participant Router as "路由数据源" participant DB as "SQL Server" App->>Loader : 初始化并扫描配置目录 Loader-->>App : 提供按机构加载能力 App->>Router : 发起数据库操作 Router->>Router : 读取当前机构上下文 Router->>Factory : 获取或创建机构数据源 Factory-->>Router : DruidDataSource实例 Router->>DB : 建立连接并执行SQL DB-->>Router : 返回结果 Router-->>App : 返回查询结果 ``` 图表来源 - [OrgDatabaseConfigLoader.java:31-65](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L31-L65) - [OrgDataSourceFactory.java:15-50](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L15-L50) - [OrgRoutingDataSource.java:18-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L18-L27) - [application.yaml:10-34](file://fms-api/src/main/resources/application.yaml#L10-L34) ## 详细组件分析 ### 多环境配置管理策略 - 统一入口:application.yaml作为应用级配置入口,定义服务端口、上下文路径、JWT密钥来源、数据库连接池参数、文件存储策略等。 - 环境变量注入:JWT密钥通过环境变量注入,便于不同环境差异化配置且避免硬编码。 - 外部化数据库配置:机构数据库连接以独立properties文件存放于config/dbconfigs目录,支持按机构隔离,便于在测试、预发布、生产环境中分别准备不同的机构配置集。 - 环境差异点示例: - 开发环境:本地或内网SQL Server地址、宽松的连接池参数、开启更多日志。 - 测试环境:共享测试库、中等连接池规模、启用基础健康检查。 - 预发布环境:接近生产的网络拓扑、严格连接池与超时参数、开启审计与告警。 - 生产环境:高可用数据库集群、严格的连接池上限与等待时间、强安全策略与最小权限账号。 章节来源 - [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34) - [README.md:1-28](file://fms-api/config/dbconfigs/README.md#L1-L28) ### 环境变量在不同环境中的定义与使用 - JWT密钥:通过环境变量注入,避免将敏感信息写入代码或仓库。 - 使用方式:在application.yaml中以占位符形式引用环境变量,运行期由容器或平台注入实际值。 - 最佳实践: - 为每个环境维护独立的密钥与凭据,禁止跨环境复用。 - 使用平台提供的密钥管理服务(如Kubernetes Secrets、云平台KMS)进行注入与轮换。 - 对关键变量增加格式校验与默认值保护,防止启动失败。 章节来源 - [application.yaml:10-13](file://fms-api/src/main/resources/application.yaml#L10-L13) ### 数据库配置的动态切换机制(按机构) - 配置目录与命名规范:config/dbconfigs下每个机构一个{ORG_ID}.properties文件,组织ID规范化为大写字母、数字、下划线和连字符。 - 加载与校验: - 加载器读取指定目录下的properties文件,校验URL必须为SQL Server驱动。 - 必填字段包括url、username、password;driver可选,未提供时使用默认SQL Server驱动。 - 对orgId进行规范化与格式校验,防止路径穿越与非法输入。 - 数据源创建: - 工厂类根据配置创建DruidDataSource,设置连接池大小、等待时间、空闲检测、保活策略等。 - 针对云NAT/防火墙回收空闲TCP会话,启用定期ping以保持连接活跃。 - 路由选择: - 路由数据源根据当前线程的机构上下文选择对应数据源,实现多租户隔离。 - 若未设置机构上下文,将抛出异常提示。 ```mermaid flowchart TD Start(["开始"]) --> Normalize["规范化机构ID"] Normalize --> CheckPath{"路径合法?"} CheckPath -- 否 --> ErrPath["抛出路径不合法错误"] CheckPath -- 是 --> LoadProps["读取*.properties"] LoadProps --> ValidateUrl{"URL为SQL Server?"} ValidateUrl -- 否 --> ErrDriver["抛出非SQL Server错误"] ValidateUrl -- 是 --> CreateDS["创建Druid连接池"] CreateDS --> Route["根据上下文路由到数据源"] Route --> End(["结束"]) ErrPath --> End ErrDriver --> End ``` 图表来源 - [OrgDatabaseConfigLoader.java:36-65](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L36-L65) - [OrgDatabaseConfigLoader.java:67-77](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L67-L77) - [OrgDataSourceFactory.java:15-50](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L15-L50) - [OrgRoutingDataSource.java:18-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L18-L27) 章节来源 - [README.md:1-28](file://fms-api/config/dbconfigs/README.md#L1-L28) - [G3HD.properties:1-5](file://fms-api/config/dbconfigs/G3HD.properties#L1-L5) - [G3HY2025.properties:1-5](file://fms-api/config/dbconfigs/G3HY2025.properties#L1-L5) - [OrgDatabaseConfigLoader.java:19-104](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L19-L104) - [OrgDataSourceFactory.java:9-53](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L53) - [OrgRoutingDataSource.java:11-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L11-L27) ### 敏感信息的安全管理 - 密钥管理: - JWT密钥通过环境变量注入,避免明文存储在代码或配置文件中。 - 建议在CI/CD中使用平台密钥管理服务注入,并在各环境独立管理。 - 密码加密与存储: - 机构数据库密码以明文存在于properties文件中,属于高风险项。建议后续引入加密存储(如KMS托管密钥、环境变量或配置中心加密)。 - 在开发环境可保留明文以便快速验证,但在测试、预发布、生产环境应强制加密与最小权限账号。 - 访问控制: - 限制config/dbconfigs目录的访问权限,仅允许运行账户读取。 - 对数据库账号实施最小权限原则,仅授予必要表与视图的读写权限。 - 对API层增加鉴权与审计,记录机构上下文与用户上下文变更。 章节来源 - [application.yaml:10-13](file://fms-api/src/main/resources/application.yaml#L10-L13) - [README.md:16-17](file://fms-api/config/dbconfigs/README.md#L16-L17) - [G3HD.properties:1-5](file://fms-api/config/dbconfigs/G3HD.properties#L1-L5) - [G3HY2025.properties:1-5](file://fms-api/config/dbconfigs/G3HY2025.properties#L1-L5) ### 环境切换的最佳实践 - 配置验证: - 启动时校验JWT密钥是否已注入,缺失则拒绝启动。 - 校验机构配置文件的URL、用户名、密码等必填字段,缺失则抛出明确错误。 - 对orgId进行规范化与正则校验,防止路径穿越与非法输入。 - 回滚策略: - 每次发布前备份当前环境的application.yaml与机构配置集。 - 支持热切换:通过替换config/dbconfigs下的properties文件并重启服务完成回滚。 - 对数据库迁移脚本进行幂等设计,支持重复执行与回滚脚本。 - 部署自动化: - CI/CD流水线中注入环境变量与密钥,生成最终配置后部署。 - 使用容器镜像固化应用代码,外部化所有敏感配置。 - 部署后自动执行健康检查与连通性测试(数据库、对象存储等)。 章节来源 - [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34) - [OrgDatabaseConfigLoader.java:36-65](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L36-L65) - [README.md:16-28](file://fms-api/config/dbconfigs/README.md#L16-L28) ### 环境特定的调试工具与监控配置 - 开发环境: - 使用legacy TLS兼容参数启动,以连接仅支持TLS 1.0的旧版SQL Server。 - 开启更详细的日志与慢查询日志,便于定位问题。 - 测试与预发布环境: - 启用连接池监控指标(Druid内置监控),关注连接数、等待时间与错误率。 - 对关键接口增加调用链追踪与审计日志。 - 生产环境: - 关闭调试开关,仅保留必要日志级别。 - 接入APM与告警系统,对数据库连接池、错误率、响应时间进行监控与告警。 - 定期演练回滚与故障恢复流程。 章节来源 - [README.md:18-28](file://fms-api/config/dbconfigs/README.md#L18-L28) - [application.yaml:10-34](file://fms-api/src/main/resources/application.yaml#L10-L34) ## 依赖关系分析 - 组件耦合: - OrgRoutingDataSource依赖OrgDataSourceManager(由框架装配)与OrgContext,负责按上下文路由。 - OrgDataSourceFactory依赖OrgDatabaseProperties,负责创建Druid连接池。 - OrgDatabaseConfigLoader依赖文件系统与正则校验,负责加载与验证机构配置。 - 外部依赖: - Spring Boot与Druid连接池。 - SQL Server JDBC驱动。 - 潜在风险: - 若未设置机构上下文,路由将抛出异常,需确保网关或拦截器正确设置上下文。 - 若properties文件缺失或格式错误,将导致认证或初始化失败。 ```mermaid classDiagram class OrgContext { +setOrgId(orgId) +getOrgId() String +requireOrgId() String +setUserId(userId) +getUserId() String +requireUserId() String +clear() } class OrgDatabaseConfigLoader { +init() +load(orgId) OrgDatabaseConfig +normalizeOrgId(orgId) String +getConfigDir() Path } class OrgDataSourceFactory { +create(orgId, config) DruidDataSource } class OrgRoutingDataSource { +getConnection() Connection +getConnection(username, password) Connection } OrgRoutingDataSource --> OrgDataSourceFactory : "获取数据源" OrgRoutingDataSource --> OrgContext : "读取上下文" OrgDataSourceFactory --> OrgDatabaseConfigLoader : "使用配置" ``` 图表来源 - [OrgContext.java:3-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgContext.java#L3-L55) - [OrgDatabaseConfigLoader.java:19-104](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L19-L104) - [OrgDataSourceFactory.java:9-53](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L53) - [OrgRoutingDataSource.java:11-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L11-L27) 章节来源 - [OrgContext.java:3-55](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgContext.java#L3-L55) - [OrgDatabaseConfigLoader.java:19-104](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L19-L104) - [OrgDataSourceFactory.java:9-53](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L9-L53) - [OrgRoutingDataSource.java:11-27](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java#L11-L27) ## 性能考虑 - 连接池调优: - initial-size、min-idle、max-active、max-wait等参数应根据负载与环境调整。 - 启用test-while-idle与keepAlive,对抗云NAT/防火墙回收空闲连接。 - 连接健康检查: - validation-query用于连接可用性检测,确保获取到的连接有效。 - time-between-eviction-runs与min-evictable-idle-time控制空闲连接回收周期。 - 资源隔离: - 按机构独立数据源,避免跨租户资源争用。 - 对高频接口使用连接池预热与批量操作减少连接开销。 章节来源 - [application.yaml:14-26](file://fms-api/src/main/resources/application.yaml#L14-L26) - [OrgDataSourceFactory.java:15-50](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java#L15-L50) ## 故障排查指南 - 常见错误与处理: - 机构码为空或格式不正确:检查传入orgId并进行规范化与正则校验。 - 配置文件缺失或路径不合法:确认config/dbconfigs目录下存在对应{ORG_ID}.properties,且路径未被篡改。 - URL非SQL Server:确保url以jdbc:sqlserver:开头。 - 缺少必填字段:检查url、username、password是否存在且非空。 - 未设置机构上下文:确保在请求处理前设置OrgContext.orgId。 - 诊断步骤: - 查看应用日志中的异常堆栈,定位具体失败阶段。 - 验证环境变量是否正确注入(如JWT密钥)。 - 检查数据库连通性与账号权限。 - 对连接池指标进行监控,关注连接泄漏与等待时间。 章节来源 - [OrgDatabaseConfigLoader.java:36-65](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L36-L65) - [OrgDatabaseConfigLoader.java:67-77](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseConfigLoader.java#L67-L77) - [OrgContext.java:13-30](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgContext.java#L13-L30) - [application.yaml:10-13](file://fms-api/src/main/resources/application.yaml#L10-L13) ## 结论 FMS环境管理系统通过application.yaml集中管理与外部化配置,结合按机构的独立数据库配置文件,实现了灵活的多环境支持与多租户隔离。通过环境变量注入敏感信息、严格的配置校验与连接池调优,提升了安全性与稳定性。建议在生产环境中进一步强化密钥加密、访问控制与监控告警,并完善回滚与自动化部署流程,以确保高可用与可运维性。 ## 附录 - 环境清单与差异对照(示例): - 开发:本地SQL Server、宽松连接池、详细日志。 - 测试:共享测试库、中等连接池、基础监控。 - 预发布:接近生产拓扑、严格参数、审计与告警。 - 生产:高可用数据库、严格安全策略、全面监控与演练。 - 部署检查清单: - 环境变量注入验证(JWT密钥等)。 - 机构配置文件完整性与权限校验。 - 数据库连通性与权限测试。 - 连接池指标与错误率基线确认。 - 回滚脚本与应急预案就绪。