Envoy

发布时间:2024年01月14日

一、Envoy简介

Envoy 是一款由Lyft开源的高性能服务代理软件,使用现代C++语言(C++11及C++14)开发,提供四层和七层网络代理功能。2017年,Envoy 被捐赠给 CNCF 基金会,最终成为继Kubenetes利Prometheus 之后第3个 CNCF毕业项目。尽管在设计之初Envoy没有将性能作为最终的目标,而是更加强调模块化、易测试、易开发等特性,但是它仍旧拥有足可媲美 Nginx 等经典代理软件的超高性能。在保证性能的同时,Envoy也提供了强大的流量治理功能和可观察性。其独创的xDS 协议则

成为构建 Sevice Mesh?通用数据平面 API(UPDA)的基石。具体来说,Envoy 具有以下的优点。

  • 高性能:使用C++语言实现,基于 Libevent 事件机制及 I/O,保障性能。
  • 易扩展:利用其L3/L4/L7筛选器机制,Envoy 可以在各个层次进行功能 展。包括但不限额外代理协议支持、HTE 流量治理功能 展等。Envo及好的期送相现S+语育对各种操作的简化,使其开发过程非常友好。此外,Eavoy 也提供了基于WASM 的扩展支持,以及基于Lua脚本的简单功能扩展。
  • 多协议支持:原生支持代理HTTP、Kafka、Dubbo、Redis 等多种协议。
  • 动态化配置:基于xDS 协议实现配置的完全动态化,简化配置更新操作,实现监听端口、路由规则、后端服务发现等全运行时动态下发及更新。
  • 可观察性:内置日志、指标和分布式追踪3个模块,用于实现全方位、多维度的流量和事件观察。
  • HTTP筛选器:社区原生提供了大量的功能强大的HTTP筛选器,如限流、认证鉴权、缓存、压缩、gRPC协议转换等,开箱即用。
  • 社区开放活跃:Bnvoy完全开源,不存在对应的商业版本,保证了它的发展不会受限于商业化;而且 Envoy 社区非常活跃,不断向前推动Bnvoy 的演进和发展。

得益于以上的种种特性,Envoy可以说已经是云原生时代数据平面的事实标准。新兴的微服务网关,如Gloo、Ambassador 都基于 Bnvoy 进行扩展开发;而在服务网格中,Istio、Kong社区、Kuma、亚马逊AWS AppMesh 都使用 Envoy作为默认数据平面。接下来,本节将从系统架构、xDS协议、可观察性,以及应用场景4个方面介绍 Envoy 相关概念。

二、Envoy系统架构

在介绍更具体的内容之前,本小节先向读者介绍一些 Bnvoy 申常见的概念。在 Envoy 中,数据请求的人口方向被称为下游(Downstream),而数据请求的出口方向则被称为上游(Upstream)。Envoy接收来自下游的请求并将之转发给上游。Envoy 的系统架构如图所示。

ef39e2e9fe9b460594ac0ca4a2c91c15.png

在下游方向,Envoy 使用监听器(Listener)来监听数据端口,接收下游连接和请求;在上游方向,Envoy 使用集群(Cluster)来抽象上游服务,管理连接池,以及与之相关的使康检查等配置。而在监听器和集群之间,Envoy则使用筛选器(Filter)和路由(Router)将两者联系在一起。

相比于监听器、集群和路由等概念,筛选器可能需要稍微再多一点解释。筛选器是 Envoy 中可插拔的多种功能组件的统称,简单来说,筛选器就是插件。但是 Envoy 中L3/L4筛选器架构大大护展了它的功能界限,以至于筛选器的内涵要比常规理解的“插件”要丰富得多,所以本小节选择直译官方名称,称其为筛选器而非插件。Envoy包含了多种类型的筛选器。其中,L3/L4筛选器主要用于处理连接和协议解析,不同的L3/L4 筛选器可以使 Envoy代理不同协议的网络数据。举例来说,Envoy 中最为核心的 HTTP 代理功能就是构筑在一个名为 “ HTTP 连接管理器(HTTP?ComnecionManager)” 的L4 筛选器上的。而L7筛选器(在绝大多数情况下,L7筛选器都可以等同于 HTTE筛选器)则是作为L4 筛选器的子筛选器存在的,用于支撑实现更加丰富的流量治理功能。监昕器、集群、路由和筛选器构成了Envoy 最为核心的骨架。

三、Envoy线程模型

Envoy 采用多线程及基于 Libeveat 的事件触发机制来保证其超高的性能。在 Envoy 中,共存在3种不同的线程,分别是 Main 线程、Worker线程及文件刷新线程。Envoy 的线程模型如图所示。

c1ef5f5e70df4af0bd863912afbfffb6.png

Main 线程负责配置更新(对接 xDS 服务)、监控指标刷新和输出、对外提供 Admin 端口等工作。此外,Main 线程也负责整个进程的管理,如处理操作系统信号、Envoy热重启等。

Worker 线程是一个非阻塞的事件循环,每个 Worker 线程都会监听所有的 Listener,并处理相关链接和请求事件。需要注意的是,操作系统会保证一个事件最终只会被一个 Worker 线程处理。在绝

