vlambda博客
学习文章列表

之家云API网关的前世今生

总篇126篇 2022年第1篇

前言

从用户层API网关是服务的统一入口,是各种协议的中转站,是对上游服务的保护,是对API全生命周期的管理,是对东西流量和南北流量的集中治理。从集群层API网关属与分布式集群可横向扩展来处理高并发的请求,从服务层API属于源站的保护伞,路由器,防火墙,对访问服务的流量进行分发,治理和转换。


01

历程


何从0到1,如何从1到100的构建API网关,下面讲述下整体的历程。

第一阶段需求/痛点:
1.多个服务端无法提供统一的服务,客户端需逐一加在;
2.无法提供统一API的认证功能,服务提供者各自为战,功能参差不齐;
3.对API无任何统一的管理,上线/下线/治理等功能无从谈起。
第二阶段调研/选型:
之家云API网关的前世今生

从开源协议和部署方式综合考虑选型为KONG,之家云网关在2019年6月上线,当时APISIX还未开源(2019 年 10 月份在Apache 开源),不与做对比。

第三阶段平台定位: API的定义,注册,管控,注销的全生命周期管理平台。
第四阶段1.0版本 API的即插即用,业务接入。
第五阶段2.0版本 API的管控,承接公司818全球车展活动。

02

架构


平台架构

之家云API网关的前世今生

通过组集合API,可以管理对应的环境和域名的访问模式,API是核心所在可以注册,发布,授权,销毁全阶段管理API,API 使用期间可以监控,告警,编辑,日志,记录,调试等操作,策略管理集成插件的功能主要有:

     1)MOCK:不请求源站,从网关层返回http状态码,http 头,http数据。

     2)跨域:描述:可在网关开发跨域功能,解决前端到服务端的同源策略字段:

  • 允许的域:Access-Control-Allow-Origin的值(多个以逗号分隔),值可以是字符串或者PCRE的正则表达式。 如果希望允许所有源, 请将 * 作为单个值添加到此配置字段中。
  • 请求方法Access-Control-Allow-Methods的值(以逗号分隔的字符串)。GET, HEAD, PUT, PATCH, POST中的一个或者多个。
  • 请求头: Access-Control-Request-Headers 的值(以逗号分隔的字符串)。 例如: Origin, Authorization。
  • 响应头: Access-Control-Expose-H eaders的值(以逗号分隔的字符串)。
  • 缓存时间: 设置preflight request结果缓存的时间,须为大于零的整数。
  • 应凭据: 控制Access-Control-Allow-Credentials头,是否以true作为此header的值。
  • 预检请求: 是否将OPTIONS代理信息发送给后端源服务器。
     3)限流: 限制单位时间内此IP访问次数,超过的访问返回限流信息(http code 429)
     4)缓存: 为本地缓存,自己设置缓存时间和缓存类型访问为HIT视为命中。
     5)黑白名单:设置ip黑白名单,限制访问用户返回(http code 403)
     6)并发:用户1秒内访问超过设置的并发数值后返回托底数据和504状态码或跳转到服务内部的URL。

     系统架构
之家云API网关的前世今生
整体的访问消耗平均在1到5毫秒之间,插件开的过多会影响访问的性能,每个插件的功能不同影响的时间不定,最多不超过5毫秒,网关的访问消耗几乎可以忽略不计。单台48核,128G的实体机25000QPS完全没有问题。

03

核心技术

Routes(路径)
路由实体定义规则以匹配客户端的请求。每个 Route 与一个 Service 相关联,一个服务可能有多个与之关联的路由。与给定路由匹配的每个请求都将代理到其关联的 Service 上。可以配置的字段有:hosts,paths,methods,Service 和 Route 的组合(以及它们之间的关注点分离)提供了一种强大的路由机制,通过它可以在 Kong 中定义细粒度的入口点,从而使基础架构路由到不同上游服务。

Services(服务)
服务实体是每个上游服务的抽象。服务的示例是数据转换微服务,计费API等。服务的主要属性是它的 URL(其中,Kong 应该代理流量),其可以被设置为单个串或通过指定其 protocol, host,port 和path。服务与路由相关联(服务可以有许多与之关联的路由)。路由是 Kong 的入口点,并定义匹配客户端请求的规则。一旦匹配路由,Kong 就会将请求代理到其关联的服务。

Plugins(插件)
插件实体表示将在 HTTP请求/响应生命周期 期间执行的插件配置。它是为在 Kong 后面运行的服务添加功能的,例如身份验证或速率限制。将插件配置添加到服务时,客户端向该服务发出的每个请求都将运行所述插件。如果某个特定消费者需要将插件调整为不同的值,你可以通过创建一个单独的插件实例,通过 service 和 consumer 字段指定服务和消费者。

Authentication(认证)
网关的认证方式配合Consumer和ACL 使用,主要有BasicAuth,HMAC,OAuth2等方式。

1)BasicAuth:使用用户名和密码,为你的apis接口集增加基本认证。该插件通过header头中的Authorization信息,校验用户有效认证信息。首先,将用户名密码已 username:password 的格式进行base64加密,例如:用户名为devtest密码为devtest,则加密后的字符串为 base64(devtest:devtest) = ZGV2dGVzdDpkZXZ0ZXN0然后,将加密后的账号信息加到HTTP请求头中进行访问,Header头信息为Authorization: Basic ZGV2dGVzdDpkZXZ0ZXN0

