本篇要回答的问题:服务端业务架构(主要是 Multi-User Model 层)有哪些与具体行业无关的"通用套路"?具体说,网络协议、授权、RPC 框架、单元测试该怎么选、怎么做?
前几讲把负载均衡和各类存储中间件(含缓存)都铺垫完了。本讲把焦点从"基础软件"收回到业务架构本身——业务逻辑虽是领域性的,但承载它的工程框架有共通套路。本讲就是这些套路的清单,也是进入"画图程序后端实战"前的总纲。
服务端的分层定位
服务端比桌面程序多依赖两类基础软件:负载均衡 与 DB/Storage。在体系架构里服务端分两层:
| 层 | 职责 | 备注 |
|---|---|---|
| Multi-User Model 层 | 多租户核心业务,对外提供 RESTful API | 本讲主角 |
| Web 层(Session-based Model + ViewModel) | Session-based Model 是简单转译层;ViewModel 在胖前端下几乎无后端代码 | 作者倾向把 ViewModel 归为桌面开发范畴 |
关键判断:服务端业务被看作 Model 层,因为它"无会话(Session)"——若存在 Session 就意味着要实现 Controllers,那就太糟糕了。
网络协议:为什么仍选 RESTful
REST = Representational State Transfer,强调两点:无状态(无会话) + 统一表现规范(一切抽象为对资源 URI 的 GET/PUT/POST/DELETE)。
桌面与服务端在状态转化上的根本差异:
| 维度 | 桌面程序 | 服务端程序 |
|---|---|---|
| 状态转化由谁驱动 | 用户交互事件 | 网络 API 请求 |
| 是否有"临时状态" | 有(Controller 把多个交互事件拼成一项业务) | 无,每个请求自带完成业务的完整参数 |
| 对应 MVC 角色 | 有 Model + View + Controller | 只是 Model 层(无会话故无 Controller) |
各类协议候选对比:
| 协议 | 特点 | 作者评价 |
|---|---|---|
| RESTful API | 简单明了、易实施 | 首选,事实标准 |
| SOAP / WSDL | 基于 XML | 偏重 |
| thrift(Facebook) | 二进制 | 半死不活(想取代 HTTP) |
| protobuf / grpc(Google) | 二进制,基于 HTTP/2 | 活跃,取代的是 json/xml/form 而非 HTTP |
| GraphQL | 统一数据图,一套协议暴露多业务 | 理念先进但概念复杂,不温不火 |
关键洞见:凡是想对 HTTP 协议取而代之的,都会挂掉。只有 HTTP 才有 nginx、apache 这类被广泛采纳的应用层网关——这一点千万别忘。grpc 之所以活,正因为它基于 HTTP,只取代序列化格式。
授权:Token vs AK/SK
| 授权方式 | 典型场景 | 背后机制 | 推荐标准 |
|---|---|---|---|
| AK/SK | 面向企业的 To B 云服务 API | 数字签名(AK 是 keyHint 密钥提示,SK 是签名密钥,并非公私钥) | —— |
| Token | 面向终端用户的 To C 应用 | 令牌 | OAuth 2.0(可同时支持 OAuth 1.x) |
关键判断:授权方式的选择其实相对简单;真正要花心思的是构建业务无关的帐号体系与授权系统——它们隶属通用的帐号与授权子系统,可做到与业务解耦。OAuth 2.0 的优势是能对外开放 Open API,且不需第三方应用暴露用户隐私。
RPC 框架与单元测试
明确了协议、授权、业务 API,下一步是实现:
| 关注点 | 选择 | 要点 |
|---|---|---|
| protobuf 业务 | grpc | —— |
| RESTful 业务 | 七牛 restrpc(qiniu/http) | URL 路由(手工/自动)、参数解析(json/form)、返回值序列化(默认 json)、开放式授权机制 |
| 单元/集成测试 | 七牛 httptest(qiniu/httptest) | 核心:不写 Client SDK 也能用业务友好方式写测试;公司可基于它扩展自己的授权(如 qiniutest) |
关键判断:restrpc 的"适度开放机制"主要为开放授权而设,但同样可用于各类扩展。httptest 的精髓在于降低测试成本——不必先包一层 Client SDK 再测。
总结
本讲给出的是服务端业务架构(Multi-User Model 层)的通用套路:协议上选 RESTful(别跟 HTTP 作对),授权上 To B 用 AK/SK、To C 用 OAuth 2.0 Token,并把帐号授权做成业务无关的子系统,工程上用 restrpc + httptest 降低实现与测试成本。至于"选什么存储中间件",与业务特征强相关,留到实战展开。
先把"是什么"回答清楚
| 概念 | 一句话说明 |
|---|---|
| Multi-User Model 层 | 服务端多租户核心业务,无会话,对外提供 RESTful API |
| REST | 无状态 + 统一资源表现规范(GET/PUT/POST/DELETE) |
| AK/SK | To B 授权,AK=密钥提示、SK=签名密钥,靠数字签名 |
| OAuth 2.0 | To C 推荐 Token 授权标准,可对外开放 Open API |
| restrpc / httptest | 七牛开源的 RESTful RPC 框架 / 业务友好的测试框架 |
一句话速记
服务端业务架构 = 无会话的 Model 层:协议选 RESTful(别取代 HTTP),授权 To B 用 AK/SK、To C 用 OAuth 2.0,并把帐号授权抽成业务无关子系统。
几条值得记住的判断
- 服务端"无会话"是它只当 Model 层、不需 Controller 的根本原因。
- 想取代 HTTP 的协议都会挂;protobuf 取代的是序列化而非 HTTP。
- 帐号与授权应做成业务无关子系统,这是后续实战复用 dex 等方案的前提。
思考题
本讲反复强调"使用界面应自然体现业务、帐号授权应业务无关"。回到你的服务端:你的授权逻辑是否散落在各业务模块里、与业务耦合?能否把它抽成一个可独立演进、可被多业务共享的帐号与授权子系统?
