Envoy 架构及其在 易轻舟的落地实践

代理,本质属性就是做两件事:第一,代替客户端向服务端发送请求,第二,代理服务端向客户端提供服务。前者隐藏客户端,后者隐藏服务端。在开端代理软件领域,比较著名有 HA Proxy 以及 Nginx,而 Envoy 则是该领域的的一个后起之秀。作为为云原生而设计的高性能 络代理,它具备以下的优点:

  • 高性能:Envoy 具备非常优越的性能。尽管 Envoy 在设计之初没有将性能作为最终的目标,而是更加强调模块化、易测试、易开发等特性,可它仍旧拥有足可媲美 Nginx 等经典代理软件的超高性能。

  • 可观察:相比于 Nginx 等传统代理,Envoy 具备更好的可观察性,包括灵活可定制的日志,丰富的指标监控,原生的多种分布式跟踪协议支持等等,在后文中会做更详细的介绍。

  • 区活跃:Envoy 的 区完全开放,不存在对应的商业版本,所以不用担心部分高级功能会被锁死在商业版当中。而且 Envoy 区非常活跃,在 Envoy 使用过程中的问题或者新的功能需求向 区提出后都可以得到很快的反馈。

  • 动态配置:xDS 协议的提出使得 Envoy 几乎所有的配置都可以动态的下发、加载和生效,而无需重载进程。并且 xDS 协议已经成为了构建通用数据面接口协议(UDPA)的基础。

  • 易扩展:作为一款云原生 络代理软件,可扩展性自然也是必不可少。Envoy 提供了 L4/L7 Filter 机制,可以让开发者在不侵入 Envoy 主干的前提下在各个层级对 Envoy 进行扩展和增强。

  • 多协议:最后 Envoy 支持代理多种协议数据,包括 HTTP,Kafka,Dubbo 等等。此类多协议治理能力其实也是构建在 Envoy 强大可扩展性上的。因为 Envoy 所有的协议解析和治理都是使用 Filter 来实现的。基本上每一种协议代理能力都对应一个 L4 Filter。

Envoy 具备很多优点,但它核心的概念却很少,只有四个。基本上,Envoy 中绝大部分的模块和功能都是围绕着这四个概念展开的:

  • Listener(监听器):监听器负责监听数据端口,接受下游的连接和请求。作为代理软件,无论是正向代理还是反向代理,肯定要接受来自下游的连接并进行数据处理。Envoy 把相关的功能都抽象在了名为监听器的资源当中。

  • Cluster(集群):集群是对真实后端服务的抽象和封装,管理后端服务连接池、负责后端服务健康检查、实现服务级熔断等等。

  • Filter(过滤器):过滤器主要负责将 Listener 接收的客户端二进制数据包解析为结构化的协议数据,比如 HTTP 二进制流解析为具体的 Header、Body、Trailer、Metadata 诸如此类并进行各种流量治理。Envoy 中 Filter 分为多种类型,覆盖不同的层级和场景,是 Envoy 强大功能的源泉。

  • Route(路由):路由一般是作为某个协议解析 Filter 的一部分存在。筛选器解析出结构化数据后会根据路由中具体规则选择一个 Cluster,最终发数据转发给后端服务。

    注:为了避免歧义,后文中 Envoy 中 Cluster 仍旧使用英文,而不是使用中文翻译“集群”。

目前 Envoy 支持 gRPC 服务、Restful 接口以及磁盘文件三种不同类型的 xDS 数据源。以最经典的gRPC 为例,Envoy 会定义了一个流式的 gPRC Service,xDS 服务提供方只需要实现对应的 gRPC Service。然后在需要配置更新时,向 gRPC 流推送配置数据即可。Envoy 侧会接受配置数据,然后加载更新。

Restful xDS 就是由 Envoy 开放一个 Post 接口由配置的提供方去调用;磁盘文件 xDS 则是由 Envoy 去 Watch 指定文件的变化并在文件更新时更新配置。这两种 xDS 配置方法在实践当中都很少使用。

本质上 xDS 协议并不复杂,真正困难的在于如何把各种资源抽象出来并通过一种通用的协议来封装和传输、如何管理数据的版本以及保证更新过程流量的平稳。这些都涉及到一些实现的细节,就不再赘述了。

下图是一个相对实际的例子。当使用 Isito Pilot 作为 xDS Server 时,如何利用 xDS 来动态更新 Envoy 配置。一般情况下,是用户修改了 K8s 集群中的一些 CRD 资源亦或者注册中心有配置更新才会触发配置更新;之后 Pilot watch 到相关变化变更将相关变化抽象成各种 Envoy 中对应的资源,如 Listener、Cluster,然后通过各个 xDS 将对应资源推送到 Envoy。


Envoy 可扩展性方面还有最后一个问题:功能更新和升级带来的运维成本。Envoy 是使用 C++ 来实现的。每实现一个新的功能性的 Filter,无论是复杂的 L4 Network Filter,还是相对简单的 L7 HTTP Filter,都需要重新构建整个 Envoy。相比于配置的动态化,Envoy 功能上似乎没那么动态化。

