学习笔记-架构的演进之微服务网关-2月day20

前言

网关(Gateway)主要是用来表示位于内部区域边缘,与外界进行交互的某个物理或逻辑设备。

在单体架构下,我们一般不太强调“网关”这个概念,因为给各个单体系统的副本分发流量的负载均衡器,实质上就承担着内部服务与外部调用之间的网关角色。不过在微服务环境中,网关的存在感就极大地增强了,甚至成为微服务集群中必不可少的设施之一。

微服务中网关的首要职责,就是以统一的地址对外提供服务,将外部访问这个地址的流量,根据适当的规则路由到内部集群中正确的服务节点之上。也正是因为这样,微服务中的网关,也常被称为“服务网关”或者“API 网关”。
微服务的网关首先应该是个路由器,在满足此前提的基础上,网关还可以根据需要作为流量过滤器来使用,以提供某些额外的可选的功能。比如安全、认证、授权、限流、监控、缓存,等等。

网关 = 路由器(基础职能) + 过滤器(可选职能)

网络层次与协议

仅从技术实现的角度来看,对于路由流量这项工作,负载均衡器与服务网关的实现是没有什么差别的,很多服务网关本身就是基于老牌的负载均衡器来实现的,比如 Nginx、HAProxy 对应的 Ingress Controller,等等;而从路由目的这个角度来看,负载均衡器与服务网关的区别在于,前者是为了根据均衡算法对流量进行平均地路由,后者是为了根据流量中的某种特征进行正确地路由。

也就是说,网关必须能够识别流量中的特征,这意味着网关能够支持的网络层次、通讯协议的数量,将会直接限制后端服务节点能够选择的服务通讯方式:

  1. 如果服务集群只提供如 Etcd 这类直接基于 TCP 访问的服务,那就可以只部署四层网关,以 TCP 报文中的源地址、目标地址为特征进行路由;
  2. 如果服务集群要提供 HTTP 服务的话,就必须部署一个七层网关,根据 HTTP 的 URL、Header 等信息为特征进行路由;
  3. 如果服务集群要提供更上层的 WebSocket、SOAP 等服务,那就必须要求网关同样能够支持这些上层协议,才能从中提取到特征。

一个提醒:现在围绕微服务的各种技术都处于快速发展期,其实并不提倡针对每一种框架,去记忆配置细节,也就是并不需要去纠结前面给出的这些配置的确切写法、每个指令的含义。因为如果你从根本上理解了网关的原理,那你参考一下技术手册,很容易就能够将前面给出的这些信息改写成 Kubernetes Ingress Controller、Istio VirtualServer 或者是其他服务网关所需的配置形式。)

性能与可用性

性能与可用性是网关的一大关注点。因为网关是所有服务对外的总出口,是流量必经之地,所以网关的路由性能是全局的、系统性的,如果某个服务经过网关路由会有 10 毫秒的性能损失,就意味着整个系统所有服务的性能都会降低 10 毫秒。

网关的性能与它的工作模式和自身实现都有关系,但毫无疑问,工作模式是最主要的。三角传输模式(DSR,即数据链路层负载均衡模式),原理上就决定了性能一定会比代理模式来的强(DSR、代理等都是负载均衡的基础知识)

今天 REST 和 JSON-RPC 等基于 HTTP 协议的接口形式,在对外部提供的服务中占绝对主流的地位,所以我们这里所讨论的服务网关默认都必须支持七层路由,这样通常就默认无法转发,只能采用代理模式。在这个前提约束下,网关的性能就主要取决于它们是如何代理网络请求的,也就是它们的网络 I/O 模型了。

网络 I/O 的基础知识

在套接字接口的抽象下,网络 I/O 的本质其实是 Socket 的读取,Socket 在操作系统接口中被抽象为了数据流,而网络 I/O 就可以理解为是对流的操作。

对于每一次网络访问,从远程主机返回的数据会先存放到操作系统内核的缓冲区中,然后再从内核的缓冲区,复制到应用程序的地址空间,所以当一次网络请求发生后,就会按顺序经历“等待数据从远程主机到达缓冲区”和“将数据从缓冲区拷贝到应用程序地址空间”两个阶段。
根据完成这两个阶段的不同方法,我们可以把网络 I/O 模型总结为两类、五种模型。两类是指同步 I/O 与异步 I/O;五种是指在同步 I/O 中又划分出了阻塞 I/O、非阻塞 I/O、多路复用 I/O 和信号驱动 I/O 四种细分模型。