2)HMAC:hmac是Hashing for Message Authentication的简写,可以用来保证数据的完整,客户端把内容通过散列/哈希算法算出一个摘要,并把算法和内容以及摘要传送给服务端,服务端按照这个算法也算一遍,和摘要比一下如果一样就认为内容是完整的,如果不一样就认为内容被篡改了。首先,拿到自己的hmac公钥私钥,然后,通过指定算法计算生成签名最后,将签名及当前时间(GMT格式)分别加入到请求头中,发起请求及签名算法,如下面所示 X-Date: Thu, 06 Dec 2018 11:51:06 GMT Authorization:hmac username="test",algorithm="hmac-sha256",headers="X-Date",signature="bwksn8/MV6UMhwWv9vD546sUQVxphopgOqoPHVLWBm4="。


代码片段:
public class Main { public static void main(String[] arg) throws Exception { String url = "http://dev.test.com"; String username = "dev_test"; String secret = "dev_test"; String auth = "hmac username=\"{1}\", algorithm=\"hmac-sha256\", headers=\"X-Date\", signature=\"{2}\""; // 获取当前GMT时间(X-Date) DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); String now = dateFormat.format(Calendar.getInstance().getTime()); System.out.println(now); // 计算签名字符串 String hash_string="X-Date: " + now; String signature = Base64.getEncoder().encodeToString(sha256_HMAC(hash_string,secret)); System.out.println(signature); //组装请求头信息 auth = auth.replace("{1}",username).replace("{2}",signature); Map<String,String> headers = new HashMap<>(); headers.put("X-Date",now); headers.put("Authorization",auth); // or headers.put("Proxy-Authorization",auth); String ret = sendGet(url,"",headers); //http的GET方式请求 System.out.println(ret); } /** * sha256_HMAC加密 * @param message 消息 * @param secret 秘钥 * @return 加密后字符串 */ private static byte[] sha256_HMAC(String message, String secret) { try { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256"); sha256_HMAC.init(secret_key); return sha256_HMAC.doFinal(message.getBytes()); } catch (Exception e) { System.out.println("Error HmacSHA256 ===========" + e.getMessage()); } return new byte[0]; }
3)OAuth2: 规定了四种获得令牌的流程。你可以选择最适合自己的那一种,向第三方应用颁发令牌。下面就是这四种授权方式:
  • 授权码(authorization-code)
  • 隐藏式(implicit)
  • 密码式(password)
  • 客户端凭证(client credentials)
注意,不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。

Consumer(消费者)
Consumer 对象表示服务的使用者或者用户。你可以依靠 Kong 作为主数据库存储,也可以将使用者列表与数据库映射,以保持Kong 与现有的主数据存储之间的一致性。

Certificate(证书)
网关的https证书,一个证书对象代表一个公共证书,可以选择与相应的私钥配对。Kong 使用这些对象来处理加密请求的 SSL/TLS 终止,或在验证客户端/服务的对等证书时用作受信任的 CA 存储。证书可选择与 SNI 对象相关联,以将证书/密钥对绑定到一个或多个主机名。证书既可以被标记,也可以被标记过滤。

Upstream(上游)
Upstream 对象表示虚拟主机名,可用于通过多个服务(目标)对传入请求进行负载均衡。例如:service.v1.xyz 为 Service 对象命名的上游 Host 是 service.v1.xyz 对此服务的请求将代理到上游定义的目标。

Targets(目标)
目标 IP地址/主机名,其端口表示后端服务的实例。每个上游都可以有多个 Target,并且可以动态添加 Target。由于上游维护 Target 的更改历史记录,因此无法删除或者修改 Target。要禁用目标,请发布一个新的 Targer weight=0,或者使用 DELETE 来完成相同的操作。

Tags(标签)
标签是与 Kong 中的实体相关联的字符串。标签几乎可以包含所有 UTF-8 字符,不允许使用不可打印的 ASCII(例如,空格字符)。大多数核心实体可以在创建或编辑时通过它们的属性进行标记tags。

04

818实战


背景:之家云需承接公司活动期间百万以上的QPS。

挑战:大并发的情况,如何保证服务的高可用,面对突增流量如何处理,面对恶意流量如何清洗,等等问题。

数据:活动期间大约10W的 QPS,压测需要达到100W。

网关支持:

1.根据单台20000QPS的指标横行扩容机器,如果机器从足的情况建议多加;

2.增加备份节点,随时加入集群处理突发情况和流量转移;

3.访问API接口尽量配置限速功能,避免源站被打崩;

4.数据更新要求实时性不高的增加缓存;

5.24小时备战随时处理问题(为了公司拼了)。

压测:

1.共持续了十轮,包括内网和外网压测,对与网关来说是不通集群(建议内网和外网分开搭建物理隔离);

2.实测最高QPS近100万,在用户访问不高的时候开发压测;

3.遇到的问题:

  • BODY过大导致数据落盘影响访问数据(解决:增大运行BODY 大小,调整到合理数据,不易过大);
  • 日志采集延迟(解决:分集群采集,集中资源处理流量大的接口);
  • 突发流量(解决:随时增加备份机器,开启限流,流量分发,缓存等网关功能);

活动: 近3个小时的活动期间,实测最高QPS近11万,网关层在压测近100万的QPS对与这11万QPS无任何压力,完美的支持了公司活动。

05

后续


网关的趋势逐步向服务网关方向发展,目前比较火的像ISTIO, kong也开源了自己的kong mesh.网关对接微服务的需求已经越来越强烈,目前之家云网关通过自研已支持服务发现功能,任重道远继续努力。

作者简介


杨宏岩

任职于云平台部、云开发团队、云开发工程师


之家云API网关的前世今生


阅读更多




▼ 关注「之家技术」,获取更多技术干货