第3章:平台架构设计:分层架构、微服务架构、技术选型(Spring Cloud / K8s)

好,咱们进入正题。需求响应聚合平台,说白了就是一个「中间人」系统。它一边连着电网调度,一边连着成千上万的用户侧资源。这种场景下,架构设计要是搞砸了,后面全是坑。我个人习惯,做这类平台先想清楚两件事:一是系统怎么拆,二是技术栈怎么选。

3.1 分层架构:先搭好骨架

我最早做能源项目时,喜欢把所有逻辑塞进一个单体应用。结果呢?每次改个计量规则,整个系统都要重新部署。后来我学乖了——分层,必须分层。

一个典型的分层架构,从上到下大概是这样:

┌─────────────────────────────────────┐
│         接入层(API Gateway)        │
├─────────────────────────────────────┤
│         应用层(业务逻辑)           │
├─────────────────────────────────────┤
│         服务层(核心能力)           │
├─────────────────────────────────────┤
│         数据层(存储与缓存)         │
└─────────────────────────────────────┘

每一层各司其职:

  • 接入层:处理认证、限流、协议转换。我建议用统一的API网关,别让业务代码去操心这些事。
  • 应用层:编排业务流程。比如「用户注册→资源接入→策略匹配」,这层只管流程,不管具体怎么算。
  • 服务层:提供原子能力。像「负荷预测」「基线计算」「结算引擎」,每个都是独立模块。
  • 数据层:负责持久化。关系库存交易数据,时序库存量测数据,缓存扛热点。

核心原则:上层依赖下层,下层不依赖上层。我曾经见过一个项目,数据层直接调了应用层的接口,结果改一个字段,全链路都要回归——那叫一个酸爽。

3.2 微服务架构:拆还是不拆?

很多朋友一上来就问:「要不要上微服务?」我的回答是:先看规模。如果你只有几百个用户,单体+分层完全够用。但需求响应平台,用户量级通常是万级甚至百万级,而且业务模块之间耦合度低——这时候微服务就是必然选择。

我建议按「业务边界」来拆。举个例子:

服务名称 职责 典型接口
用户服务 管理聚合商、终端用户信息 注册、认证、权限
资源服务 管理可调负荷、储能、充电桩 资源注册、状态上报
策略服务 生成需求响应策略 策略计算、下发
结算服务 计算补贴、收益分成 账单生成、对账
监控服务 实时数据采集与告警 遥测、事件推送

每个服务独立部署、独立数据库。服务之间通过轻量级API通信。嗯,这里要注意:别搞成「分布式单体」——就是拆了服务但数据库还共用一个,那还不如不拆。

避坑指南:我曾经把一个「策略服务」拆得太细,分成了「基线计算」「响应评估」「激励计算」三个微服务。结果每次策略下发要调5次接口,延迟从50ms飙到500ms。后来我合并了强相关的逻辑,才把性能拉回来。微服务的粒度,以「独立变更、独立部署」为准,别为了拆而拆。

3.3 技术选型:Spring Cloud vs K8s

这是大家最纠结的地方。我直接说结论:Spring Cloud 适合「微服务治理」,K8s 适合「容器编排」。两者不是二选一,而是互补关系。

3.3.1 Spring Cloud:服务治理的瑞士军刀

如果你团队Java技术栈比较强,Spring Cloud是首选。它提供了:

  • Nacos:服务注册与配置中心。我个人习惯用它替代Eureka,因为Nacos支持动态配置刷新,省去了重启服务的麻烦。
  • Gateway:路由、限流、熔断。比Zuul性能好不少。
  • Feign + Sentinel:声明式调用 + 流量控制。我在项目中用Sentinel做过一个「按聚合商等级限流」的策略——VIP用户优先响应,普通用户排队,效果不错。
// 一个典型的Feign客户端示例
@FeignClient(name = "resource-service", path = "/resources")
public interface ResourceClient {
    
    @PostMapping("/register")
    Result<ResourceVO> register(@RequestBody ResourceDTO dto);
    
    @GetMapping("/status/{resourceId}")
    Result<StatusVO> getStatus(@PathVariable("resourceId") String resourceId);
}