同步就是指调用端发出请求之后,在得到结果之前必须一直等待,与之相对的就是异步,在发出调用请求之后将立即返回,不会马上得到处理结果,这个结果将通过状态变化和回调来通知给调用者。而阻塞和非阻塞 I/O 针对请求处理的过程,就是指在收到调用请求、返回结果之前,当前处理线程是否会被挂起。

  1. 异步 I/O(Asynchronous I/O)
    异步 I/O 中,数据到达缓冲区后,不需要由调用进程主动进行从缓冲区复制数据的操作,而是在复制完成后,由操作系统向线程发送信号,所以它一定是非阻塞的。
  2. 同步 I/O(Synchronous I/O)- 阻塞 I/O(Blocking I/O)
    阻塞 I/O 是最直观的 I/O 模型,逻辑清晰,也比较节省 CPU 资源,但缺点就是线程休眠所带来的上下文切换,这是一种需要切换到内核态的重负载操作,不应当频繁进行。
  3. 同步 I/O - 非阻塞 I/O(Non-Blocking I/O)
    非阻塞 I/O 能够避免线程休眠,对于一些很快就能返回结果的请求,非阻塞 I/O 可以节省上下文切换的消耗,但是对于较长时间才能返回的请求,非阻塞 I/O 反而白白浪费了 CPU 资源,所以目前并不常用。
  4. 同步 I/O - 多路复用 I/O(Multiplexing I/O)
    多路复用 I/O 本质上是阻塞 I/O 的一种,但是它的好处是可以在同一条阻塞线程上处理多个不同端口的监听。多路复用 I/O 是目前的高并发网络应用的主流,它下面还可以细分 select、epoll、kqueue 等不同实现。
  5. 同步 I/O - 信号驱动 I/O(Signal-Driven I/O)
    信号驱动 I/O 与异步 I/O 的区别是“从缓冲区获取数据”这个步骤的处理,前者收到的通知是可以开始进行复制操作了,在复制完成之前线程处于阻塞状态,所以它仍属于同步 I/O 操作。而后者收到的通知是复制操作已经完成。

网关的性能考量

服务网关处理一次请求代理时,包含了两组网络操作,分别是“作为服务端对外部请求的应答”和“作为客户端对内部服务的调用”。理论上这两组网络操作可以采用不同的网络 I/O 模型去完成,但一般来说并没有必要这样做。

网关的可用性考量

任何系统的网络调用过程中都至少会有一个单点存在,这是由用户只通过唯一的一个地址去访问系统决定的。即使xxx这样全球多数据中心部署的大型系统,给多数据中心翻译地址的权威 DNS 服务器,也可以认为是它的单点。作为后端对外服务代理人角色的网关,经常被看作是系统的入口,往往很容易成为网络访问中的单点。这时候,它的可用性就尤为重要。

  • 网关应尽可能轻量。尽管网关作为服务集群统一的出入口,可以很方便地做安全、认证、授权、限流、监控等功能,但在给网关附加这些能力时,要仔细权衡,取得功能性与可用性之间的平衡,不然过度增加网关的职责是很危险的。
  • 网关选型时,应该尽可能选择较成熟的产品实现。比如 Nginx Ingress Controller、KONG、Zuul 等等这些经受过长期考验的产品,我们不能一味只考虑性能,选择最新的产品,毕竟性能与可用性之间的平衡也需要做好权衡。
  • 在需要高可用的生产环境中,应当考虑在网关之前部署负载均衡器或者等价路由器(ECMP),让那些更成熟健壮的(往往是硬件物理设备)的设施去充当整个系统的入口地址,这样网关就可以很方便地设置多路扩展了。

BFF

“BFF”(Backends for Frontends)概念指出,网关不必为所有的前端提供无差别的服务,而是应该针对不同的前端,聚合不同的服务,提供不同的接口和网络访问协议支持。

比如,运行于浏览器的 Web 程序,由于浏览器一般只支持 HTTP 协议,服务网关就应该提供 REST 等基于 HTTP 协议的服务,但同时我们也可以针对运行于桌面系统的程序,部署另外一套网关,它能与 Web 网关有完全不同的技术选型,能提供基于更高性能协议(如 gRPC)的接口,来获得更好的体验。

在网关这种边缘节点上,针对同样的后端集群,裁剪、适配、聚合出适应不一样的前端服务,有助于后端的稳定,也有助于前端的赋能。
在这里插入图片描述

此文章为2月Day20学习笔记,内容来源于极客时间《周志明的软件架构课

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值