Go进阶训练营 – 微服务概览与治理二:微服务设计
本文最后更新于 1000 天前,其中的信息可能已经有所发展或是发生改变。

同系列文章:Go 进阶训练营

API Gateway

B 站进行了 SOA 服务化的架构演进,按照垂直功能进行了拆分,对外暴露了一批微服务,但是因为缺乏统一的出口面临了不少困难:

1.0

image-20220502191549104

  • 客户端到微服务直接通信,强耦合。
    • 如果涉及移动端,同时存在多版本,api 兼容困难,重构困难,用户可能还在使用一年前版本的移动端。
  • 需要多次请求,客户端聚合数据,工作量巨大,延迟高。
    • 聚合数据应该在服务端做
      1. 服务端对自己提供的数据最了解,减少和客户端的沟通成本。
      2. 多次请求,网络开销大
    • 客户端使用的 API,不应面向资源,应面向用户场景。服务端内部 API 应该面向资源,降低耦合性,提升可复用性
  • 协议不利于统一,各个部门间有差异,需要客户端来兼容。
    • 客户端不好控制,无法强制升级
    • 客户端发版难,不像服务端,不停机更新都可以
    • 前轻后重,移动端应该尽量轻量,因为发版受限,用户更新不可控,服务端可控性相对较高
  • 面向 “端” 的 API 适配,耦合到了内部服务。
    • 移动端适配难,不同移动端需要的字段不同,接口需要考虑兼容性
    • 多终端兼容逻辑复杂,每个服务都需要处理。
  • 统一逻辑无法收敛,比如安全认证、限流

2.0

image-20220502191615290

我们新增了一个 app-interface 用于统一的协议出口,在服务内进行大量的 dataset join,按照业务场景来设计粗粒度的 API,给后续服务的演进带来的很多优势:

  • 轻量交互:协议精简、聚合。
  • 差异服务:数据裁剪以及聚合、针对终端定制化 API
  • 动态升级:原有系统兼容升级,更新服务而非协议。
  • 沟通效率提升:协作模式演进为移动业务 + 网关小组。

BFF(background for frontend) 可以认为是一种适配服务,将后端的微服务进行适配 (主要包括聚合裁剪和格式适配等逻辑),向无线端设备暴露友好和统一的 API,方便无线设备接入访问后端服务。

  • 单体场景层
  • 感觉这里的网关层和场景层合二为一了

在计算机科学领域里的任何问题,都可以通过引入一个中间层来解决,不行就再加一层

...except for the problem of too many layers of indirection

存在的问题

最致命的一个问题是整个 app-interface 属于 single point of failure(单点故障),严重代码缺陷或者流量洪峰可能引发集群宕机。

  • 单个模块也会导致后续业务集成复杂度高,根据康威法则,单块的无线 BFF 和多团队之间就出现不匹配问题,团队之间沟通协调成本高,交付效率低下。

    本来是场景层的多个场景,这里只有一个,所以这个 BFF 需要掌握所有业务,和组织机构不匹配。

3.0

image-20220502192108190

场景层拆分为多个场景

存在的问题

很多跨横切面逻辑,比如安全认证,日志监控,限流熔断等。随着时间的推移,代码变得越来越复杂,技术债越堆越多。

BFF 包含了业务,每个服务都得加上上诉功能,所以臃肿

4.0

image-20220504175550325

抽取网关层

跨横切面 (Cross-Cutting Concerns) 的功能,需要协调更新框架升级发版 (路由、认证、限流、安全),因此全部上沉,引入了 API Gateway,把业务集成度高的 BFF 层和通用功能服务层 API Gateway 进行了分层处理。

在新的架构中,网关承担了重要的角色,它是解耦拆分和后续升级迁移的利器。在网关的配合下,单块 BFF 实现了解耦拆分,各业务线团队可以独立开发和交付各自的微服务,研发效率大大提升。另外,把跨横切面逻辑从 BFF 剥离到网关上去以后,BFF 的开发人员可以更加专注业务逻辑交付,实现了架构上的关注分离 (Separation of Concerns)。

我们业务流量实际为:

移动端 -> API Gateway -> BFF -> Mircoservice,在 FE Web 业务中,BFF 可以是 nodejs 来做服务端渲染 (SSRServer-Side Rendering),注意这里忽略了上游的 CDN4/7 层负载均衡 (ELB)

4 层负载均衡

  • 传输层做负载均衡,客服端请求到负载均衡器,负载均衡器通过负载均衡算法匹配到服务端的地址,然后客户端与服务端直接连接,负载均衡器的作用相当于路由。

7 层负载均衡

  • 应用层做负载均衡,客服端请求到负载均衡器,负载均衡器通过请求内容匹配到服务端,这里读取了请求内容,所以客户端已经和负载均衡器 3 次握手连接了。然后负载均衡器再去连接服务端,又是一次连接。负载均衡器的作用相当于代理服务器。
  • 功能更强大
  • 复杂意味着性能差
  • 安全性高,可防御 DDos 攻击

微服务拆分

微服务架构时遇到的第一个问题就是如何划分服务的边界。在实际项目中通常会采用两种不同的方式划分服务边界,即通过业务职能 (Business Capability) 或是 DDD 的限界上下文 (Bounded Context)。

Business Capability

由公司内部不同部门提供的职能。例如客户服务部门提供客户服务的职能,财务部门提供财务相关的职能。

Bounded Context

限界上下文是 DDD 中用来划分不同业务边界的元素,这里业务边界的含义是 “解决不同业务问题” 的问题域和对应的解决方案域,为了解决某种类型的业务问题,贴近领域知识,也就是业务。

这本质上也促进了组织结构的演进:Service per team

如何拆分微服务,先按照业务领域,再考虑公司组织机构,避免出现一个服务多个部门负责。

刚开始的拆分可能会出现不合理的情况,和代码一样,都是不断重构,不断优化,才能做的更好。

CQRS

定义

Command and Query Responsibility Segregation。将应用程序分为两部分:命令端和查询端。命令端处理程序创建,更新和删除请求,并在数据更改时发出事件。查询端通过针对一个或多个物化视图执行查询来处理查询,这些物化视图通过订阅数据更改时发出的事件流而保持最新。

示例

image-20220530111707545

  • 在稿件服务演进过程中,我们发现围绕着创作稿件、审核稿件、最终发布稿件有大量的逻辑揉在一块,其中稿件本身的状态也有非常多种,但是最终前台用户只关注稿件能否查看,我们依赖稿件数据库 binlog 以及订阅 binlog 的中间件 canal,将我们的稿件结果发布到消息队列 kafka 中,最终消费数据独立组建一个稿件查阅结果数据库,并对外提供一个独立查询服务,来拆分复杂架构和业务。

  • 我们架构也从 Polling publisher -> Transaction log tailing 进行了演进 (Push vs Pull)。

  • 服务根据读写进行拆分。需要结合实际场景:1、对某个服务读操作和写操作的请求都有很多,整体服务庞大。2、写操作暴露出来比较危险,只想给部分服务调用,达到权限控制的目的。这时可以进行服务拆分,提供读操作的服务 watch 提供写操作的服务,也就是读写分离。

  • 为啥不直接数据库主从,因为读取服务并不是需要原数据库里的所有字段,只需要部分信息。所以同步逻辑需要自己实现,不能直接全部同步。

  • 读写分离的升级版。

微服务安全

image-20220530113439948

外网的请求

  1. 在 API Gateway 进行统一的认证拦截。

  2. 使用 JWT 方式通过 RPC 元数据传递的方式带到 BFF 层,BFF 校验 Token 完整性后把身份信息注入到应用的 Context 中。

    类似 http 请求里的 header

  3. BFF 到其他下层的微服务,在 RPC Request 中带入用户身份信息 (UserID) 请求服务。

服务内部请求

一般要区分身份认证和授权。服务可以通过证书区分调用服务是哪个服务,可通过配置中心进行权限控制。

分为以下级别:

  • Full Trust
  • Half Trust
  • Zero Trust
    • 例如请求加密
作者:Yuyy
博客:https://yuyy.info
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