小技巧:Feign接口一定要加fallback工厂。我曾经线上环境资源服务挂了,因为没有降级策略,导致用户服务线程池被打满——整个平台瘫痪了10分钟。从那以后,每个Feign接口我都配了Sentinel熔断。

3.3.2 K8s:容器编排的工业标准

如果你的团队运维能力较强,或者系统需要跨云部署,K8s是更好的底座。它解决的是「部署、扩缩容、自愈」的问题。

我建议的部署模式是这样的:

┌─────────────────────────────────────────────┐
│              K8s 集群                        │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  │
│  │ 用户服务  │  │ 资源服务  │  │ 策略服务  │  │
│  │ (Pod x3) │  │ (Pod x5) │  │ (Pod x2) │  │
│  └──────────┘  └──────────┘  └──────────┘  │
│  ┌──────────────────────────────────────┐   │
│  │  Ingress (统一入口)                   │   │
│  └──────────────────────────────────────┘   │
└─────────────────────────────────────────────┘

每个服务跑在独立的Pod里,通过Service暴露内部地址。Ingress负责外部流量接入。当负荷预测高峰期到来,K8s自动扩Pod——我见过一个场景,响应事件触发时,策略服务的Pod从2个自动扩到20个,整个过程不到30秒。

我的建议:Spring Cloud + K8s 组合拳。Spring Cloud管服务间的「东西向流量」(服务调用、熔断、配置),K8s管「南北向流量」(外部请求、部署、扩缩容)。两者各司其职,互不冲突。

3.4 核心架构图:一张图看懂全局

下面这张图,是我在多个项目中沉淀下来的架构模板。你直接拿去用,基本不会出大问题。

接入层:API Gateway (Spring Cloud Gateway + Nginx) 应用层:业务编排 用户注册流程 | 资源接入流程 | 策略下发流程 | 结算流程 服务层:核心能力 (Spring Cloud 微服务) 用户服务 | 资源服务 | 策略服务 | 结算服务 | 监控服务 Nacos (注册/配置) | Sentinel (熔断/限流) | Feign (服务调用) 数据层:存储与缓存 MySQL (交易数据) | InfluxDB (时序数据) | Redis (缓存/队列) 基础设施:K8s 集群 (Pod / Service / Ingress / HPA)

这张图里,每一层都对应了具体的技术组件。你想想看,从用户请求进来,到最终数据落库,整个链路清晰明了。我在实际项目中,就是拿着这张图跟团队对齐的——省去了大量口舌。

3.5 技术选型对比:一张表说清楚

维度 Spring Cloud K8s 我的建议
服务发现 Nacos / Eureka Service + DNS 内部调用用Nacos,外部用K8s Service
配置管理 Nacos Config ConfigMap 动态配置用Nacos,静态配置用ConfigMap
熔断限流 Sentinel / Hystrix 无原生支持 必须用Sentinel,K8s管不了这个
部署扩缩 需配合Jenkins 原生HPA K8s完胜,自动扩缩太香了
学习成本 中(Java开发者友好) 高(需懂容器化) 团队Java强选Spring Cloud,运维强选K8s

我的经验:别纠结「全用Spring Cloud还是全用K8s」。我现在的项目是:Spring Cloud做服务治理,K8s做部署底座。每个微服务打包成Docker镜像,通过K8s部署。服务之间的调用走Feign,配置走Nacos。这套组合我用了两年,线上没出过大问题。

3.6 避坑总结:那些年我踩过的雷

  • 服务拆分太细:我曾经把「资源服务」拆成「充电桩服务」「储能服务」「空调服务」三个微服务。结果每次资源注册要调三个接口,数据库还得做分布式事务——后来我合并了,世界清净了。
  • 忽略配置中心:早期项目没用Nacos,每次改个数据库连接串都要重新打包部署。后来我强制所有配置外置,改配置就像改文本一样简单。
  • K8s资源限制没配:有一次策略服务内存泄漏,因为没有设置limits,Pod把整个Node的内存吃光了,导致其他服务集体OOM。现在我的每个Pod都配了requests和limits,谁也别想抢谁的资源。

嗯,架构设计这块,说白了就是「权衡」。没有银弹,只有适合你场景的方案。你只要记住:分层要清晰,服务要独立,选型要务实。剩下的,交给时间去验证。


公众号:蓝海资料掘金营,微信deep3321