下面我们以静山平台为例,从需求出发,深入了解负载均衡和应用网关这两个关键技术。
假设我们的静山电商平台发展迅猛,很快每秒钟的 HTTPS API 请求数量就达到了五万,我们需要着手给静山平台设计高并发架构。
解决问题的第一步,认识问题——让我们先来评估一下五万 QPS 大概是一个什么规模的压力。
我们通过京东财报中的数据来评估一下京东工作日上午平峰期的并发量。
根据财报,京东在 2022 年的 GMV 达到了 33155 亿元。我们可以按照以下步骤进行估算:
通过以上计算,我们可以得出平峰期每秒交易额为 331550000 x 0.8 ÷ 365 ÷ 2 ÷ 12 ÷ 3600 = 8.4
万元。以京东的平均订单价值 650 元估计,平峰期每秒订单数约为 130 单。我们假设 QPS 是订单数的 200 倍,则京东在平峰期的 QPS 大约为 2.6 万。这个数字只有我们静山平台的一半。
既然五万 QPS 是一个很大的数字,那我们该如何设计架构满足这个并发量呢?
目前,在一台拥有 2 vCore 的虚拟机上,Kong 网关在承受 2000 QPS 的压力时对应的 CPU 占用率大约是 20%。经过换算,我们可以得知:如果 Kong 的性能可以随着核心数的增加而线性提升的话,在保持最大 CPU 占用率为 40% 的情况下,我们需要:
(50000 / 2000) 2 (20% / 40%) = 25 核
所以,我们至少需要在一台拥有 25 核 CPU 的云服务上安装 Kong 网关,才能应对五万 QPS。实际上这个规模已经超过单机 Kong 的极限了,我们稍后会做详细讨论。现在,让我们先来详细了解一下这个 Kong 网关究竟是什么。
在第三章中,我们已经了解到将单台物理服务器拆分成多个虚拟机可以提高系统整体容量。然而,仅仅依靠虚拟机技术无法单独提升系统容量,因为分布式计算架构需要一个流量分发器。通常情况下,我们不会奢侈地为每台后端虚拟机分配一个公网 IP 并使用 DNS 进行流量分发。因此,域名必须解析到某个公网 IP,而该 IP 指向的机器需要承担流量分发器的角色。
为了实现这一目标,笔者选择了 Kong gateway 软件作为反向代理服务器。Kong 能够处理海量 HTTPS 请求,并以 HTTP 协议将其发送到后端的多台应用虚拟机上。
Kong 是基于 OpenResty 技术开发的开源网关。OpenResty 是由国人章亦春创建的开源软件项目,它将非常轻量的 Lua 语言嵌入了 Nginx 对 HTTP 请求处理的整个生命周期。这使得原本只能静态配置的 Nginx 拥有了一种类似于 Perl 和 PHP 的动态脚本语言,从而极大地扩展了 Nginx 的能力。除了具备 HTTP 网关的一整套功能外,Kong 还拥有插件系统和基于数据库的水平扩展能力,理论上可以支持超高并发的系统。
在我们为静山平台引入 Kong 网关以后,其平台架构如图 5-2 所示。
在一个包含 Kong 网关的架构中,上游服务器(Upstream)是指执行后端代码的实际机器,也称为应用虚拟机。在接下来的讨论中,我们将频繁使用“上游服务器”这个术语。
在流量低谷期,笔者使用一台虚拟机运行 Apache 作为上游服务器。如果在开团前需要再启动一台上游服务器,Kong 如何知道新服务器已经启动并获取其 IP 地址呢?这就需要使用服务发现技术。
类似于 Kong,HashiCorp 开源的 Consul 也可以独立于 Kubernetes 环境运行,因此笔者选择使用它来进行服务发现。
服务发现的原理其实非常简单:构建一个共识集群,各个节点之间使用固定的端口进行通信。当新的上游服务器开机后,其上的 Consul 服务会开机启动,并与预先配置好的主节点 IP 进行通信,加入集群并广播自己的 ip。此时,集群内的所有机器都知道有一台新的机器加入集群了。
加入集群后,Consul 会基于本地的配置文件,向整个集群广播自己本机可以提供的服务名称,假设静山平台后端服务的名称为“up”,其对应的默认域名就是 up.service.consul
。此时,集群内的所有节点都可以通过 Consul 的 DNS 服务,通过查询 up.service.consul 域名,获得声明自己可以提供“up”服务的所有机器的 IP 地址。安装 Kong 网关的虚拟机同样位于集群内,所以它也可以使用这个方法获取到新加入集群的服务器的 IP 地址。
当 Kong 接收到来自客户端的 HTTPS 请求后,需要将请求转换为向 Upstream 发起的 HTTP 请求。此时,Kong 会向本机上安装的 Consul DNS 服务发送查询,以查找 up.service.consul
这个域名对应的 IP 地址。在此之前,该域名只会返回一个 IP 地址,即唯一的上游服务器的 IP 地址。然而,在新机器启动并成功加入集群后,该域名的解析结果将变为两个 IP 地址,Kong 可以将 HTTP 请求均匀地发送给新旧两台上游服务器,从而将系统总容量提升一倍。此时静山平台架构如图 5-3 所示。
应用网关,也被称为 API 网关,顾名思义,它是所有 API 请求的入口:它接收所有的 HTTP/HTTPS/TCP 请求,并将请求转发给真正的上游服务器。这些上游服务器可以是一堆虚拟机、容器,甚至是多个数据中心各自的应用网关。由于应用网关所承担的任务相对较少,因此它能够使用单台服务器支持很高的并发量。
常见的应用网关软件包括 HAProxy、Nginx、Envoy 等,而 Cisco、Juniper、F5 等一体化设备厂商也提供相关的硬件产品。
除了提升系统容量外,应用网关还具有许多其他优势。
经过对应用网关三年多的使用之后,笔者现在认为所有系统都应该放在应用网关的背后,包括开发环境。应用网关对后端架构的解放作用实在是太大了,可以让你在后端玩出花来:各种语言、各种技术、各种部署形式、甚至全国各地的机房都可以成为某条 URL 的最终真实服务方,让你的后端架构彻底起飞。
终端用户访问应用网关时采用的是 HTTPS 协议,这个协议需要对数据进行加密解密,应用网关非常适合完成这个任务,而背后的业务系统只需提供标准 HTTP 协议即可,从而降低了业务系统的部署复杂度和资源消耗。
应用网关可以对后端异构系统进行统一的身份验证,无需单独实现。同时也可以统一防火墙白名单,后端系统防火墙只需对网关 IP 开放,极大地提升了后端系统的安全性,降低了海量服务器安全管理的难度。甚至可以针对某条 API 进行单独鉴权,使系统的安全管控能力大幅提升。
由于所有流量都会经过网关,因此对指标进行收集变得简单了。你甚至可以将双向流量的内容全部记录下来,用于数据统计和安全分析。
应用网关还可以统一对流量进行 gzip 压缩,可以将所有业务一次性升级到 HTTP/2 和 HTTP/3,可以对数据进行格式转换(XML 到 JSON)和修改(增加/修改/删除字段),总之就是能够灵活应对各种需求,随心所欲地操控输入和输出的数据。
📙 高并发的哲学原理 《Philosophical Principles of High Concurrency》
Copyright © 2023 吕文翰