Lyft 的 Service Mesh 工具 Envoy

10月3日更新。Envoy 作为一个 Service Mesh 的软件而出名。而当看了 Envoy 的功能之后才发现,它使用这一个解决方案,解决了很多架构中的传统问题。


原文

Envoy 的链接

Lyft 的 SoA 架构

3-5年前,Lyft 的架构是, AWS ELB + Php monolith app + Mongo DB。出现的问题是,apache 服务器的连接数也是有限的。整个架构的 scalability 很差。

直到大概2年前,Lyft 采用了 SoA 架构

业内 SOA 在网络层的现状

  • 使用各种语言,各种框架
  • 对于一个工具 ,每个语言需要一个对应的 library
  • 使用各种协议: http1, http2, gRPC, db 协议,缓存机制
  • 使用各种基础设施: IaaS, Caas 等
  • 使用各种 Load balancer: AWS ELB, F5
  • Observability 问题,如何研究网站的流量:发送统计信息,并由logging收集整理信息,分布式跟踪请求(stats, logging, tracing)
  • 公司内个团队可能需要自己实现 retry, circuit breaker, rate limiting, timeout 等等基础功能
  • authentication, authorization
  • 当网络层问题出现的时候,很难 debug 这些问题
  • 很多基础设施,比如 LB、cache、网络拓扑,工程师很难了解这些部分的全貌
  • 而一些解决了这些问题的公司,他们大多数都是使用一个 library 来解决的。library 很容易被套在某个技术栈上,比如是基于某个编程语言的,如果要支持另一个语言,需要较大代价

所有这些变化,使得业内没有一个相对统一的维护方式,难以管理。

什么是 service mesh

我觉得 Istio 文档上的介绍比较精炼:

The term service mesh is used to describe the network of microservices that make up such applications and the interactions between them. As a service mesh grows in size and complexity, it can become harder to understand and manage. Its requirements can include discovery, load balancing, failure recovery, metrics, and monitoring. A service mesh also often has more complex operational requirements, like A/B testing, canary releases, rate limiting, access control, and end-to-end authentication.

Service mesh 适用于解决网站从 monolithic 架构到 SOA 转型过程中 microservice 之间网络交流的问题。这些问题包括 service discovery,load balancing,错误恢复,统计和监测。同时还可以用于一些运维方面的需求,比如 A/B testing,灰度发布, rate limiting 等等

Envoy

Envoy 认为,网络层应该对 app 透明。当网络的问题出现的时候, app 应该知道这是什么网路问题。换言之,就是对于 app 开发者们来说,要简化网络层出现的问题。比如,为什么某个 service 连不上了。

那么 Envoy 是个什么?

  • 它是一个软件,像 Nginx 一样,而不是一个 library
  • 它可以做网络中 L3/L4 层的 filter。所以它可以被用在很多网络协议中,比如 MongoDB, redis, gRPC,可以作为 TCP rate limiter
  • 它也可以做作 L7 的 filter,处理 HTTTP 请求。比如修改 header
  • Envoy 应该和每一个 app 放在一起,作为 app 处理网络问题的 proxy
  • 它也做 service discovery,通过主动和被动的 health checking
  • load balancing
  • 提供业界领先的 Observability
  • edge proxy,类似于反向代理这种 Nginx 实现的功能

实际应用中,Envoy 是以 sidecar 的模式运行的。它类似于服务器中的一个单独进程,单独软件,监控所有进出服务器的流量。

如果一台服务器要发送请求给另一台 service, envoy 作为中间代理而存在。envoy 知道请求最终应该发给哪台具体的服务器。如果请求要发到另一个 cluster,那么 envoy 会把请求发给另一个 clsuter 上的 envoy。

如今的 Lyft 架构

Web request 由 front Envoy 发送给其他 sub Envoy。各个 service 再用 microservices 架构,后端会共享各种工具,比如 MongoDB, DynamoDB, Redis 等

关于 service discovery

作者认为,目前业界的 service discovery 工具,比如 ZooKeeper 和 consul,在解决服务器上线又下线的问题上,他们都普遍使用了 strong consisitency 算法,比如 ZooKeeper 使用的就是 Raft。strong consisitency 所带来的一个问题是,伸缩性差了些。当服务器规模变大时,工具会变得不好用或者不稳定。他觉得 service discovery 是一个 eventually consistent 问题,其实不需要实现 strong consistent。他的分布式系统设计哲学是,如果一个 strong consistent 问题,可以通过变成 eventually consistent 来解决,那就用 eventually consistent。

所以,Envoy 和其他工具的一个很大区别是,它是按照 eventually consistent 设计和实现的。它做了一个假设是,服务器下线后总是会尽快恢复的。

举个例子来说,request 在发送给另一台服务器的过程中,服务器下线了。 envoy 并不能马上感知到这个情况,还是把请求发给了这台服务器。那肯定是不能收到回应的。 但这并不是问题,因为 envoy 实现了 eventually consistency,很快 envoy 就会发现这个问题后,会发送给在线的服务器。envoy 只需要确保有足够好的 retry 机制,确保这个发现问题的时间足够短就行了。

这里可以提一下 envoy 的 health checking 机制。它使用了主动和被动两种方式。主动是说, envoy 会间歇性询问服务器是否还在。被动是说,如果一台服务器连续返回 5xx,那么 envoy 就认为服务器挂了。

Envoy 其他功能

  • 各种类型的 service discovery: API, DNS
  • load balancing: 很多公司的服务器在不同的地区。envoy 会将请求发送到最近的地区,省时省钱
  • 记录 stats
  • circuit breaking:当服务器流量过大的时候, envoy 会断掉向这台服务器发请求,以保护服务器
  • rate limiting
  • Request shadowing:重现请求,并发送给测试服务器
  • 实现 Retry
  • deploy control: 因为 envoy 可以控制 request 的流向,这样它可以用于实现 blue/green deploy(一种滚动部署机制),或者 canary deploy(灰度部署)
  • 提供 Observability。既然所有请求都通过 Envoy,那么 Envoy 可以提供一个完整的 log。log 可以发送给统计服务,比如流行的 ELK 工具,供工程师 debug 用。下图是一个Envoy记录的全局 stats。

  • 完整跟踪一个请求。能看到一个请求是怎么在各个 service 之间流动的,各自所花的时间。

最后看一眼使用 Envoy 的公司:

微信公众号:网站架构札记

最近发布