为了解决这个问题,Envoy 区提出了基于 WASM 的 Filter 扩展机制。WASM 是一种前端的技术,最初设计是用于加速 JS 脚本以及将 C++ 等语言带到 WEB 上。Envoy 内置了 WASM 虚拟机,开发者可以将自己的功能扩展使用如 C++、Go 、AS 等各种语言开发,然后编译成 WASM 字节码文件。之后,Envoy 动态的加载文件就可以实现功能的增强。

此外,Envoy 区也提供了 Lua Filter,可以让 Envoy 通过动态的下发一个 Lua 脚本来实现功能扩展。举例来说,用户可以使用 Lua 来编写一段 Lua 逻辑,只要实现 envoy_on_request 和 envoy_on_response 两个函数,然后将 Lua 脚本通过 xDS 动态的下发给 Envoy,Envoy 在处理请求的过程中,就会执行对应的 Lua 脚本代码。

目前 WASM 还没有完全落地,但是 Gloo、Istio 区都在力推,前景美好。而 Lua 相对来说,比较成熟,但是 区提供的功能较弱一些。所以轻舟团队也做了一些优化工作,后文当中也会讲到。

2.3 Envoy 可观察性

接下来需要介绍的 Envoy 关键特性是可观察性。可观察性其实是一个很大的主题,完全可以做一个单独的文章分享。但是这里就是主要介绍一下可观察性的概念以及 Envoy 的一些优势。希望有机会在其他文章中在对 Envoy 可观察性做更详细的介绍。

可观察性是指在软件程序运行过程中,获取软件程序内部状态或者发生的一个能力。如果程序执行起来之后,开发者和运维人员就对内部状态一无所知,那很多问题就根本无法定位。

按照侧重面的不同,Envoy 的可观察性主要依靠三个部分构成。分别是日志、指标、以及分布式追踪。

  • 日志:日志是对 Envoy 内部事件(或者直白的说,就是一个请求处理过程)的详细记录。Envoy 提供了非常丰富的日志字段,而且可以灵活的配置。同时还提供了类似 L7 Filter 一样的 Access Log Filter 来自定义日志过滤和筛选、二次修改之类的能力。

  • 指标监控数据是对 Envoy 内部事件的数值化统计,本质上,指标数据就是一个个计数器。记录诸如请求次数、正确请求次数、错误请求次数之类的统计数据。指标监控数据要结合 Prometheus 之类的时间数据库来使用,用于观察 Envoy 的整体流量趋势。

    Envoy 提供了非常丰富的指标数据。包括 xDS 指标监控, Cluster 维度的请求统计、连接统计,Listener 维度请求统计、连接统计。而且对于连接上发生的一些事件也会进行记录。比如连接断开了,根据断开的原因不同,会提供不同的计数,这样就非常方便开发者去定位问题。

  • 指标监控和日志描述的都是单个实例内部的状态。但是在微服务架构中,往往不同的服务实例内事件是有关联的。比如服务 A  调用服务 B ,服务 B 又调用了服务 C 和 服务 D。在服务 A B C D 中的 4 个事件是具有因果关系的。分布式跟踪就是为了记录这种因果关系,进行全链路的监控。

    分布式跟踪一般都要对接分布式跟踪后端。服务将自己内部事件的一些数据上 给分布式跟踪后端,后端做数据聚合和分析,构造出服务拓扑和链路关系。分布式跟踪是快速发现微服务集群中问题点和性能瓶颈的利器。Envoy 本身原生提供了对 ZipKin、OpenTracing 等多种分布式跟踪系统。目前轻舟团队也在和 区合作,一起开发 Envoy 对 SkyWalking 的支持。

xDS 协议、可扩展性、可观察性,这是我个人认为的在 Envoy 之中,最为核心的三个特性。它们横跨多个模块,基本上,可以说,这三者就是使得 Envoy 如此独特的基石。

3 Envoy 落地实践

最后分享从 Envoy 数据面的视角看 Envoy 如何在 易轻舟落地。通过这一部分的介绍,大家可以更好地理解 Envoy 的各个特性是如何在实践之中发挥效用的。

最简单的用法是把 Envoy 当作一个纯粹的七层 络代理,没有任何其他的依赖,只有单独的一个 Envoy,就像使用单体的 Nginx 一样。可以使用静态配置,或者基于磁盘文件作为数据源的 xDS 协议。

对于广大的个人开发者以及个人 站维护者而言,如果需要一个七层代理,不妨尝试一下 Envoy,立刻就能拥有一个高性能的 络代理,而且具备丰富的观察手段。同时对于希望深入学习 Envoy 的开发者来说,这种方法也是上手 Envoy 最快的方式。

