webservice工作原理及实例,web service入门详解

首页 > 经验 > 作者:YD1662022-11-14 20:14:30

服务网格架构已经是一个老生常谈的问题,服务的进出口流量经过 iptables 等技术手段被劫持到 sidecar,经由 sidecar 观察、治理之后再被转发到实际目标服务或者实例。

webservice工作原理及实例,web service入门详解(1)

那么,在 sidecar 内部流量是如何处理并正确应用治理规则和转发的呢?

更具体一点,某个服务访问其他服务时,流量被劫持到到 sidecar 之后:

接下来,本文将以 envoy sidecar 实现为例一点点说明 sidecar 是如何解决以上两个问题的(服务入口流量劫持和处理相对简单,所以本文主要关注出口流量处理)。

01

只是代理

说一千,道一万,envoy sidecar 也只是最简单不过的代理而已,它所有能做的事情都不会超过代理的范畴。

回顾代理的通用工作机制:接受下游连接和请求,按需对请求解析,然后经过一系列的模块或过滤器处理之后,将请求转发给上游服务。

在 envoy sidecar 中,接受下游的连接和请求的模块被抽象为 listener,而上游服务则被抽象为 cluster,形成如下结构:

webservice工作原理及实例,web service入门详解(2)

当然,envoy 支持多 listener 机制,即同时监听复数个地址,并且可以通过 xDS 协议实现 listener 的动态更新。并且,envoy 允许 listener 并不实际绑定地址和端口,即不产生实际的地址监听。这两个特性对于 sidecar 来说很关键,不过并不复杂。

在对 sidecar 本身最简单的结构有了基本的了解之后,接下里就可以正式开始回答之前的问题了。

02

你去哪儿?

第一个问题,流量劫持之后,如何确认原始的目标地址并转发?

一般来说,sidecar 会创建两个特殊的 listener 并打开端口监听。一个作为服务入口流量劫持的入口(virtual inbound),一个作为服务出口流量劫持的入口(virtual outbound)。服务进出口流量被劫持后被分别发送 sidecar 这两个特殊 listener 处理。

以出口流量的 virtual outbound 为例。数据流量经过 iptables 劫持和重定向之后和 virtual outbound 建立连接。而 virtual outbound 则可以使用系统调用通过 SO_ORIGINAL_DST 获得该连接原始目标地址(IP 地址和端口)。该原始目标地址就可以用于辅助后续流量的转发。

当然,对于部分的应用层协议来说,其协议消息本身就可能会携带目标服务的相关信息。sidecar 也可以在对流量内容解析之后,根据其中的信息识别目标服务并转发。

举个例子,HTTP 协议。当客户端使用域名访问目标服务时,该域名就会直接被添加到请求的 host 当中。

根据配置,sidecar 也可以使用请求消息中的 host 将 HTTP 请求转发给目标服务。根据应用层消息中服务标识选择目标服务转发也是一个关键特性,在后续内容中还会提到。

03

路在何方?

在服务网格中,sidecar 的职责当然不只是简单的流量转发了,更重要的是流量观察及流量治理。所以,获取到了流量原始目标 IP 和端口之后,直接转发出去显然不是网格想要的,必须进行更进一步的治理。

这就是第二个问题了,如何使治理规则生效,又有哪些治理规则需要对当前流量生效呢?

答案其实就在第1小节中。作为代理的 sidecar 本身就具备流量观察、流量治理、负载均衡等基础能力,流量自 listener 进入,经过过滤器处理,最终通过 cluster 转发给目标服务。

同时,envoy sidecar 又具备灵活的多 listener 机制,且允许 listener 不产生实际监听。

那么,sidecar 完全可以为每一个服务创建一个不会实际监听地址的内部 listener(简称为 fake listener),以服务 VIP(注意,是服务 VIP,一个服务可能有很多个实例,每个实例都有实例 IP,但是一个服务一般只有一个 VIP)为索引。而所有与该服务相关的治理规则,都以各种过滤器配置下发到该 fake listener 当中。不同 fake listener 可以使用不同过滤器配置。

webservice工作原理及实例,web service入门详解(3)

