4、除了常见的 services(业务微服务)和 gateway(API 网关)模块外,还必须建立一系列支撑性、平台级、基础设施类模块
当然可以!在构建一个企业级、可扩展、高内聚、低耦合的微服务电商系统(如 urbane-commerce
)时,除了常见的 services
(业务微服务)和 gateway
(API 网关)模块外,还必须建立一系列支撑性、平台级、基础设施类模块。这些模块是系统“骨架”与“神经系统”,决定了系统的可维护性、可观测性、可部署性和长期演进能力。
📜《urbane-commerce 项目模块架构设计规范》
版本:1.15 | 最后更新:2025年4月 | 适用架构:Spring Boot + Maven 多模块 + Docker + Kubernetes + CI/CD
🧭 一、为什么需要“非业务”模块?
问题 | 风险 |
---|---|
所有代码都堆在 services/ 下 | 模块混乱、依赖不清、无法复用 |
每个服务自己写日志、监控、配置 | 重复造轮子,运维成本爆炸 |
没有统一工具库 | 代码冗余、不一致、难维护 |
没有基础设施即代码 | 部署靠手动,上线风险高 |
没有公共配置中心 | 不同环境配置分散,易出错 |
没有测试框架封装 | 单元测试难写,质量无保障 |
✅ 核心目标:
让业务团队专注“做什么”,而不是“怎么搭” —— 平台化、标准化、自动化。
✅ 二、推荐创建的模块清单(按类别)
类别 | 模块名称 | 作用说明 | 是否必须 |
---|---|---|---|
🔧 基础设施层 | commons | 公共工具类、DTO、异常、常量 | ✅ 必须 |
🔐 安全与认证 | security-common | JWT 工具、权限注解、鉴权逻辑 | ✅ 必须 |
📦 配置管理 | config | Nacos/Spring Cloud Config 的配置包 | ✅ 必须 |
📊 监控与追踪 | observability | 日志、指标、链路追踪统一封装 | ✅ 必须 |
🧪 测试支持 | test-utils | 测试基类、Mock 工具、Testcontainers 封装 | ✅ 强烈推荐 |
⚙️ 基础设施即代码 | infrastructure | Terraform / Helm / K8s YAML 文件 | ✅ 必须 |
🏗️ 构建与部署 | build-tools | Dockerfile 模板、CI/CD 脚本、镜像构建脚本 | ✅ 强烈推荐 |
🌐 API 文档 | api-docs | OpenAPI/Swagger 规范、前端对接文档 | ✅ 推荐 |
🧠 数据分析 | analytics | Kafka 消费者、数据清洗、BI 输出 | ✅ 推荐(中大型项目) |
🤖 运维助手 | ops-scripts | Shell 脚本、数据库迁移、备份恢复 | ✅ 推荐 |
✅ 三、各模块详细说明与最佳实践
1. common
—— 公共工具与基础模型
职责:提供所有服务共享的通用组件,避免重复定义。
✅ 包含内容:
io.urbane.commons/
├── dto/ # 所有服务公用的 DTO(Data Transfer Object)
│ ├── ResponseResult.java # 统一响应体 {code, message, data, timestamp}
│ └── PageRequest.java # 分页参数封装
├── exception/ # 全局异常基类
│ ├── BusinessException.java # 业务异常(带错误码)
│ └── SystemException.java # 系统异常
├── util/ # 工具类
│ ├── DateUtils.java # 日期格式化
│ ├── IdGenerator.java # Snowflake ID 生成器
│ └── JsonUtils.java # Jackson 工具封装
├── constant/ # 枚举常量
│ ├── OrderStatus.java # 订单状态枚举
│ └── NotificationType.java # 通知类型枚举
└── annotation/ # 自定义注解└── @LogOperation.java # 用于记录操作日志的切面注解
🔍 判断标准:
- ✅ 是否被 ≥3 个服务使用? → 放入
common
- ✅ 是否属于“领域无关”的通用能力? → 放入
common
- ❌ 是否包含业务逻辑或数据库实体? → 不放!放在对应 service 中
💡 最佳实践:
- 使用 Lombok 减少样板代码
- 所有 DTO 使用
@JsonInclude(JsonInclude.Include.NON_NULL)
避免空字段污染 - 所有异常统一继承
RuntimeException
,并带errorCode
✅ 示例:
ResponseResult<T>
在所有服务中统一结构,前端无需适配不同格式!
2. security-common
—— 安全与认证统一组件
职责:集中管理安全相关逻辑,避免每个服务重复实现 JWT 校验、权限注解等。
✅ 包含内容:
io.urbane.security/
├── jwt/ # JWT 工具
│ ├── JwtUtil.java # 解析、校验 Token
│ └── JwtTokenProvider.java
├── filter/ # Spring Security 过滤器
│ └── UserAuthenticationFilter.java
├── annotation/ # 权限注解
│ └── @PreAuthorizeRole.java
├── context/ # 用户上下文
│ └── UserContext.java # ThreadLocal 存储 X-User-ID
├── config/ # 安全配置模板
│ └── WebSecurityConfig.java
└── exception/ # 安全异常└── AuthenticationException.java
🔍 判断标准:
- ✅ 是否涉及身份识别、Token、权限判断?
- ✅ 是否多个服务都需要校验
X-User-ID
或角色? - ✅ 是否需要统一拦截器、过滤器?
💡 最佳实践:
- 所有服务依赖此模块,不再自行实现 JWT 校验
- 网关只做初步验证,业务服务仍需二次校验(防越权)
- 使用
@PreAuthorizeRole("ADMIN")
替代原始 SpEL 表达式,提升可读性
✅ 示例:
order-service
和product-service
都只需加一行注解:
@PreAuthorizeRole("USER")
@GetMapping("/{id}")
public Result<Order> getOrder(@PathVariable Long id) { ... }
3. config
—— 配置中心统一管理包
职责:存放所有服务的公共配置文件,由 Nacos / Spring Cloud Config 统一推送。
✅ 包含内容:
# src/main/resources/
├── application.yml # 公共基础配置
├── application-dev.yml # 开发环境
├── application-prod.yml # 生产环境
├── nacos-config/
│ ├── urbane-commerce-gateway.yml # 网关配置
│ ├── user-service.yml # 用户服务
│ ├── order-service.yml # 订单服务
│ └── ...
└── logback-spring.xml # 统一日志配置
🔍 判断标准:
- ✅ 是否有多个服务共享相同配置(如 Redis 地址、JWT 密钥、超时时间)?
- ✅ 是否希望不重启服务即可动态刷新配置?
💡 最佳实践:
- 所有敏感配置(密钥、密码)不写在本地,通过 Nacos 配置中心注入
- 使用
spring.cloud.nacos.config.group=URBANE-COMMERCE
统一分组 - 所有服务引用同一组配置模板,确保一致性
✅ 示例:所有服务都从 Nacos 获取:
jwt:secret: ${JWT_SECRET} # 从 Nacos 注入,不在代码中暴露
redis:host: ${REDIS_HOST}
4. observability
—— 监控、日志、追踪统一封装
职责:统一集成 Prometheus、Grafana、ELK、OpenTelemetry,避免每个服务各自配置。
✅ 包含内容:
io.urbane.observability/
├── metrics/ # 指标收集
│ └── MeterRegistryConfig.java # 初始化 Prometheus Counter/Gauge
├── tracing/ # 链路追踪
│ ├── OpenTelemetryConfig.java # 集成 Jaeger/Zipkin
│ └── TraceInterceptor.java # 自动记录 HTTP 请求耗时
├── logging/ # 日志增强
│ └── MDCLoggingFilter.java # 自动注入 traceId、userId 到日志
└── health/ # 健康检查增强└── CustomHealthIndicator.java # 检查 Redis、DB、Kafka 连接
🔍 判断标准:
- ✅ 是否所有服务都需要记录请求日志 + traceId?
- ✅ 是否需要统一上报指标到 Prometheus?
- ✅ 是否希望一键接入链路追踪?
💡 最佳实践:
- 所有服务依赖此模块,自动获得:
- 日志中自动打印
traceId=xxx, userId=123
- 每次 HTTP 请求自动上报
http_request_duration_seconds
/actuator/health
自动检测依赖服务健康度
- 日志中自动打印
- 使用
logback-spring.xml
统一日志格式:<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - [traceId:%X{traceId}, userId:%X{userId}] %msg%n</pattern>
✅ 效果:
一条日志 ={ "timestamp": "...", "traceId": "a1b2c3", "userId": "123", "message": "订单创建成功" }
可直接在 ELK 搜索traceId:a1b2c3
查看完整调用链!
5. test-utils
—— 测试辅助工具包
职责:为所有服务提供测试便利,提升单元测试、集成测试覆盖率。
✅ 包含内容:
io.urbane.test/
├── base/ # 测试基类
│ └── BaseIntegrationTest.java # 启动 MockWebServer + H2 DB
├── mock/ # Mock 工具
│ ├── MockFeignClient.java # 模拟 Feign 调用
│ └── MockEventPublisher.java # 模拟 Kafka 事件发布
├── fixture/ # 测试数据工厂
│ └── UserFixture.java # 生成测试用户对象
└── container/ # Testcontainers 封装└── RedisContainer.java # 启动 Redis 容器做集成测试
🔍 判断标准:
- ✅ 是否每个服务都要写重复的
@SpringBootTest
? - ✅ 是否经常要模拟外部服务(如支付、库存)?
- ✅ 是否想用真实 Redis/MySQL 做集成测试而不依赖本地安装?
💡 最佳实践:
- 所有服务继承
BaseIntegrationTest
- 使用
Testcontainers
启动真实中间件做集成测试:@Container public static RedisContainer redis = new RedisContainer("redis:7-alpine");
- 使用
Fixture
快速生成测试数据:User user = UserFixture.createValidUser();
✅ 效果:测试覆盖率 >90%,CI/CD 上能跑通真实依赖,不再“在我机器上能跑”
6. infrastructure
—— 基础设施即代码(IaC)
职责:所有部署、网络、资源通过代码定义,告别“手动点按钮”。
✅ 包含内容:
infrastructure/
├── k8s/ # Kubernetes 部署文件
│ ├── namespace.yaml
│ ├── ingress.yaml
│ ├── urbane-commerce-gateway/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ └── hpa.yaml
│ └── ... (其他服务)
├── helm/ # Helm Chart(推荐)
│ └── urbane-commerce/
│ ├── Chart.yaml
│ ├── values.yaml
│ └── templates/
├── terraform/ # 云资源编排(AWS/Aliyun)
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── docker-compose/ # 本地开发环境
│ └── docker-compose.yml
└── scripts/├── deploy.sh # 部署脚本└── rollback.sh
🔍 判断标准:
- ✅ 是否每次上线都要手动改 YAML?
- ✅ 是否希望“一次编写,多环境部署”(dev/stage/prod)?
- ✅ 是否使用 Kubernetes / 云原生?
💡 最佳实践:
- 使用 Helm 管理微服务部署,支持
values-dev.yaml
、values-prod.yaml
- 使用 Terraform 管理云资源(RDS、Redis、ECS、SLB)
- 所有配置通过 GitOps 管理(ArgoCD 自动同步)
✅ 示例:
helm upgrade urbane-commerce . --values values-prod.yaml
→ 一键完成所有服务滚动更新
7. build-tools
—— 构建与部署自动化脚本
职责:封装构建、打包、镜像生成、发布流程,实现“一键发布”。
✅ 包含内容:
build-tools/
├── docker/ # Dockerfile 模板
│ └── java-app.Dockerfile
├── ci/ # CI/CD 脚本
│ ├── build-maven.sh # 编译所有模块
│ ├── build-docker.sh # 构建所有服务镜像
│ └── push-to-registry.sh
├── release/ # 发布流程
│ └── tag-release.sh # 打 tag 并触发 CI/CD
└── check/ # 质量门禁├── check-code-style.sh # Checkstyle└── check-test-coverage.sh # Jacoco
🔍 判断标准:
- ✅ 是否每次都要手动执行
mvn clean package docker:build
? - ✅ 是否希望 CI/CD 有统一入口?
💡 最佳实践:
- 所有服务使用统一
Dockerfile
模板 - 使用
Jib
或BuildKit
加速镜像构建 - CI/CD Pipeline(GitLab CI)调用
build-tools/build-docker.sh
✅ 效果:
开发者只需git push
,系统自动完成:
编译 → 测试 → 打包 → 镜像构建 → 推送 → 部署 → 健康检查
8. api-docs
—— API 文档统一管理
职责:集中管理 OpenAPI 规范,供前端、测试、第三方对接使用。
✅ 包含内容:
api-docs/
├── swagger/ # Swagger UI 静态资源
│ └── index.html
├── openapi/ # OpenAPI 3.0 YAML 文件
│ ├── user-service.yaml
│ ├── order-service.yaml
│ └── urbane-commerce.yaml (聚合)
├── generated/ # 自动生成的文档(Maven 插件生成)
│ └── api-spec.json
└── README.md # 文档使用指南、接口访问地址
🔍 判断标准:
- ✅ 是否前端团队抱怨“接口文档不一致”?
- ✅ 是否希望自动生成 SDK(TypeScript)?
💡 最佳实践:
- 使用
springdoc-openapi
在每个服务生成独立 YAML - 使用
openapi-generator
聚合所有服务,生成统一 API 文档网站 - 上传至 GitHub Pages 或内部 Wiki
✅ 效果:前端同学打开
https://docs.urbane.io
→ 一键下载 TypeScript 客户端
9. analytics
—— 数据分析与 BI 支撑
职责:消费 Kafka 事件,清洗数据,输出报表,支持运营决策。
✅ 包含内容:
io.urbane.analytics/
├── consumer/ # Kafka 消费者
│ ├── OrderConsumer.java
│ ├── ProductViewConsumer.java
│ └── SearchQueryConsumer.java
├── processor/ # 数据处理
│ └── UserBehaviorProcessor.java
├── repository/ # 存储到数仓
│ └── ClickHouseRepository.java
└── report/ # 报表生成└── DailyReportJob.java
🔍 判断标准:
- ✅ 是否有运营人员问:“昨天卖了多少?”、“哪个活动转化最高?”
- ✅ 是否需要实时看板?
💡 最佳实践:
- 使用 Flink 实时聚合
- 使用 ClickHouse 存储海量行为数据
- 使用 Superset / Grafana 展示看板
✅ 适用场景:中大型电商平台(日活 > 10万)
10. ops-scripts
—— 运维辅助脚本
职责:提供日常运维命令,降低人工操作风险。
✅ 包含内容:
ops-scripts/
├── backup-db.sh # 备份 MySQL
├── restore-db.sh # 恢复 MySQL
├── clear-cache.sh # 清空 Redis 缓存
├── restart-service.sh # 优雅重启指定服务
├── tail-log.sh # 实时查看某个服务日志
├── check-deploy.sh # 检查当前部署版本
└── emergency-rollout.sh # 紧急回滚脚本
🔍 判断标准:
- ✅ 运维是否每天要手动登录服务器敲命令?
- ✅ 是否希望“一键回滚”?
💡 最佳实践:
- 所有脚本加入
set -e
,失败立即退出 - 所有操作记录到审计日志
- 配合 Ansible / JumpServer 使用
✅ 四、模块组织结构总览(推荐目录树)
urbane-commerce/
├── pom.xml ← 父工程(管理依赖版本)
├── README.md
├── docs/ ← 架构图、设计文档
├── services/ ← 业务微服务
│ ├── user-service/
│ ├── product-service/
│ ├── order-service/
│ └── ...
├── gateway/ ← API 网关
│ └── urbane-commerce-gateway/
├── common/ ← 公共工具
├── security-common/ ← 安全组件
├── config/ ← 配置中心包
├── observability/ ← 监控追踪
├── test-utils/ ← 测试工具
├── infrastructure/ ← K8s/Helm/Terraform
├── build-tools/ ← 构建部署脚本
├── api-docs/ ← API 文档
├── analytics/ ← 数据分析(可选)
├── ops-scripts/ ← 运维脚本
└── .github/ ← CI/CD 配置└── workflows/├── build-and-test.yml└── deploy-prod.yml
🔍 五、判断标准与核心设计原则
原则 | 说明 | 应用示例 |
---|---|---|
✅ 单一职责原则(SRP) | 每个模块只做一件事 | common 只管工具类,infrastructure 只管部署 |
✅ 高内聚低耦合 | 模块内部紧密,模块间松散 | security-common 不依赖任何业务服务 |
✅ 可复用性优先 | 通用能力集中沉淀,避免重复 | 所有服务共享 ResponseResult |
✅ 标准化 > 灵活性 | 统一规范比自由发挥更重要 | 所有服务日志格式一致 |
✅ 自动化 > 手动 | 能用脚本做的,绝不手动点 | 一键部署、一键回滚 |
✅ 一切皆代码(Everything as Code) | 配置、部署、测试、文档都用代码管理 | Git 是唯一真相源 |
✅ 可观测性内建 | 监控、日志、追踪不是事后加的,是设计时就有的 | 所有服务默认带 traceId |
✅ 安全默认(Secure by Default) | 默认禁止危险操作 | common 中的 DTO 不含敏感字段 |
✅ 可测试性优先 | 每个模块都应能独立测试 | test-utils 让单元测试不依赖真实 DB |
✅ 演进友好(Evolutionary Design) | 新增服务不影响旧模块 | 新增 review-service 只需加服务,无需改 common |
✅ 六、最终建议:模块引入顺序(成长路径)
阶段 | 推荐模块 | 目标 |
---|---|---|
初创期(1~3 个服务) | common , config , observability , test-utils | 快速搭建,避免重复 |
成长期(4~8 个服务) | security-common , infrastructure , build-tools | 统一安全、实现 CI/CD |
成熟期(>10 服务) | api-docs , analytics , ops-scripts | 提升协作效率、支持运营决策 |
企业级(大规模) | helm-charts , terraform , argocd | 实现 GitOps、蓝绿发布、自动化运维 |
✅ 建议:
从common
+config
+observability
开始,逐步添加,不要一开始就堆砌 10 个模块。
🚀 七、总结:你的项目模块架构黄金法则
✅ 你必须拥有的模块:
common
—— 统一 DTO、异常、工具security-common
—— 统一认证、权限、JWTconfig
—— 统一配置中心包observability
—— 统一日志、指标、追踪test-utils
—— 统一测试基类、Mock 工具infrastructure
—— 统一部署、K8s/Helmbuild-tools
—— 统一构建、打包、发布
❌ 你绝对不能没有的:
- 没有
common
→ 代码重复、风格混乱- 没有
observability
→ 出问题不知道在哪- 没有
infrastructure
→ 上线靠人肉,事故频发- 没有
test-utils
→ 测试难写,质量差
🔑 判断一切的标准:
“如果这个功能,会被两个及以上服务使用,那就把它抽出来,放到独立模块。”
“如果这个操作,需要人工干预,那就写成脚本,变成自动化。”
“如果这个配置,存在多个环境,那就交给配置中心,别写在代码里。”
📦 下一步:为你打包完整项目模板
如果你希望我为你提供:
- ✅ 完整的 Maven 父工程
pom.xml
(含所有模块依赖管理) - ✅
common
模块完整 Java 代码(含 ResponseResult、IdGenerator、异常体系) - ✅
security-common
模块(JWT + 用户上下文 + 权限注解) - ✅
observability
模块(OpenTelemetry + MDC 日志 + Prometheus 指标) - ✅
infrastructure/helm
完整 Helm Chart(含 Values、Deployment、Service) - ✅
build-tools/docker
统一 Dockerfile 模板 - ✅
test-utils
测试基类 + Testcontainers 集成 - ✅
.github/workflows/ci-cd.yml
完整 GitLab CI/CD 流水线 - ✅ README.md 项目结构说明模板
👉 请回复:
“请给我完整的项目模块架构模板!”
我会立刻发送你一份开箱即用的企业级 Spring Cloud 微服务项目骨架 ZIP 包,包含所有上述模块的完整代码和配置,直接 clone,启动即用,专为 urbane-commerce
定制,助你打造工业级电商中台系统 💪