Spring Boot 3.5 + Java 25 + Cloud Native 系列(一):Shop Platform 总览
目录
为什么要做这个项目#
在实际工作中,每当要推一套新的技术方向时,团队最常遇到的问题不是"知不知道这个技术",而是——“这东西跑起来是什么样子?出了问题怎么排查?和现有的模块能不能配合?”
光读官方文档和博客往往很难回答这些问题。于是我决定做一个尽量完整跑通的 POC 项目——一个电商平台原型,把当时想亲手验证的技术选型尽量放进同一个可运行工程里,看看它们在微服务场景中能不能协同工作。
这个项目就是 Shop Platform,也是本系列文章的主角。
2026-04 实践更新 目前主线仓库已经完成一批最初文章发布时仍在演进中的平台项:
auth-server→ RS256 + JWKS、api-gateway→ JWKS 校验 + Redisson Lua 限流、buyer-bff/seller-bff→ 全量@HttpExchangetyped clients、镜像构建 → AppCDS 三阶段构建。还刻意保持延期的,主要是DistributedLockExecutor抽象、搜索增强、AI 推荐等下一阶段能力。
系列会围绕几个方向展开:
- 总览(本文):项目背景、整体架构、技术栈速览
- 各层专题:API 网关、认证信任链、BFF 聚合、领域服务、事件总线、可观测、活动引擎……
- 工程实践:ArchUnit 架构测试、Maven Archetype 脚手架、Feature Toggle、KMP 跨端……
项目是什么#
Shop Platform 是一个云原生微服务电商平台 POC,支持:
- 买家/游客浏览商品、加购物车、结账下单
- 卖家管理商品、订单、促销
- 钱包真实货币支付(Stripe 接入)
- 积分、优惠券、活动(签到/抽奖/集卡/虚拟养成)
- 搜索、Webhook 开放平台、订阅续费
项目目的是技术验证,不是生产级业务实现。功能覆盖面是为了让各个技术模块都能找到真实的应用场景,而不是为了做完整的业务产品。
整体架构#
整体分为五个层次:
Buyer Portal / Buyer App / Seller Portal"] Gateway["边缘层: API Gateway
JWT 校验 · Trusted Headers · Redis Lua 限流 · Canary 灰度"] BFF["聚合层: Buyer BFF ↔ Seller BFF
Virtual Threads + Resilience4j"] Domain["领域服务层
profile · marketplace · order · wallet
promotion · loyalty · activity · search
notification · webhook · subscription"] Infra["基础设施层
MySQL 8.4 · Kafka 3.9 · Redis 7.4 · Meilisearch 1.12 · Garage S3"] Obs["可观测层
Micrometer · OTel Collector · Tempo · Loki
Grafana · Prometheus · Pyroscope"] Client -->|"HTTPS"| Gateway Gateway -->|"Trusted Headers"| BFF BFF --> Domain Domain --> Infra Domain -.->|"metrics · traces · logs"| Obs BFF -.->|"metrics · traces · logs"| Obs Gateway -.->|"metrics · traces · logs"| Obs
流量路由#
| 路径前缀 | 目标 |
|---|---|
/buyer/** |
buyer-portal(Kotlin SSR,SEO/游客模式) |
/buyer-app/** |
buyer-app(KMP WASM SPA,交互式购物体验) |
/seller/** |
seller-portal(部署单元名;内容来自 frontend/kmp/seller-app) |
/api/buyer/** |
buyer-bff(聚合领域服务) |
/api/seller/** |
seller-bff(聚合领域服务) |
/api/loyalty/** |
loyalty-service |
/api/activity/** |
activity-service |
/api/webhook/** |
webhook-service |
/api/subscription/** |
subscription-service |
/auth/** |
auth-server |
/public/** |
白名单,无需鉴权 |
Gateway 完成 JWT 校验后,把身份信息(Buyer-Id、Username、Roles、Portal)以 Trusted Headers 形式注入请求,下游服务直接信任这些 header,不需要重复解析 token。
前端架构演进#
项目采用渐进式前端策略,根据不同场景选择最适合的技术栈:
Kotlin + Thymeleaf SSR"] BA["Buyer App
KMP WASM SPA"] SP["Seller Portal
KMP WASM via seller-portal"] BP --> L["/buyer/login 登录页"] BP --> R["/buyer/register 注册页"] BP --> C["/buyer/catalog 商品浏览 SEO"] BA --> D["/buyer-app/ 购物车 · 结账 · 订单追踪"] SP --> E["/seller/ 商品 · 订单 · 促销管理"]
KMP(Kotlin Multiplatform)模块采用功能模块化设计:
| KMP 模块 | 职责 |
|---|---|
core |
网络层、状态管理、路由、主题系统 |
feature-auth |
认证流程(JWT、Google/Apple/OTP 登录) |
feature-cart |
购物车管理(游客/登录态统一) |
feature-marketplace |
商品浏览、搜索、筛选 |
feature-order |
订单创建、追踪、历史 |
feature-profile |
用户档案、地址簿 |
feature-promotion |
优惠券、活动展示 |
feature-wallet |
钱包余额、充值、Stripe 支付 |
ui-shared |
通用 UI 组件库 |
buyer-app |
买家应用组装(WASM) |
seller-app |
卖家应用组装(WASM) |
这种拆分让同一套 feature-* 模块可以复用到 WASM Web、Android 和 iOS 客户端;对一个技术验证型 POC 来说,这种组织方式比为每个端单独复制业务逻辑更容易观察演进成本。
服务清单#
| 服务 | 语言 | 职责 |
|---|---|---|
api-gateway |
Java 25 | 统一入口、JWT 校验、限流、灰度 |
auth-server |
Java 25 | JWT 签发、Google/Apple/OTP 登录、游客 token |
buyer-bff |
Java 25 | 买家聚合、游客购物流、结账编排 |
seller-bff |
Java 25 | 卖家工作台聚合 |
buyer-portal |
Kotlin | 买家 SSR 门户(Thymeleaf) |
buyer-app |
Kotlin Multiplatform | 买家 WASM 应用(frontend/kmp/buyer-app) |
seller-portal |
Kotlin Multiplatform | 卖家门户静态发布单元(构建自 frontend/kmp/seller-app) |
profile-service |
Java 25 | 用户档案、地址簿 |
marketplace-service |
Java 25 | 商品目录、SKU、库存、评价 |
order-service |
Java 25 | 订单状态机、购物车(登录态) |
wallet-service |
Java 25 | 钱包余额、充值/提现、Stripe 接入 |
promotion-service |
Java 25 | 促销引擎、优惠券(策略模式可扩展) |
loyalty-service |
Java 25 | 积分账户、签到、积分兑换 |
activity-service |
Java 25 | 互动活动中心(插件化游戏引擎) |
search-service |
Java 25 | Meilisearch 全文搜索、Feature Toggle 试点 |
notification-service |
Java 25 | 邮件通知、Channel SPI 可扩展 |
webhook-service |
Java 25 | Webhook 订阅、HMAC 签名、失败重试 |
subscription-service |
Java 25 | 订阅计划、自动续费 |
技术栈#
语言与框架基线#
| 维度 | 版本 |
|---|---|
| JDK | Java 25 |
| Spring Boot | 3.5.11 |
| Spring Cloud | 2025.0.1 |
| Kotlin | 2.3.20 |
| 构建工具 | Maven + Maven Wrapper |
父 POM 统一管理所有版本,通过 Maven Enforcer 强制最低 JDK 版本,各子模块继承父 POM 而不自行指定 Spring 版本。这让版本组合更容易复现和比较;至于是否直接作为生产基线,仍要结合团队支持策略与依赖兼容性评估。
基础设施#
| 维度 | 技术选择 |
|---|---|
| 数据库 | MySQL 8.4(每服务独立 schema + Flyway 迁移) |
| 消息队列 | Apache Kafka 3.9(KRaft 模式,无需 ZooKeeper) |
| 缓存 | Redis 7.4 + Redisson(分布式锁、Lua 脚本) |
| 搜索 | Meilisearch 1.12 |
| 对象存储 | Garage S3(兼容接口,存 Trace/Log 数据和商品图片) |
| 支付 | Stripe SDK(通过 Gateway 接口抽象,可插拔替换) |
可观测栈#
Micrometer + OTLP Logback + shop.profiling"] OTel["采集层: OpenTelemetry Collector
Trace + Log + K8s 元数据富化"] Tempo["Tempo
Trace"] Loki["Loki
Log (OTLP)"] Grafana["展示层: Grafana"] Prometheus["指标: Prometheus
Exemplar (Trace ↔ Metric 双向关联)"] Pyroscope["持续分析: Pyroscope
CPU/内存火焰图"] Alert["告警: Prometheus Alert Rules
+ SLO Burn-rate Rules"] App -->|"OTLP"| OTel OTel --> Tempo OTel --> Loki Tempo --> Grafana Loki --> Grafana Prometheus --> Grafana App -->|"scrape"| Prometheus Prometheus --> Exemplar["Exemplar 关联 Trace"] Tempo -.->|"关联"| Pyroscope Loki -.->|"关联"| Pyroscope Prometheus --> Alert
所有 Java 服务通过 shop-common 的 ObservabilityAutoConfiguration 自动装配,当前基线里就具备 metrics、traces、structured logs 和 profiling 接入点,不需要每个服务单独重复配置。
几个值得关注的设计决策#
Virtual Threads 替代 WebFlux#
Gateway 和所有 BFF/Domain 服务都启用了 Virtual Threads,而没有选 WebFlux。
原因:Virtual Threads 让 I/O 密集型微服务获得可接受的并发能力,同时保留了同步代码的可读性和可调试性。对于聚合多个下游调用的 BFF 来说,代码模型是:
// 并发读多个下游,代码仍然是同步风格
var profile = profileClient.getProfile(playerId); // 实际运行在不同 VT 上
var cart = cartStore.getCart(sessionId);
var products = marketplaceClient.getProducts(productIds);
如果用 WebFlux,同样的逻辑会变成 Mono.zip(...) 链条,调试和错误追踪的成本都会上升。
Outbox Pattern 替代分布式事务#
跨服务传播的业务事实(如下单扣库存、充值通知积分)全部走:
好处:本地事务原子性有保证,事件可重放,失败可补偿,而且不依赖任何分布式事务协调器。
Strategy + Plugin 保持扩展性#
两个场景用了类似的思路:
促销引擎:BenefitCalculator 和 ConditionEvaluator 都是 SPI 接口,新增一种折扣规则只需实现接口,PromotionEngine 通过 Spring 自动发现。
活动游戏引擎:GamePlugin 接口 + GamePluginRegistry,目前已有砸金蛋/抽奖、抢红包、集卡、虚拟养成四种插件。新增游戏类型至少不需要改引擎核心代码;是否需要重启或额外部署,仍取决于最终交付方式。每个插件有自己的扩展表前缀,Redis key 命名空间隔离。
shop-contracts 集中管理contract#
API path 常量、跨服务共享的 DTO、事件 envelope 全部放在 shop-contracts 模块。BFF、Portal、Worker 都从同一个地方引用,消除字符串拼接和 DTO 复制。
shop-common 的共享能力#
ApiResponse<T>:统一 northbound 响应模型BusinessException+CommonErrorCode:统一错误语义(SC_ 前缀错误码)HeaderPropagationInterceptor:在RestClient链路中继续透传 Gateway 注入的可信 Header- OTLP logback appender + 结构化日志自动配置
云原生工程实践#
Kubernetes 优先#
platform/k8s/ 目录包含完整的 K8s manifest:应用部署、基础设施(MySQL/Redis/Kafka)、可观测组件(Prometheus/Tempo/Loki/Grafana/Pyroscope)。本地用 Kind 集群运行,流程尽量贴近集群环境。
每个服务遵循统一端口规范(应用 8080,Actuator/Management 8081),K8s 探针、Prometheus ServiceMonitor、资源请求/限制在当前仓库里也都已经给出了对应配置。
Feature Toggle#
search-service 是试点场景:
OpenFeature SDK (供应商无关 API)
→ 仓库内 property provider
→ ConfigMap 目录挂载
→ Configuration Watcher + /actuator/refresh(热更新)
不依赖第三方控制面,用 K8s 原生能力就能完成动态配置下发。
ArchUnit 架构测试#
architecture-tests 模块通过 ArchUnit 验证代码约定:
- Controller 不能直接调用 Repository
- BFF 不能持有 JPA Entity,需要通过 HTTP 聚合领域服务
- 不允许使用
RestTemplate或手动创建传统线程池 - Kafka 消费者需要实现幂等处理
架构约束变成可自动执行的测试用例,而不是靠 Code Review 口头约定。
Maven Archetype 脚手架#
shop-archetypes 提供 6 个模板:
| Archetype | 适用场景 |
|---|---|
gateway-service-archetype |
Spring Cloud Gateway 服务 |
auth-service-archetype |
OAuth2 资源服务器 + JWT |
bff-service-archetype |
BFF 聚合层 |
domain-service-archetype |
JPA + Flyway + MySQL 领域服务 |
event-worker-archetype |
Kafka 消费者 + Outbox worker |
portal-service-archetype |
Kotlin + Thymeleaf SSR 门户 |
新建服务时从 archetype 出发,开箱就有统一的目录结构、依赖、可观测配置和测试基类,不需要从旧模块复制再手工删改。
可能的参考方向#
这个项目的初衷是为真实项目的技术选型提供一个可运行的参照系。以下几个方向,我觉得更适合拿来做讨论起点:
技术版本组合:Java 25 + Spring Boot 3.5 + Spring Cloud 2025.0.1 是这套 POC 当前采用并跑通的一组组合。它对 2026 年的新项目可能有参考价值,但是否直接进入生产,还要结合团队对 JDK/Spring 支持周期、三方依赖兼容性和运维基线做判断。
Virtual Threads vs WebFlux:对于这个项目里的 I/O 密集型微服务,Virtual Threads 在这个项目里已经提供了可接受的并发能力,同时保留同步代码的工程优势。新项目如果没有明确的 Reactive/Streaming 诉求,可以先从 Virtual Threads 起步,再按压测结果决定要不要换模型。
可观测性的成本:把 OTLP + Prometheus + Tempo + Loki + Pyroscope 全部接进来,在这个项目里至少验证过一轮基础接线与排障路径。实际项目可以按需裁剪,但底层链路模型已经有了一个可对照样本。
事件驱动的落地姿势:Outbox Pattern 是一种在不引入分布式事务的前提下处理跨服务一致性的方案。本项目在 order、wallet、marketplace、activity 等服务里都有具体实现,适合拿来讨论边界和取舍。
SPI 驱动扩展性:促销引擎和活动游戏引擎的 Strategy/Plugin 设计,在业务规则经常变化的场景下能降低主线代码的膨胀速度。它不一定适合所有团队,但至少提供了一个比较清晰的扩展样例。
参考与实现位置#
- Spring Cloud Gateway Server MVC:https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway-server-webmvc.html
- OpenTelemetry Docs:https://opentelemetry.io/docs/
- ArchUnit User Guide:https://www.archunit.org/userguide/html/000_Index.html
- OpenFeature Java:https://openfeature.dev/docs/reference/technologies/server/java/
- 仓库内可以直接对照的入口:
pom.xml、frontend/settings.gradle.kts、services/api-gateway/src/main/resources/application.yml、shared/shop-common/、tooling/architecture-tests/、platform/k8s/
下一篇#
下一篇会深入 API Gateway 模块:Spring Cloud Gateway Server MVC 的路由配置、JWT 校验过滤器、Redis Lua 限流、Trusted Headers 注入,以及从 WebFlux 迁移到 MVC + Virtual Threads 的背景和得失。
项目仓库:github.com/meirongdev/shop(公开,可结合源码一起看)