第3章:分层架构演进:为什么需要分层、经典三层架构、好处与挑战、实际项目中的分层实践

3.1 为什么我们需要分层?

先聊个我亲身经历的事。几年前我接手过一个交易系统,代码全写在一个大文件里。数据库查询、业务逻辑、网络通信全混在一起。你猜怎么着?每次改个订单状态,都得把整个流程捋一遍。改完一个bug,至少冒出两个新bug。

为什么会这样?说白了,就是没有分层。

分层架构的核心思想很简单:把不同职责的代码拆开。就像盖楼,你不能把地基、承重墙、水电管线全糊在一起。每一层只关心自己的事,层与层之间通过明确的接口通信。

我个人习惯把分层比作「三权分立」。接入层管「谁来敲门」,逻辑层管「怎么处理」,数据层管「东西放哪」。各司其职,互不干扰。

核心原则:每一层只对下层有依赖,上层不关心下层的实现细节。

3.2 经典三层架构

交易系统里最经典的分层,就是这三层:

层级 职责 常见组件
接入层 协议解析、会话管理、流量控制 Gateway、Nginx、WebSocket Server
逻辑层 业务编排、风控校验、订单处理 Order Service、Risk Engine、Matcher
数据层 持久化、缓存、数据一致性 MySQL、Redis、Kafka

下面这张图,是我在项目中常用的分层结构。你看一眼就明白了:

接入层 协议解析 · 会话管理 · 限流熔断 · 安全认证 逻辑层 订单处理 · 风控校验 · 撮合引擎 · 资金结算 数据层 MySQL · Redis · Kafka · 分布式文件存储 请求方向 → 数据流向 ↓

3.3 分层带来的好处

我在项目中体会最深的有这几点:

  • 可维护性大幅提升——改接入层的协议,逻辑层完全不用动。我记得有一次把HTTP改成WebSocket,只改了接入层一个模块,逻辑层一行代码没碰。
  • 团队协作更顺畅——前端团队管接入层,后端团队管逻辑层,DBA团队管数据层。各干各的,互不踩脚。
  • 扩展性变强——想加个新的风控规则?在逻辑层加个模块就行。想换缓存方案?只改数据层。
  • 测试更容易——每层都可以单独写单元测试。我习惯给逻辑层写mock测试,把数据层mock掉,专注测业务逻辑。
小技巧:分层之后,建议每层都定义清晰的接口契约。用protobuf或者OpenAPI规范,这样层与层之间就像插拔式组件,换起来特别方便。

3.4 分层带来的挑战

当然,分层也不是银弹。你想想看,它也有麻烦的地方:

  • 性能损耗——每层之间都有序列化、网络开销。我见过一个系统,三层之间来回传对象,一次请求光序列化就占了30%的耗时。
  • 调试困难——问题跨层的时候,你得一层一层排查。我曾经花了一整天,才发现是接入层把时间戳截断了,导致逻辑层计算错误。
  • 过度设计——小项目硬套三层架构,反而增加复杂度。我建议:业务逻辑少于50个接口的项目,别急着分层。
避坑指南:我曾经在一个项目里,把逻辑层又拆了五层。结果呢?改一个需求要改四个文件。记住:分层不是越多越好,够用就行。

3.5 实际项目中的分层实践

说了这么多理论,来点实际的。我在一个日交易量过亿的系统中,是这样落地的:

接入层实践:

  • 用Nginx做反向代理和限流
  • 自定义Gateway处理协议转换
  • 每个连接分配一个Session ID,用于追踪

逻辑层实践:

  • 拆成多个微服务:Order Service、Risk Service、Settlement Service
  • 服务之间通过gRPC通信
  • 每个服务内部再分三层:Controller、Service、Repository

数据层实践:

  • MySQL存核心账户数据
  • Redis做热点缓存
  • Kafka做异步消息和日志

嗯,这里要注意:数据层不要直接暴露给接入层。我见过有人图省事,让接入层直接查数据库。结果呢?接入层一个慢查询,把整个数据库拖垮了。

最后分享一个我踩过的坑。有一次,逻辑层需要调用数据层的一个存储过程。存储过程里有个bug,导致数据不一致。排查的时候,逻辑层说「我传的参数没问题」,数据层说「我执行的逻辑没问题」。最后发现是存储过程里有个隐式类型转换。从那以后,我要求所有跨层调用都必须显式声明类型。

分层架构,说白了就是「分而治之」的思想。它不完美,但确实是交易系统最稳妥的起点。你想想看,没有分层,那些千万级的订单量,根本没法维护。


专注资料整理