大多数情况下,Worker 线程都只在不断地处理下游的请求和上游的响应。在极少数情况下,Main线程会将配置更新以事件的形式添加到 Worker 线程的事件循环中。

文件刷新线程负责将 Envoy 需要持久化的数据写人磁盘。在 Envoy 中,所有打开的文件(主要是日志文件)都分别对应一个独立的文件刷新线程,用于周期性地把内存缓冲的数据写人磁盘文件中。而Worker 线程在写文件时,实际只是将数据写人内存缓冲区,最终由文件刷新线程落盘。如此可以避免 Worker线程被磁盘I/O所阻塞。

此外,为了尽可能地减少线程间因数据共享而引人的争用及锁操作,Envoy设计了一套非常巧妙的 Thread Local Store机制(简称 TLS),如果读者希望更进一步了解可以阅读 Envoy 社区提供的官方文档。这里不再深人介绍更多关于 Envoy线程模型的技术细节。

四、Envoy扩展功能

在对Envoy的整体框架及其事件模型有了一个初步的了解之后,本小节将再次着重介绍Envoy强大功飪的源泉:筛选器。正如前文所述,筛选器本质上就是插件,因此通过扩展开发筛选器,可以在不侵人Envoy 主干源码的前提下,实现对 Envoy 功能的扩展增强。而且L3/L4 筛选器架构大大拓宽了 Envoy 中 “扩展” 二字的可能性。在 Envoy 中大量的核心功能都是以可插拔的扩展构筑在其L3/14筛选器架构之上的。不过本小节并不打算过多地介绍 Envoy 中筛选器开发或实现的具体细节,而是从原理和结构层面解析不同层次筛选器的工作机制,使读者对Envoy筛选器及其扩展功能有一个粗略但完整的认知。Envoy 的扩展功能如图所示。

9441c429ae694469b9b285014aa7c414.png

当换作系统接收到来自下游的连接时,会随机选择一个Worker 线程来处理该有件。每个监听器缩选器(Listener Filter) 都用于处理该连接的状态。监听器筛选器会在一个新连接截操作系统接收之后且 Envoy 仍来完全创建对应的连接对系之前发挥作用。此比时,Listener 可以直接操作原始的套接字(Sooket),也可以中断插件链执行。直到所有的监听器筛选器执行完成,一个可操作的 Envoy 连接对象才会被建立,Envoy 开始按收来自下游的请求或数据。当该连接具体的消求或教据到来之时,每个 L4 (Network)筛选辉开始工作。监听累筛选器很少被用到,对绝大部分的开发人员来说,即使是需要深度定制开发Eavey,也极少会需要开发监听器缔选器。

L4 筛选器分为 Read 和 Write 两种不同类型,分别用于读取外部数据利向外部发送数据,它们可以直接操作连接上的二进制字节流。在大部分的实现当中,L4筛选器负责将连接中的二进制字节游解析为具有的协议语义的数据(奶HTTP Headers,Body等)并交由L7筛选器做进一步处理。Envoy使用全个 L4 筛选器分别解析不同协议来实现全协议代理功能。目前社区已经据供了与 HTTP、Dubbo、Mongo、Kafka、Thrift 等协议对应的全种 L4 筛选器,而且通过扩展L4筛选器,可以轻极她在不受人Envoy 主干的前提下,扩展支持新的协议。另外必须说明的是,协议解析并不是L4 筛选器的必备功能,同样存在一些非协议解析类型的L4筛选器,如工作在L4的限流、鉴权等筛选器。实际上,在L4 筛选器和L7 筛选器之间,应这有一个专门的编解码器。不过在常见的变现当中,给解码器都集成成到对应协议的L4 筛选器中,所以在本节提供的筛选器链路图中干脆也略去了对应的层次。在一般情况下,只有在需要扩展 Envoy 以支持视外的协议时,才需要扩展开发L4筛选器。

L7筛选器一般是对应协议的L4筛选器的子筛选器,如 HTTP筛选器就是L4筛选器“HTTP连接管理器”的子筛选器。L4 筛选器在完成二进制数据的解析之后,会依次调用各个L7筛选器来处理解析后的具有协议语义的结构化数据,用于实现各种流量治理功能,包括但不限于限流、熔断、IP黑/白名单、认证鉴权、绥存、降级等。实际上,路由组件也往往被实现为一个特的L7筛选器。当然,推个互联网是搭建在 HTTP上的,所以在 Envoy 中处处可见对HTTP的特化。在Envoy 中,L7筛选器几乎可以等同于 HTTP筛选器,因为如 Kafka、Redis 等其他协议的L4筛选器目前还没有提供良好的L7支持。L7筛选器是大部分开发人员最常用的,也是最需要关注的类型。通过扩展L7筛选器,可以扩展支持各种特定的流量控制功能,而且社区本身也提供了大量可靠、高性能的L7筛选器供用户直接使用。

在所有的L7筛选器都执行完成之后,路由组件将被调用,将请求通过连接池发送给后端服务,并异步等待后端响应。在收到后端服务响应之后,Envoy会倒序执行上述插件链,最终将响应传递给客户端。至此,一个完整的请求转发和响应流程便完成了。

文章来源:https://blog.csdn.net/summer_fish/article/details/135575765
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。