此外,也可以将 Envoy 应用于 API 关之中。使用 Envoy 作为核心数据面,结合控制台、日志分析系统、指标监控 警系统、APM 链路跟踪系统、外部注册中心等等来构建一个功能完善、可观察、易扩展的 API 关。也可以将 Envoy 作为 Service Mesh 服务 格中数据面,接管微服务集群东西向流量,构建全新的微服务架构。

注:有兴趣的同学也可以了解一下 Envoy Mobile 项目,那是另一个更加有趣的场景。

接下来要着重介绍的,就是Envoy 在 关和 格两种场景下的落地和实践。

3.1 整体架构

Envoy 在 易轻舟实践中的整体架构如下。当然,图中简化了很多细节,只留下了核心的一些模块。

性能

在性能方面,Envoy 本身就是保障,在都使用最简配置的情况下,它的性能与 Nginx 相差仿佛,比 HA Proxy 要稍差一些。根据实际测试结果,一个 8C8G 的轻舟 API 关,在容器 络下,可以达到 8w+ QPS,而物理 络下,可以达到 10w+ QPS。

并发量 Fails TPS MRT(ms)
50 0 66089.44 0.71
100 0 75219.25 1.27
300 0 81199.04 3.59
500 0 82626.56 5.92

在 Envoy API 关性能保障方面,有三个小的 Tips 分享一下:

  • 第一,Envoy 提供了一个 virtual host 的概念,对应着域名。每个 virtual host 下都会有一组对应域名下的路由。virtual host 的搜索复杂度是 O(1),而路由的搜索和匹配是线性的。所以一定要合理的规划域名和路由,使用 virtual host 来把路由表隔离开来。

  • 第二,Envoy 日志提供了 JSON Access log。使用 JSON log,可以方便后续的日志分析和解析,但是性能极差。Envoy 可以把日志输出到 gRPC 服务,没有验证过它在这种情况下的性能如何。但是JSON Access Log 写入磁盘文件时,由于会使用 ProtoBuf 自身提供的 JSON 序列化方法,会严重影响性能。

  • 第三,对于核心的治理功能扩展,使用原生的 C++ 实现,并且使用 PPROF 功能来定位性能瓶颈做优化。这里是最需要开发去下功夫打磨的地方。性能,大部分时候都是需要一点点挤压出来的。

可观察性

在可观察性方面,轻舟 API 关构建了完整的监控体系。由前文可知,Envoy 本身就提供了非常丰富的指标监控数据,以及灵活的日志系统,所以重点是如何把这些 Envoy 本身提供的能力利用起来的问题。

首先是指标监控,前面也提到过,轻舟使用的是 Prometheus 数据库。指标监控就是一个个计数器,而把这些计数器在时间轴上排列出来时,就可以形成线和图,用于观察整个 关的流量趋势。对于一些核心的数据,我们会对接到控制台。同时,也提供了 Grafana 来把 Prometheus 中的数据做可视化。此外,Prometheus 还负责提供根据指标数据监控告警的能力。比如说,一段时间内,4xx/5xx 的请求数暴涨,这个时候就立刻会把相关告警推送给对应的负责人。这些告警能力,也是通过控制台来对外暴露,让业务方或者客户配置。

其次是日志,Envoy JSON 日志存在性能问题,普通的文本日志解析起来又差一些。所以这里有一个取巧的办法,使用文字字符串拼接成 JSON 格式字符串。同时,使用日志提供的 Log Filter 对包含特殊字符串的字段做转义,这样就可以保证性能的同时,输出标准的 JSON 字符串了。

而分布式跟踪,Envoy 原生支持了 Zipkin、OpenTracing、LightStep 等多种分布式跟踪系统,可以直接对接。而我们自己开发了 SkyWalking 的 Tracing 支持,还在持续的优化之中,而且也准备贡献给 区。

下图是一个很简单直观的 Sidecar 工作原理图。当业务进程作为服务提供方时,会由 Envoy 作为反向代理,流量先到 Envoy 再到业务本身。当业务进程作为客户端希望调用其他服务时,Envoy Sidecar 会作为正向代理,流量也要经过 Envoy 流转。一系列的流量的治理功能就可以从 SDK 剥离到独立的 Sidecar 进程中。

而 L4 Filter 则允许开发者扩展新的基座,实现多协议治理能力的增强。而且新开发的 L4 Filter 之上,同样可以构建对应协议的 L7 Filter。

10 月 27 日,周礼赞(Tetrate 创始工程师,Envoy 维护者,Istio Networking/Security WG Lead)直播分享了《Envoy 调试流量的常用技巧》,点击查看本次直播文字回顾及问答整理。

加入云原生 区 Envoy SIG

扫描下面的二维码,申请加入云原生 区 Envoy SIG,与 区一起共同交流学习 Envoy。

Envoy 架构及其在 易轻舟的落地实践

文章知识点与官方知识档案匹配,可进一步学习相关知识Python入门技能树人工智能机器学习工具包Scikit-learn215586 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年10月3日
下一篇 2020年10月3日

相关推荐