▲ 点击上方“分布式实验室”关注公众号
回复“1”抽取纸质技术书
— 1 —
背景
在知乎,我们很早就进行了非常彻底的容器化部署。全站在线运行的微服务数量高达两千多个。这些微服务通过我们自己维护的 RPC 框架和 Kodor 体系来实现服务互联的能力。
在这其中,我们也存在一系列的问题:
各种基础组件维护成本比较高,单点风险存在。
各语言客户端特性难以统一,熔断、重试等特性实现颇有不同,且不能做到动态线上进行调整。
客户端版本迭代难以推动。
微服务某些能力上跟其他大厂还有差距。
与社区、云原生距离较远,配合常见的开源项目紧密度较差。
Service Mesh 可以很好的解决上面的这些问题:
提升微服务治理能力,规范的引入精准的熔断、限流、流量管理等手段。
减少客户端维护、迭代的投入。
提升服务间通信速度。
具备故障注入能力。
具备动态服务路由调整的能力。
因此,我们选择拥抱社区、拥抱 Service Mesh、拥抱 Istio。
— 2 —
Kodor 体系介绍
我们先聊一聊知乎之前的微服务体系:Kodor。
在这个系统里,我们会为所有微服务都创建一组 HAProxy 容器。
而所有发向目标服务的流量都会经过这一组 HAProxy。
HAProxy 负责记录基本的指标和访问日志,并实现鉴权、限流、黑名单等功能。
在这一点上, Kodor 系统与服务网格可以算得上是异曲同工之妙,即都是借用代理来实现原本在微服务框架上实现的功能。
— 3 —
服务发现与注册
在 Kodor 体系中,Consul 是主要用来作为服务发现和注册的关键组件。
我们将服务的 HAProxy 节点作为服务节点注册到 Consul 。
同时,将服务自身的各节点信息,存储在 Consul 指定路径的 KV 。
这样客户端通过 Consul 发现的服务地址实际上是服务的 HAProxy 地址。
而 HAProxy 则通过 consul-template 的感知上游节点信息。
整体架构如下图所示:
— 4 —
Servive Mesh 迁移方案
目标
我们首先要确认迁移方案的一个基本要求。
即满足这几个保证:
保证业务无感知迁移,不变更代码
保证可回滚
保证高可用
保证性能无明显下滑
保证 Mesh 内的服务和 Kodor 的服务可以互相访问
基于以上的目标要求,我们设计了如下的一个迁移方案。
流量互通方案
让我们先看看这两个通路的区别:
从整体上来看还是非常的类似的,都是先经过 Consul 的服务发现或是 DNS 查询,再进行 RPC 或 HTTP 的流量访问。
由于我们无法要求业务程序进行代码修改,因此无论如何服务发现的组件需要得到保留。(这一点的原因是大量长尾项目难以推动,耗费大量人力资源可能得不偿失)
通过引入一个新的服务发现服务(Discovery),我们可以轻松的让 Mesh 和 Kodor 的服务实现互通。
这里存在两种 Case:
1、调用方服务在 Mesh 内
当目标服务不在 Mesh 内,Discovery 服务返回的地址是服务的 HAProxy 的地址(也就是将流量代理到 Consul)。
当目标服务在 Mesh 内,Discovery 服务将返回服务的 ServiceIP,此时应用将通过 Sidecar 触发 Service Mesh 的路由能力,将请求直接传递到对端 Sidecar。
2、调用方服务不在 Mesh 内
我们仍然保留服务的 HAProxy,因此调用方仍然可以通过 “Consul” 发现 HAProxy 端点,进行流量的投递。
流量管理
1、沙箱联调的支持
在知乎,我们有一种功能叫沙箱联调。
即创建一种沙箱,在沙箱内部署的服务在调用其他服务的时候,优先访问沙箱内部署的负载组。