API Gateway
历史的微服务架构
存在的问题:
- 客户端到微服务直接通信、强耦合
需要多次请求、客户端聚合数据、工作量巨大
- 轻前端重后端
- 前端逻辑太重、发版太慢
- 协议不统一
- 面向端的 API 适配
- 多端兼容逻辑。每个服务都需要处理
- 统一逻辑无法收敛,比如安全认证、限流
新增 app-interface 用于统一的协议出口
在内进行大量的 dataset join,按照业务场景来设计粗粒度的 API,BFF 层
特点:
- 轻量交付:协议精简、聚合。不同设备或者网络做区分
- 差异服务:数据裁剪以及聚合、针对终端定制化 API。
- 动态升级:原有系统亲容升级,更新服务而非协议。
- 沟通效率提升,协作模式演进为形动业务+网关小组。
BFF 可以认为是一种适配服务,将后端的微服务进行运配(主要包括聚合裁剪和格式适配等逻辑),向无线端设备暴露友好和统一的API,方便无线设备接入访问后端服务。
存在的问题:
- app-interface 属于
single point of failure
- 单个模块体积庞大、团队之间沟通协调成本高,交付效率低下。
- 很多跨横切面逻辑,比如安全认证,日志监控,限流熔断等。随着时间的推穆,代码变得越来越复杂, 技术债越堆越多
之前一些限流、认证、安全的逻辑,如果放在 BFF 里面,推动别人升级会有很大的阻力,再抽出一层来单独做公共的功能
跨横切面(Cross-Cutting Concerns)的功能,需要协调更新框架升级发版(路由、认证、限流、安全),因此全部上沉,引入了 API Gateway,把业务集成度高的 BFF 层和通用功能服务层 API Gateway 进行了分层处理。
在新的架构中,网关承担了重要的角色,它是解耦拆分和后续升级迁移的利器。在网关的配合下,单块 BFF 实现了解耦拆分,各业务线国队可以独立开发和交付各自的微服务,研发效率大大提开。另外,把跨横切面逻辑从 BFF 剥离到网关上去以后,BFF 的开发人员可以更加专注业务逻辑交付,实现了架构上的关注分离 (Separation of Concerns)。
微服务划分
大多通过业务职能 (Business Capability)或是 DDD 的限界上下文(Bounded Context)
• Business Capability
由公司内部不同部门提供的职能。例如客户服务部门提供客户服务的职能,财务部门提供财务相关的职能。
• Bounded Context
限界上下文是 DDD 中用来划分不同业务边界的元素,这里业务边界的含义是“解决不同业务问题” 的问题域和对应的解决方案域,为了解决某种类型的业务问题,贴近领域知识,也就是业务。
这本质上也促进了组织结构的演进:Service per team
CQRS,将应用程序分为两部分:命令端和查询端 。
命令端处理程序创建,更新和删除请求,并在数据更改时发出事件。查询端通过针对一个或多个物化视图执行查询来处理查询,这些物化视图通过订阅数据更改时发出的事件流而保持最新。
在稿件服务演进过程中,我们发现围绕着创作稿件、审核福件、最终发布福件有大量的逻辑操在一块,其中稿件本身的状态也有非常多种,但是最终前台用户只关注福件能否查看,我们依赖高件数据库binlog 以及订阅 binlog 的中间件 canal,将我们的稿件结果发布到消息队列kafka 中,最终消费数据独立组建一个稿件查阅结果数据库,并对外提供一个独立查询服务,来拆分复杂架构和业务。
我们架构也从 Polling publisher -> Transaction log tailing 进行了演进(Pull vs Push)
微服务安全
对于外网的请求来说,我们通常在 API Gateway 进行统一的认证拦截,一旦认证成功,我们会使用 Header 方式通过RPC 元数据传递的方式带到 BFF 层,BFF 获取后把身份信息注入到应用的 Context 中,BFF 到其他下层的微服务,建议是直接在 RPC Request 中带入用户身份信息 (UserlD)请求服务。
• API Gateway ->BFF -> Service
• Biz Auth -> UID -> Request Args
对于服务内部,一般要区分身份认证和授权。
• Full Trust
• Half Trust
• Zero Trust
内网 RPC 服务鉴权