背景
Envoy是一款由Lyft开源的7层代理和通信总线,我们都知道随着微服务的盛行,越来越多的项目中开始使用微服务的理念,当然我们也知道互联网中任何理念或者软件都不是绝对的银弹,随着微服务的流行,一个大项目中会有成千个微服务用于组合来完成项目中的功能,所以紧跟着而来的便是我们如何让这些微服务进行通信,如此多的微服务又该如何治理?
管理好服务间通信对于保证端到端的性能与可靠性来说无疑成为重中之重。在Service Mesh没有出现之前,微服务框架之间的通讯大多采用SDK方案,但该方式短板也非常明显,例如对业务有侵入性、无法做到SDK升级对业务透明等。基于以上原因便催生了我们的服务间通讯层。
Service Mesh起初知识一个网络代理,随后Google联合IBM、Lyft发起了Istio项目,从架构层面明确了数据平面、控制平面,并通过集中式的控制平面概念进一步强化了Service Mesh的价值,而今天要说的Envoy是Istio中的Sidecar官方标配,是一个面向服务架构的高性能网络代理,由C++语言实现,拥有强大的定制化能力,通过其提供的Filter机制基本可以对请求转发过程中超过50%的流程做定制化。
Envoy的核心特点是什么?
透明性
网络对应用程序来说应该是透明的。当网络和应用程序出现问题时,我们可以轻松的确定问题的根源,因此Envoy为实现这一点采用进程外的架构,即是一个独立的进程,所有的Envoy是一个透明的通信网格。
支持所有的TCP协议
HTTP/2 作为第一公民,Envoy支持HTTP/2 包括上游连接以及下游连接在内的双向通信。 而 nginx 仅仅支持HTTP/2 下游连接。
负载均衡
Envoy具有免费的负载功能,这一点相比较于nginx,nginx中只有付费的 nginx plus 服务器才能提供类同于 Envoy 的高级负载功能。
动态配置
通过“动态配置API”实现配置的动态调整,而无需重启 Envoy 服务的。
当然除了以上这些Envoy还有很多特性,如服务发现,健康检查,统计与监控等。
专业术语入门
- Host/主机:能够进行网络通信的实体(如移动设备、服务器上的应用程序),主机是逻辑网络应用程序。一块物理硬件上可能运行有多个主机,只要它们是可以独立寻址的。
- Downstream/下游:下游主机连接到 Envoy,发送请求并接收响应。
- Upstream/上游:上游主机接收来自 Envoy 的连接和请求,并返回响应。
- Listener/监听器:监听器是命名网地址(例如,端口、unix domain socket等),可以被下游客户端连接。Envoy 暴露一个或者多个监听器给下游主机连接。
- Cluster/集群:集群是指 Envoy 连接到的逻辑上相同的一组上游主机。Envoy 通过服务发现来发现集群的成员。可以选择通过主动健康检查来确定集群成员的健康状态。Envoy 通过负载均衡策略决定将请求路由到哪个集群成员。
- Mesh/网格:一组主机,协调好以提供一致的网络拓扑。在本文档中,“Envoy mesh”是一组 Envoy 代理,它们构成了分布式系统的消息传递基础,这个分布式系统由很多不同服务和应用程序平台组成
- Runtime configuration/运行时配置:外置实时配置系统,和 Envoy 一起部署。可以更改配置设置,影响操作,而无需重启 Envoy 或更改主要配置。
Envoy如何进行代理
作为一个网络代理程序,它的核心职责便是完成请求的转发,在转发的过程中做一些请求的处理,我们都知道,在软件中我们往往定义数据结构来读取,进而判断应该执行什么功能,Envoy也不例外,在Envoy中有着自己的配置文件,在了解配置文件之前我们不妨简单的假设一下做代理的一个流程,无非就是一个中间件的功能。通常我们的主机进行发送请求,然后到达我们的代理,代理做了一些处理之后,如果我们的后端是一个集群,这个代理便要通过负载均衡来找到一个可用的主机上的服务,进行发送我们的请求。接下来我们来简单看看它的配置文件:
监听listeners
服务(程序)监听者。Envoy 会暴露一个或者多个listener监听downstream的请求。在下面中可以看出监听127.0.0.1
地址和10000
端口
listeners:
- name: listener_0
address:
socket_address: { address: 127.0.0.1, port_value: 10000 }
过滤器 Filter
在 Envoy 中指的是一些“可插拔”和可组合的逻辑处理层。是 Envoy 核心逻辑处理单元。
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["example.com"]
routes:
- match: { prefix: "/" }
route: { cluster: some_service }
http_filters:
- name: envoy.router
路由
路由规则配置,即请求路由到后端那个集群(cluster)。
routes:
- match: { prefix: "/" }
route: { cluster: some_service }
集群
Envoy 通过服务发现定位集群成员并获取服务。具体请求到哪个集群成员是由负载均衡策略决定。通过健康检查服务来对集群成员服务状态进行检查。
clusters:
- name: service_google
connect_timeout: 0.25s
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_google
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: www.google.com
port_value: 443
关于Envoy的入门就先讲到这里,后续会Envoy进行深入了解。