如上图所示,上层服务抽象中的服务以及治理规则最终被映射为 sidecar 中具体的 listener 和过滤器。

一般来说,在 K8S 的服务模型当中,客户端服务会使用目标服务域名访问目标服务。目标服务域名经 DNS 解析为目标服务 VIP。访问流量经 iptables 劫持,自 virtual outbound 进入 sidecar,在使用 SO_ORIGINAL_DST 获得流量原始目标地址(也即目标服务 VIP 地址和端口)之后,搜索该原始目标地址对应的 fake listener,然后把连接整个交给该 fake listener 处理,该 fake listener 会负责应用对应服务的治理规则(以过滤器实现)并将流量最终转发给目标服务(以 cluster 实现)。


04

公共的路

前文说过,sidecar 为每个服务都创建一个对应的 listener,以服务 VIP 为索引。可是如果存在大量的服务,那么就会创建大量的 listener,带来更大的资源开销。

另外,并不是所有服务模型中都有 VIP。比如在 Dubbo 的微服务模型中,就没有 VIP 的位置,所以就必须为每个实例创建一个 listener 保证流量被正确的治理和转发。且相同服务的所有实例对应的多个 listener 会应用相同的治理规则。

如此,显然会带来配置和资源的膨胀,给控制面和数据面都带来压力。

为了缓解该问题,envoy sidecar 提供了通配的 fake listener。通配 fake listener 使用 0.0.0.0:<port> (IPv4)为索引。

当以流量原始目标地址无法搜索到对应 fake listener 之后,就会根据流量原始目标端口搜索对应的通配 fake listener 来处理该流量。举例来说,如果一个请求(连接 or 流量)原始目标地址为 1.2.3.4:80,但是 sidecar 中不存在 1.2.3.4:80 fake listener 时,该请求就会被交由 0.0.0.0:80 通配 fake listener 处理。多个不同的 Dubbo 服务实例,也可以只创建一个对应的 fake listener。

但是,显然,通配 fake listener 会引入一些新问题。

首先,多个不同服务的流量最终会被同一个 fake listener 处理,为了保证服务治理规则能够正确、准确的生效,该通配 listener 内部必须要根据请求消息内服务标识(如 HTTP 中 host 请求头,如 Dubbo 请求中 interface)识别流量的目标服务并应用治理规则。

其次,通配 fake listener 可能会带来协议冲突问题。一般来说,同一地址(相同 IP,相同端口)只会使用一种协议(一般如此,当然也存在特殊情况,暂不讨论)。

可是,现在多个不同目标目标流量都可能聚集到同一 fake listener,必然存需要在同一 fake listener 处理多种不同协议流量的场景。比如说,目标地址 1.2.3.4:8080 提供 Dubbo 服务,目标地址 2.3.4.5:8080 提供 HTTP 服务,指向两者的流量最终都被 0.0.0.0:8080 处理。为了解决该问题,envoy sidecar 提供了协议嗅探机制,在同一 listener 中处理不同协议流量。


05

选择车道

如前文所述,请求流量和连接最终会交由 listener 处理,并以各种过滤器来实现各种治理规则,并且由于通配 fake listener,会大量出现需要在同一 listener 中处理不同协议流量的能力。

不同协议,可能有完全不同的消息格式和模型,显然需要不同的过滤器来进行处理。在 envoy sidecar 中就有相关的机制来支持该场景。

在 sidecar 的 listener 中,可以同时配置多组不同的过滤器,每组过滤器称为一个 filter chain。并且还提供了名为 listener filter 的特殊过滤器,可以对流量和连接进行预处理,并根据预处理的结果选择不同的 filter chain。

再次以 Dubbo 和 HTTP 协议为例。

当一个新的连接在 fake listener 中建立时,会首先经过 listener filter 预处理。它们会预读该连接上少量字节,如果其中包含 Dubbo Magic Number 和消息类型等字节,则为 Dubbo 协议;如果包含 HTTP 协议行,则为 HTTP 协议。最终 sidecar 会根据协议的不同选择不同的 filter chain 来处理,实现协议嗅探的效果。

webservice工作原理及实例,web service入门详解(4)

首页 1234下一页

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.