一文详细讲解API网关核心功能和API管理扩展

作者:人月神话,新浪博客同名

简介:多年SOA规划建设,私有云PaaS平台架构设计经验,长期从事一线项目实践

今天准备再详细讲解下API网关的基础概念,使用场景和核心功能,以及基于API网关核心引擎做的API全生命周期管理功能扩展等,最好再介绍下当前主流的开源API网关引擎。

API网关概述

在微服务架构体系里面,我们一般会使用到微服务网关或叫API网关。

大家都比较清楚,在微服务架构体系下本身是去中心化的架构,通过服务注册中心来实现服务注册发现和消费调用,那么为何又需要使用API网关?

在传统的ESB总线进行服务集成的时候我们就经常谈到一个概念就是位置透明,即需要屏蔽底层业务模块提供API接口服务地址信息,并实现多个微服务API接口的统一出口。即类似设计模式里面经常谈到的门面模式。

如何给API网关一个定义?

简单来说API网关就是将所有的微服务提供的API接口服务能力全部汇聚进来,统一接入进行管理,也正是通过统一拦截,就可以通过网关实现对API接口的安全,日志,限流熔断等共性需求。如果再简单说下,通过网关实现了几个关键能力。

内部的微服务对外部访问来说位置透明,外部应用只需和网关交互统一拦截接口服务,实现安全,日志,限流熔断等需求

从这里,我们就可以看到API网关和传统架构里面的ESB总线是类似的,这些关键能力本身也是ESB服务总线的能力,但是ESB服务总线由于要考虑遗留系统的接入,因此增加了:

大量适配器实现对遗留系统的遗留接口适配,多协议转换能力进行数据的复制映射,路由等能力

对于两者,我原来做过一个简单的对比,大家可以参考。

这个概念理解后,我们再回到微服务架构里面。

对于微服务架构大家经常说的最多的就是去中心化的架构,认为ESB中心化架构模式已经过时。而实际上经过上面分析你可以看到。在微服务架构里面的API网关仍然是中心化的架构模式,所有的API接口都要经过网关这个点。

非中心化架构-》走微服务里面的服务注册中心进行接口交互中心化架构-》走网关进行接口服务暴露和共享交互

对于微服务架构里面有无去中心化的架构?当然是有的,即我们常说的微服务模块之间可以通过服务注册中心来实现服务发现查找,服务间的点对点调用即使去中心化的。

如果一个单体拆分为微服务后,完全不需要和外部应用打交道,也不需要共享自己的接口能力,那么这个微服务体系里面就不需要用API网关,仅仅使用服务注册中心即可。通过服务注册中心实现完全的去中心化和接口调用更高的性能。

什么时候需要使用API网关?

如果一个微服务架构下,虽然不会外部的其它应用进行交互和集成,但是整个应用本身存在APP应用端,而APP应用端通过前后端分析开发,同时需要通过互联网访问。本身存在需要一个统一访问API访问入口,同时也需要考虑和内部微服务模块进一步进行安全隔离。

当我们谈到这里的时候,你会发现我们常说的API网关的服务代理或透传能力,实际和我们常说的Ngnix反向代理或路由是一个意思。

如果你仅仅是为了统一API接口的访问出口,并考虑类似DMZ区的安全隔离,那么在你架构前期完全不需要马上实施API网关,直接采用Ngnix进行服务路由代理即可。因为在这种架构下,API接口消费端,提供端全部是一个开发团队开发,各种问题分析排查都相当方便,类似API接口安全访问等也可以通过JWT,Auth2.0等统一实现,而且这个过程也并不复杂。

能力开放或多应用外部集成对API管控治理需要

但是当我们面临是和多个外部应用集成,或者说将自己的API接口服务能力开放给外部多个合作伙伴使用的时候,这个时候对于API接口的管控治理要求自然增加。

即在常规的服务代理路由基础上,需要增加类似负载均衡,安全,日志,限流熔断等各种能力,而且我们不希望这些能力在API接口开发的时候考虑,而是希望这些能力是在API接入到网关的时候统一灵活配置来实现管控。

那么这个时候使用API网关作用就体现出来。

API网关核心功能说明

对于API网关实际上前面已经多次强调,可以看做是ESB总线的轻量化实现,不再需要复杂的协议转换,适配和数据映射等能力,但是提升了流量控制和安全,实时监控等方面的能力。对于API网关引擎部分提供的核心功能,再简单总结如下:

1.实现统一服务代理和服务统一出口

这点是网关和常规点对点服务注册中心最大的一个区别点,就是位置透明,消费端只需要和网关打交道,具体网关如何和后台的微服务模块打交道,后台微服务模块的部署逻辑,模块提供服务的IP地址等都不用关心。

由于实现了位置透明,带来一点就是数据流必须通过网关,那么网关本身又成为了去中心的微服务架构中的中心化节点,那么就必须考虑网关节点的性能,可靠性和弹性扩展能力。

网关要实现位置透明,延伸出来对应的网关必须提供的能力就包括了

提供服务注册和服务接入的能力提供服务代理和服务路由能力,能够将服务路由到具体的原始服务上提供负载均衡能力(该点并不是必须具备)

在这里准备重点强调下负载均衡能力,实际上对于API网关往往并不是必须具备负载均衡能力。

其一是提供API接口服务的模块本身进行了负载均衡,再提供地址其二是类似容器化集成和部署,已经可以通过Kubernetes实现了负载均衡

我们可以看下对于注册和接入到API网关服务的三种场景,只有场景一需要由API网关来提供负载均衡能力。

注意API网关是否需要具备负载均衡能力,是必须考虑的一个点,即如果底层微服务模块提供的API接口服务本身能够提供负载均衡后的地址,那么网关不需要进行负载均衡。如果底层模块不具备这个能力,那么网关必须具备负载均衡能力。

微服务模块本身可以基于容器化资源池提供的能力进行动态扩展,因此这个地方本身又有两层负载均衡,一个是kubernates提供的集群能力,一个是多个API网关本身提供的集群能力。当然API网关本身也具备负载均衡功能,可以和Kubernate进行衔接。

2. 通过网关的拦截能力来实现所有共性能力抽取和实现

刚才已经谈到启用网关后就承载了数据流,因此可以通过对接口访问输入和输出的拦截来实现所有共性可复用能力的抽取和实现。这些共性能力可以理解为网关实现的一个个拦截插件,本身可插拔,灵活可配置。

这些插件能力中最核心的就是安全,日志,流控。

其中安全可以实现访问安全,传输安全,数据安全等,其中访问安全本身又可以实现类似Token,IP,用户名密码等多种安全控制策略。包括对Auth2.0等标准规范的支持等。

对于日志也是网关提供的一个关键能力,即可以实现对服务消费日志,详细的输入和输出报文的查询能力,这个在各开源网关往往并不具备这个能力,也无法面向业务系统人员去使用,因此这块能力提升往往都需要在开源网关基础上做大量扩展。

流控是我们谈的另外一个关键能力,包括了服务限流和服务熔断。对于服务限流主要是实现对服务消费前线程数控制,资源分配实现消费前等待。而对于服务熔断,即直接对服务进行下线或禁用,以避免大并发服务消费调用对网关造成的影响或带来的服务雪崩等。

一个网关来说,流控能力相对关键,因为网关是中心化节点,必须保证网关的高可靠运行。因此网关流控能力强弱直接影响到网关的高可靠性和性能,而判断流控能力强弱的关键则在于灵活的流量控制策略配置,只有这样才能够做到既实现流控,又不影响到关键业务和接口服务的访问。

3. 满足前后端分离的需求

注意,如果一个企业开发的业务系统涉及到手机APP端,而手机APP端一定涉及到公网访问,按业务系统内部部署安全策略也一定涉及到DMZ区的设置和硬件防火墙隔离。

而对于API网关本身恰好又是可以部署到DMZ区的一个内容,既实现了服务代理路由,又实现了安全隔离,如果存在这种场景,即使业务应用不和外部系统打交道,为了前后端的隔离和外部访问,往往也需要API网关能力支撑。当然前期你也可以使用Ngnix来替代API网关实现统一代理。

4. 灰度发布或金丝雀发布

这个在我原来谈网关的文章的时候很少谈到这点,但是实际上在DevOps和微服务架构实施下,对于灰度发布能力往往也是必须的。比如我们对已有的一个接口服务做了修改,我们想先在某些业务系统试用,没有问题再发布到所有的业务系统。这个时候就涉及到金丝雀发布的问题。当然你可以配置是按系统,按IP,按用户还是其他的发布策略。

这块的能力不仅仅是DevOps的自动部署,同时也必须考虑网关层能够基于动态发布的内容进行路由。确保服务调用消费的路由路径是隔离开的。而对于金丝雀发布策略允许你直接只导入指定量的流量到新的版本,API网关就可以帮你来做这件事情。你可以配置10%的请求到新的版本,然后一旦你确保了新版本没有bug,你可以把流量切换到100%。

5. 服务组合能力

实际上当我们谈API网关的时候,一般不会谈服务组合能力,因为一涉及到服务组合或编排,那么必然导入网关整体架构变重。从当前主流网关看,一般也不提供类似能力。

实际上服务组合编排难点在于,上个服务的输出往往要成为下一个服务的输入,同时服务输入和输出还存在大量的数据映射操作。我们回顾下类似智慧家庭里面的组合场景编排,实际上很简单,比如我回到家后需要打开空调,关窗帘,打开热水器,开灯的一系列动作,我只是需要简单将这些动作编排在一起。

对应到API网关的服务组合,实际上我们也可以做轻量的服务组合,即去掉数据映射等复杂组合场景,只需要实现简单的服务多次调用,服务返回数据的组合等即可。

对于具体的服务组合和编排,可以参考下面这篇文章:

从ESB服务组合编排到NetflixConductor微服务编排

API全生命周期管理能力

可以看到,API网关更多是一个底层引擎,而要实现完整的API管控,往往还需要配合API全生命周期管理能力。这个完全可以在底层API网关引擎基础上进行扩展开发。

API接口的定义

在定义API接口的时候首先要定义API分组,这个从京东,淘宝等OpenAPI能力开放平台的API文档都可以看到,首先要有API归类分组,然后再定义详细的API。

比如京东开放平台,有商品,店铺,仓储,支付等多个类目,然后各类目下有详细的API的定义。

API的定义包括两个部分,一个是API基本信息定义,一个是详细输入输出定义。

API基本信息仍然是包括了API的编码,API名称,API的分组,API的用途描述,API的缓存,安全等基本控制信息的定义等。还有就是这个API接口的访问路径定义,API接口是Get还是Post方法定义等。

API详细信息主要就是API的输入和输出信息定义。

API的输入参数注意实际有多种形式,一个就是在API访问路径上的路径参数,还有一个就是在访问路径后?参数后面的查询参数信息,还有就是一个完整的Request Body请求参数信息。

比如对于Http Rest查询接口,这类Get方法接口,可以看到并没有Body信息,更多的是通过路径和查询参数定义来完成查询。而对于Post接口往往就涉及到具体的Body信息定义。

但是要注意,为了实现Http Rest接口和SOAP WS接口服务的互相转换,对于SOAP WS查询服务接口在自动转换为Http Rest接口服务的时候实际上仍然为转换为Post方法+Body参数模式。

对于API接口定义,仍需要预留标准的系统级参数部分内容。这部分内容是API网关实现统一标准化管理的基础,不能随便修改和变动。比如京东API平台预留的API名称,方法,版本,Token,APP_Key,Date等都是使用系统级别的参数定义,是每一个接口API暴露后都需要增加的参数头信息。

API快速开发的支持

在API接口服务定义完成后,一方面是可以通过类似WADL或RAML等标准的Rest接口定义规范文件,另外一个就是需要提供客户端和服务端的开发框架代码。

在这个基础上,还可以提供完整的示例代码下载,方便开发商或合作伙伴对API接口进行快速开发。开发完成的后端原始服务接口,在注册接入前还可以提供接口服务的模型匹配自校验功能,确认开发的服务完全遵循从上到下方式-》API开发框架生成和API后端服务开发。

对于API接口管理,如果是标准的从顶朝下模式,即在定义了API接口后,实现生成类似WADL或RAML标准接口规范。后端服务基于我们标准的API接口契约进行开发,那么开发完成后就方便快速代理方式接入,在接入过程中就不再有参数映射和转换的问题,否则我们的API接入过程会比较复杂。

API接口服务的注册和接入

API接口定义过程和API接口的注册接入最好分开。

在API接口定义完成后进行API接口服务的注册,即选择具体的后端服务,然后对服务进行接入。同时将后端服务对应到我们在前面定义的API接口代理服务上。注意在前面谈到的API路径定义,方法类型定义,实际上也可以在API接口服务注册和接入的时候来完成。

API接口服务的后续变更发布,还可以考虑和DevOps平台配合并支持灰度发布功能。

反向的后端服务快速接入并发布为API接口服务,即直接对后端已有的API服务进行快速接入,将API后端服务发布为代理服务,在整个接入过程中需要定义API接口名称,API访问路径,API方法类型等信息。在发布为API接口服务后,对于后端服务的API参数信息也需要进行快速导入,以方便在API接口查询中看到详细的接口内容定义。

在将后端业务服务发布为API接口服务的时候,发布的代理服务要自动增加系统级的输入参数信息,这个输入参数最好的方式是在访问路径中进行增加,以减少对已有的后端服务的影响。

API接口在注册和接入完成后,将自动进行服务部署和服务发布,即注册接入完成后的服务可以通过发布的访问路径地址进行访问。

服务接入适配能力

服务注册接入本身分为两个层面,一个是已有服务的注册接入,一个是需要适配后的服务发布。在设计的时候需要考虑到两个方面的需求。

对于已有服务的存代理接入最简单,即只需要提供业务系统的Rest接口服务地址即可,在接入的时候,对相关的日志,安全,流控,负载均衡等策略进行配置,配置完成后即完成服务接入和注册。同时对于路由服务接入需要单独考虑,对于路由服务在接入的时候可以适配到多个原始业务系统的接口服务地址。

服务发布是对原来我们服务适配功能的一个改进,即直接从底向上的进行服务发布,而不需要实现定义服务元数据或模型,制定服务契约格式等,在服务发布完成后再生成相关的基础数据到服务元数据库即可。对于服务发布参考服务适配的能力,我们可以考虑如下场景下的需求。

将一个已有的SOAP WS服务发布和注册为一个Http Rest接口服务。将一个数据库表,或存储过程发布为一个Http Rest接口服务。 将一个JMS消息接口发布为一个Http Rest接口服务。将一个JAR包中的API接口方法或函数发布为一个Http Rest接口服务。

对于服务发布而言,如果不仅仅是微服务网关能力,而是一个微服务支撑或微服务快速开发平台的话,还可以提供完整的服务开发和设计能力。即在微服务平台首先定义数据或对象模型,然后将对象模型转换为Http Rest中的资源对象,并发布对应的Get , Post各种Http Rest接口服务。

对应发布的接口服务可以直接在微服务平台上进行拦截,模拟生成相关的输入或输出数据。当然也可以直接将数据模型对象生成到对应的数据库,同时将微服务API接口的实现生成对应的Java代码框架并给出参考实现。而我们剩余的工作,仅仅是填充代码逻辑即可。通过这种方式可以极大的提高我们进行微服务架构开发的速度。

API接口在线模拟测试功能

这个功能参考当前的OpenAPI能力开放平台的做法来实现即可。即对于已经发布完成的API接口服务,提供在线测试工具进行在线测试。同时对接口服务调用的输入参数进行结构化展示,方便用户对测试需要的各种参数进行输入。在输入完成后形成完整的提交参数完整字符串。通过测试,可以返回最终的模拟调用返回结果字符串信息。

同样,这里可以采用Swagger工具来完成,Swagger不仅仅是API接口的定义,接口文档的生成,同时还可以根据可以接口定义,自动生成接口测试用例,对接口进行测试工作。我们也很容易将Swagger能力整合都API网关的管理平台中。

API接口查询功能

对于API接口查询功能也是一个标准的功能,实际上可以考虑将查询功能和API接口服务的分类浏览分开。对于API接口的分类浏览参考开放平台的API接口文档做法来实现接口。对于API接口查询,即可以设置不同的动态查询条件,对API接口进行查询,返回结果集。对于查询到的API接口清单列表,可以点击详细进入到API接口详细的输入和输出信息查看界面。

API状态管理功能

对于已经注册和发布的API接口可以对其状态进行管理。其中主要的状态包括了待发布,上线,暂停,下线废弃等几种关键状态。对于API状态本身还需要和后续的API监控管理结合,能够通过API性能监控动态的调整API接口的状态。比如在API触发熔断后,自动对API接口状态调整为暂停。

API版本管理能力

对于API需要启用版本管理能力。当前一些API接口服务实现方法会在路径参数中增加API版本信息,以确定究竟访问哪个版本。但是由于不同的API版本可能存在返回的结果集的数据结构不一样的问题,因此对于这种场景需要针对该API定义不同的大版本,不同的大版本实际上对应不同的后端原始服务。

在这里我们介绍下当前主流的一些API网关功能供参考。

开源Kong API网关

在微服务架构之下,服务被拆的非常零散,降低了耦合度的同时也给服务的统一管理增加了难度。如上图左所示,在旧的服务治理体系之下,鉴权,限流,日志,监控等通用功能需要在每个服务中单独实现,这使得系统维护者没有一个全局的视图来统一管理这些功能。API 网关致力于解决的问题便是为微服务纳管这些通用的功能,在此基础上提高系统的可扩展性。

Kong 的插件机制是其高可扩展性的根源,Kong 可以很方便地为路由和服务提供各种插件,网关所需要的基本特性,Kong 都如数支持:

云原生: 与平台无关,Kong可以从裸机运行到Kubernetes动态路由:Kong 的背后是 OpenResty+Lua,所以继承了动态路由的特性限流和熔断健康检查日志: 可以记录通过 Kong 的 HTTP,TCP,UDP 请求和响应。鉴权: 权限控制,IP 黑白名单,同样是 OpenResty 的特性SSL: Setup a Specific SSL Certificate for an underlying service or API.监控: Kong 提供了实时监控插件认证: 如数支持 HMAC, JWT, Basic, OAuth2.0 等常用协议REST API: 通过 Rest API 进行配置管理,从繁琐的配置文件中解放可用性: 天然支持分布式高性能: 背靠非阻塞通信的 nginx,性能自不用说插件机制: 提供众多开箱即用的插件,且有易于扩展的自定义插件接口

从上面图可以看到,Kong网关是基于OpenResty应用服务器,OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。而Kong 核心基于OpenResty构建,并且拥有强大的插件扩展功能。

在Http请求到达Kong网关后,转发给后端应用之前,可以通过网关的各种插件对请求进行流量控制,安全,日志等各方面的处理能力。当前Kong的插件分为开源版和社区版,社区版还有更多的定制功能,但是社区版是要收费的。

目前,KONG开源版本一共开放28个插件,如下:

acl、aws-lambda、basic-auth、bot-detection、correlation-id、cors、datadog、file-log、galileo、hmac-auth、http-log、ip-restriction、jwt、key-auth、ldap-auth、loggly、oauth2、rate-limiting、request-size-limiting、request-termination、request-transformer、response-ratelimiting、response-transformer、runscope、statsd、syslog、tcp-log、udp-log。

以上这些插件主要分五大类,Authentication认证,Security安全,Traffic Control流量控制,Analytics & Monitoring分析&监控,Logging日志,其他还有请求报文处理类。插件类似AOP开发中的横切功能,可以灵活的配置进行拦截控制,下面选择一些关键性的插件进行简单的说明。

黑白名单控制能力-ip-restriction

Kong提供的IP黑白名单控制能力还算相当强,从配置项里面可以看到主要可以针对两个维度进行配置,一个是针对所有的API接口还是针对特定的API接口,一个是针对所有的所有的消费方还是特定的某个消费方。对于IP配置可以是一个区段,也可以是特定的IP地址。但是黑白名单不能同时配置,其次当前没有一个功能是针对某一个系统提供的所有服务都启用黑名单或白名单功能。

日志记录能力-syslog, file-log,http-log

这里主要日志的插件比较多,一个是sysLog在配置后可以直接将Kong产生的日志写入到应用服务器的系统日志文件中。如果配置了file-log则是单独写入到你指定的file文件中。对于http-log则是对于http服务请求,可以详细的记录请求的输入和输出报文信息,但是具体是记录到哪里,需要通过config.http_endpoint配置。具体关键的配置参数信息如下:

consumer_id: 可选参数,消费者id(启用了消费者认证可以使用,根据id识别发出请求的消费者);

config.http_endpoint: 日志接收服务器(包括使用的协议,http or https);

config.method: 可选参数,默认POST,访问日志服务器的请求方式(可选值:PUT,PATCH,POST);

config.timeout: 可选参数,默认10000毫秒,请求超时时间

config.keepalive: 可选参数,默认60000毫秒,连接在关闭之前可存活时间

熔断插件-request-termination

该插件用来定义指定请求或服务不进行上层服务,而直接返回指定的内容.用来为指定的请求或指定的服务进行熔断。注意Kong的熔断插件感觉是临时对服务的禁用,而不是说当达到某一种监控阈值的时候自动触发熔断,或者相关内容还没有了解到。从官方文档的应用场景也可以看到这点。

Temporarily disable a Service (e.g. it is under maintenance).

Temporarily disable a Route (e.g. the rest of the Service is up and running, but a particular endpoint must be disabled).

Temporarily disable a Consumer (e.g. excessive consumption).

如果仅仅是这种方式的熔断话,实际上意义并不是很大。但是可用的地方就在于当某个业务系统进行发版部署的时候我们可以对该业务系统或该业务系统所提供的所有服务进行熔断。

限流插件-rate-limiting

Kong当前提供的限流相对来说还是比较弱,即主要是控制某一个API接口服务在单位时间内最多只能够调用多少次,如果超过这个次数那么网关就直接拒绝访问并返回错误提示信息。而在前面我讲限流和流量控制的时候经常会说到,就是限流实际上一个是根据服务调用次数,一个是根据服务调用数据量,需要在这两个方面进行限流。而里面更加重要的反而是数据量的限流,因为大数据量报文往往更加容易造成内存溢出异常。

安全认证类插件

当前Kong网关提供basic-auth,key-auth、ldap-auth,hmac-auth多种认证插件。

Basic-auth基本认证插件,即我们根据用户名和密码来生成一个base64编码,同时将该编码和目标服务绑定,这样在消费目标服务的时候就需要在报文头填写这个Base64编码信息。

Key-auth认证插件则是利用提前预设好的关键字名称,如下面设置的keynote = apices,然后为consumer设置一个key-auth 密钥,假如key-auth=test@keyauth。在请求api的时候,将apikey=test@keyauth,作为一个参数附加到请求url后,或者放置到headers中。

Hmac-auth插件是设置绑定的service和rout,以启动hmac验证。然后在Consumers页面中Hmac credentials of Consumer设置中添加一个username和secret。

请求报文容量限制-request-size-limiting

该插件用于限制请求报文的数据量大小,可以限制单个服务,也可以显示所有的API接口服务。

支持OAuth2.0身份认证-oauth2

Kong网关支持OAuth2.0身份认证,OAuth2.0 协议根据使用不同的适用场景,定义了用于四种授权模式。

Authorization code(授权码模式):标准的 Server 授权模式,非常适合 Server 端的 Web 应用。一旦资源的拥有者授权访问他们的数据之后,他们将会被重定向到 Web 应用并在 URL 的查询参数中附带一个授权码(code)。在客户端里,该 code 用于请求访问令牌(access_token)。并且该令牌交换的过程是两个服务端之前完成的,防止其他人甚至是资源拥有者本人得到该令牌。另外,在该授权模式下可以通过 refresh_token 来刷新令牌以延长访问授权时间,也是最为复杂的一种方式。

Implicit Grant(隐式模式):该模式是所有授权模式中最简单的一种,并为运行于浏览器中的脚本应用做了优化。当用户访问该应用时,服务端会立即生成一个新的访问令牌(access_token)并通过URL的#hash传回客户端。这时,客户端就可以利用JavaScript等将其取出然后请求API接口。该模式不需要授权码(code),当然也不会提供refresh token以获得长期访问的入口。

Resource Owner Password Credentials(密码模式):自己有一套用户体系,这种模式要求用户提供用户名和密码来交换访问令牌(access_token)。该模式仅用于非常值得信任的用户,例如API提供者本人所写的移动应用。虽然用户也要求提供密码,但并不需要存储在设备上。因为初始验证之后,只需将 OAuth 的令牌记录下来即可。如果用户希望取消授权,因为其真实密码并没有被记录,因此无需修改密码就可以立即取消授权。token本身也只是得到有限的授权,因此相比最传统的 username/password 授权,该模式依然更为安全。

Client Credentials(客户端模式):没有用户的概念,一种基于 APP 的密钥直接进行授权,因此 APP 的权限非常大。它适合像数据库或存储服务器这种对 API 的访问需求。

简单转换能力-request-transformer and response transformer

Kong网关提供对输入和输出报文简单转换的能力,这部分内容后续再详细展开介绍。从当前配置来看,主要是对消息报文提供了Add, Replace,Rename,Append等各种简单操作能力。

Kong网关和其它网关的一些对比。

从上面对比图也可以看到,Kong网关在功能,性能,插件可扩展性各方面都能够更好的满足企业API网关的需求。因此我们也是基于Konga来进一步定制对Kong网关的管控治理平台。

在整个定制中增加了基于DB适配的Http Rest API接口的自动发布,API服务自动化注册,服务日志采集和服务日志查询,常见映射模板定制,接口服务的自动化测试等方面的能力。

阿里公有云API网关

首先我们来看下阿里云提供的API网关产品的功能介绍:

API 网关(API Gateway),是提供API托管服务,涵盖API发布、管理、运维、售卖的全生命周期管理。辅助用户简单、快速、低成本、低风险的实现微服务聚合、前后端分离、系统集成,向合作伙伴、开发者开放功能和数据。

阿里提供的API网关提供的关键功能,参考产品本身的功能文档说明,主要如下:

API 生命周期管理

支持包括API 注册和接入发布、API 测试、API 下线等生命周期管理功能。支持 API 日常管理、API 版本管理、API 快速回滚等维护功能。基本需要覆盖API管理全生命周期。

全面的安全防护

支持多种认证方式,支持 HMAC (SHA-1,SHA-256) 算法签名。支持 HTTPS 协议,支持 SSL 加密。防攻击、防注入、请求防重放、请求防篡改。(没看到是否支持Auth2.0和具体的Token验证机制)

灵活的权限控制

用户以 APP 作为请求 API 的身份,网关支持针对 APP 的权限控制。只有已经获得授权的 APP 才能请求相应的 API。API 提供者可以将调用某个API 的权限主动授予给某个APP。若 API上架到 API 市场,购买者可以将已购买的 API 授权给自己的 APP。(没看到是否基于IP进行控制,还是基于Token进行控制,即对于消费方分配独立的Token信息)

精准的流量控制

流量控制可以用于管控 API的被访问频率、APP的请求频率、用户的请求频率。流量控制的时间单位可以是分钟、小时、天。支持流控例外,允许设置特殊的 APP 或者用户。(流量控制只支持服务运行频率,没看到可以基于数据量进行流控)

请求校验

支持参数类型、参数值(范围、枚举、正则、Json Schema)校验,无效校验会被 API 网关直接拒绝,以减少无效请求对后端造成的资源浪费,大幅降低后端服务的处理成本。(这个功能实际有一定的用处,并不会牺牲太多的性能,但是会实现一些简单的参数完整性校验能力。)

数据转换

通过配置映射规则,实现前、后端数据翻译。支持前端请求的数据转换。支持返回结果的数据转换。(暂时不清楚数据转换功能能够实现的能力)

监控报警

提供可视化的API实时监控,包括:调用量、流量大小、响应时间、错误率,在陆续增加维度。支持历史情况查询,以便统筹分析。可配置预警方式(短信、Email),订阅预警信息,以便实时掌握API运行情况。

自动工具

自动生成 API 文档,可供在线查看。API 网关提供多种语言 SDK 的示例。降低 API 的运维成本。提供可视化的界面调试工具,快速测试,快速上线。(当前网上也有不少的API接口文档自动生成工具可选)

API 市场

可将 API 上架到 API 市场,供更多开发者采购和使用。

从整个功能的介绍可以看到对于API的全生命周期管理(注册,接入,代理,路由,负载均衡),安全,权限,流量控制,监控和告警等是所有API网关都必须具备的功能。而对于API市场,API文档自动生成,请求的参数校验,数据的转换等则可以看做是扩展功能。

对于API市场往往是一个重要的扩展能力,即对于API接口服务可以作为商品一样进行订购和使用,并根据相应的调用次数,调用的数据量等条件进行计费处理。这我们我们说的PaaS平台的服务层能力作为产品和服务发布,能够进行订购生产订单,能够进行计费等完全是一个道理。

对于公有云上API网关存在的背景说明

对于类似亚马逊,华为云,阿里云等公有云上为何要提供API网关类产品,其关键点还是在于一个企业如果内部的主动业务应用和系统都迁移到公有云后,那么当企业需要将内部多个业务系统的共享或发布给外部使用的时候如何做?这个时候必须要有一个API网关,来进行能力的统一发布,最基本是提供统一的服务目录访问,更加重要的是实现统一的安全管理,授权,服务日志监控预警能力。

因此一个企业迁移到公有云后,只要存在内部多业务系统,多组件都需要发布API接口能力给外部使用的时候,一定存在API网关的应用场景。

其它开源API网关

有赞团队的API网关实践

有赞API网关目前承载着微商城、零售、微小店、餐饮、美业、AppSDK、部分PC、三方开发者等多个业务的调用,每天有着亿级别的流量。

有赞后端服务最开始是由PHP搭建,随着整个技术体系的升级,后面逐步从PHP迁移到基于Dubbo开发了一个新的框架Nova,兼容Dubbo调用,同时支持调用PHP服务。于是网关也支持了新的Nova协议,这样就有Dubbo、Http、Nova三种协议。

在这篇文章中提到的网关核心设计部分相关内容可以参考

异步特性:我们使用Jetty容器来部署应用,并开启Servlet3.0的异步特性,由于网关业务本身就是调用大量业务接口,因此IO操作会比较频繁,使用该特性能较大提升网关整体并发能力及吞吐量。

缓存:为了进一步提升网关的性能,我们增加了一层分布式缓存(借用Codis实现),将一些不经常变更的API元数据缓存下来,这样不仅减少了应用和DB的交互次数,还加快了读取效率。

链式处理:在设计网关的时候,我们采用责任链模式来实现网关的核心处理流程,将每个处理逻辑看成一个Pipe,每个Pipe按照预先设定的顺序先后执行

平滑限流:消除了简单计数器限流带来的短时间内流量不均的问题。目前网关支持IP、店铺、API、应用ID和三方ID等多个维度的限流,也支持各维度的自由组合限流。

熔断降级:使用Hystrix进行熔断降级处理。Hystrix支持线程池和信号量2种模式的隔离方案,内部也开发了一个基于Hystrix的服务熔断平台

预警监控:实时地从Kafka消费API调用日志,如果发现某个API的RT或者错误次数超过配置的报警阈值,则会立即触发报警

企业级API网关设计

这篇文章是对企业级API网关设计必须系统化的产生,从API网关的概述,API网关所起的作用,当前主流的API网关功能对比分析,API网关的高可用性设计多方面进行了阐述。

网关层作为客户端与服务端的一层挡板,主要起到了三大类作用:

隔离作用:作为企业系统边界,隔离外网系统与内网系统。解耦作用:通过解耦,使得微服务系统的各方能够独立、自由、高效、灵活地调整。脚手架作用:提供了一个地点,方便通过扩展机制对请求进行一系列加工和处理。

API网关作为对外提供服务的入口,就像企业服务的大门。一方面,要有足够的能力,应对大量的对外访问,另一方面,还要给对内的服务提供一定的安全保障。除此之外,企业提供的API服务多种多样,API网关要能够对这些API的全生命周期进行便捷的管理,例如服务发布、调整、下架、计费、监控等。

企业API网关在功能设计上主要应该考虑如下内容:

API 生命周期管理功能:覆盖 API 的定义、测试、发布的整个生命周期管理。

API开发和使用支持功能:

安全防护功能:API 请求到达网关需要经过身份认证、权限认证,才能到达后端服务。流量控制功能:API调用次数,异常,分级。流控粒度:分钟、小时、天。请求管理功能:可根据配置进行参数类型、参数值(范围、枚举、正则)的校验监控告警功能:提供实时、可视化的 API 监控,调用量、调用方式、响应时间、错误率。API交易功能: 提供API交易市场,计量计费、Quota 控制、运营售卖等需求。

顺着这篇文章,我们参考了另外一篇谈如何设计高并发下API网关的一篇文章,重点对并发模型,SEDA基于事件的并发架构进行了阐述。

地址:?__biz=MzI5MDEzMzg5Nw==&mid=&idx=1&sn=f1c1bd5e22e2ae7dedf4b788a625e814&scene=21#wechat_redirect

传统的并发编程模型主要有两种:一种是Thread-based concurrency, 另一种是Event-driven concurrency。总结下两种模式的特点如下:

基于线程的并发:每个任务一线程直线式的编程使用资源高昂,context切换代价高,竞争锁昂贵,太多线程可能导致吞吐量下降,响应时间暴涨;

基于事件的并发:单线程处理事件的每个并发流实现为一个有限状态机应用直接控制并发负载增加的时候,吞吐量饱和响应时间线性增长。

SEDA架构是目前云计算、微服务时代下一种优秀的消息处理架构,而且历经考验,稳定可靠。SEDA架构的核心思想:把一个请求处理过程分成几个Stage,每个Stage可由不同的微服务进行处理,不同资源消耗的Stage使用不同数量的线程来处理,微服务之间采用异步通讯的模式。

开源API网关Goku

GoKu API Gateway,中文名:悟空API网关,是eoLinker旗下、国内首个企业级开源的go语言API网关,帮助企业进行API服务治理与API性能安全维护,为企业数字化赋能。

GoKu支持OpenAPI与微服务管理,支持私有云部署,实现API转发、请求参数转换、数据校验等功能,提供图形化界面管理,能够快速管理多个API网关,提高API业务安全性。

码云地址:官网地址:https://www.eolinker.com/product/api_gateway/

Goku API Gateway (悟空 API 网关)是运行在企业系统服务边界上的微服务网关。当您构建网站、App、IOT甚至是开放API交易时,Goku API Gateway 能够帮你将内部系统中重复的组件抽取出来并放置在Goku网关上运行,如进行用户授权、访问控制、防火墙、数据转换等;并且Goku 提供服务编排的功能,让企业可以快速从各类服务上获取需要的数据,对业务实现快速响应。

Goku API Gateway 的社区版本(CE)拥有完善的使用指南和二次开发指南,代码使用纯 Go 语言编写,拥有良好的性能和扩展性,并且内置的插件系统能够让企业针对自身业务进行定制开发。并且 Goku API Gateway 支持与 EOLINKER 旗下的 API Studio 接口管理平台结合,对 API 进行全面的管理、自动化测试、监控和运维。

产品关键特性

控制台:通过清晰的UI界面对网关集群进行各项配置。集群管理:Goku网关节点是无状态的,配置信息自动同步,支持节点水平拓展和多集群部署。热更新:无需重启服务,即可持续更新配置和插件。服务编排:一个编排API对应多个backend,backend的入参支持客户端传入,也支持backend间的参数传递;backend的返回数据支持字段的过滤、删除、移动、重命名、拆包和封包;编排API能够设定编排调用失败时的异常返回。数据转换:支持将返回数据转换成JSON或XML。负载均衡:支持有权重的round-robin负载平衡。服务发现:从 Consul、Eureka 等注册中心发现后端服务器。HTTP(S)反向代理:隐藏真实后端服务,支持 Rest API、Webservice。多租户管理:根据不同的访问终端或用户来判断。访问策略:支持不同策略访问不同的API、配置不同的鉴权(匿名、Apikey、Basic)等。灵活的转发规则:支持模糊匹配请求路径,支持改写转发路径等,可为不同访问策略或集群设置不同的负载。IP黑白名单。自定义插件:允许插件挂载在常见阶段,例如before match,access和proxy。CLI: 使用命令行来启动、关闭和重启Goku。Serverless: 在转发过程的每一个阶段,都可以添加并调用自定义的插件。请求日志(access log):仅记录转发的基本内容,自定义记录字段与排序顺序,定期自动清理日志。运行日志(system log):提供控制台和节点的运行日志,默认仅记录ERROR等级的信息,可将等级按实际情况调成INFO、WARN或DEBUG。可扩展:简单易用的插件机制方便扩展功能。高性能:性能在众多网关之中表现优异。Open API:提供 API 对网关进行操作,便于集成。版本控制:支持操作的发布和多次回滚。监控和指标:支持Prometheus、Graphite。

具体对比:#/tutorial/?groupID=c-269&productID=19

从对比可以看到,开源版本对于关键的服务限流熔断,服务降级,数据缓存,格式转换,请求大小校验等能力是没有的,这些能力只在企业版本中提供。

由于该网关基于Go语言编写,因此比类似Zuul网关有更好的性能,实际性能测试结果数据来看,和Kong网关的性能比较接近,比Kong网关性能略好。

关键内容说明

整个部署架构图和常见的ESB总线或API网关产品类似,数据库可以采用Oracle或Mysql数据库,缓存采用Redis库进行缓存。前端通过F5或Ngnix进行负载均衡,本身网关节点是无状态的,支持集群化架构部署。

通过定期检查后端服务器的可用情况,智能识别可用后端、屏蔽不可用后端,减少服务器开销。这个实际类似对后端的业务服务进行心跳监测,出现问题后进行屏蔽或预警,后端服务不可用时候实际通过API网关封装暴露的新代理服务本身也处于不可用状态。

对于后端的业务服务本身可以再通过类似Ngnix集群或K8s集群暴露集群IP地址接入,当然网关本身也支持直接将多个后端业务多节点接入到网关中,由网关对后端业务服务器阶段进行负载均衡,在采用了类似容器化和K8s或集群架构的后端来说,该功能往往并不会用到。

API健康检查,文档编写完成之后,API 定期检查节点运行状态,若节点出现异常则通过邮件或者API发送告警信息,并自动尝试重启修复节点。实际我们看到对于API的监控检查包括了两个方面,一个是通过网关封装后的API节点的监控检查,一个是后端业务API服务的监控检查。

API断线重连:请求转发失败后,网关会进行一定次数的断线重连,防止因网络闪断等原因导致API访问质量下降。这个类似我们说的服务重试机制,传统ESB总线的标准能力。该功能还是有用,主要是为了防止网络闪断引起的服务访问异常。

在网关里可以给不同的调用方或客户端设置访问策略,不同的访问策略可以设置不同的 API 访问权限、鉴权方式以及插件功能等。网关支持 开放策略 与 普通策略:

开放策略:系统自带访问策略,使用开放策略时不需要传递策略 ID 参数;普通策略:自定义访问策略,需要传递策略 ID 参数。

网关的插件分为 策略插件 与 API插件。

策略插件包括:流量控制、鉴权、IP黑白名单等。API插件包括:参数映射、额外参数、熔断、服务降级等。

鉴权的对象为 策略 (Strategy) ,策略可表示为一个公司、一个业务部门或一个用户。开源版网关支持以下鉴权方式:Public、Basic、Apikey。暂时没有看到基于消费访问IP地址的服务访问鉴权,不清楚是否企业版由对应的IP认证鉴权支持。

日志管理能力

网关系统的日志分为两大部分:请求日志(access.log)和系统运行时日志;运行时日志又分为:控制台的运行日志(console.log)、各节点的运行日志(node.log)。对于请求日志可以详细的配置日志存放路径,记录周期,具体记录的内容等。

整体相对来说,当前网关提供的日志管理能够偏弱,特别是日志信息的查看,基于服务日志运行进行的API接口服务的运行分析统计等方面的能力。

参数映射:功能具备,但是使用起来会比较麻烦,暂时没看到图形化或者表格方式的参数映射界面。对于参数映射不一定完全的图形化,但是提供类似阿里云API网关的表格化映射是一种可行的方式。

小豹API网关

这个是最近在网上查找API网关相关资料的时候搜索到的一个商用的API网关,从产品介绍材料来看,我们前面谈过的网关的核心功能基本上全部包括,而且相当来说也比较完善。同时提供了一个较方便的API网关的治理管控平台,可以方便的对API注册接入和运行全生命周期, 方便对安全,流控,日志各方面进行灵活管控。

下面我们看下网站对API网关架构特点的一些说明:

基于Netty NIO的响应式架构;分布式缓存基于Redis;数据库基于Mysql,分布式配置基于ZooKeeper

API配置缓存,运行时不依赖DB,配置更新后自动通知各网关节点;

支持自定义组件,动态加载,在不中断网关服务的情况下重新加载配置和运行组件;

API服务连续异常后自动熔断和自我恢复,访问异常、超时处理;

网关核心运行过程不写磁盘IO,避免磁盘IO性能影响网关吞吐量;

Docker容器化支持,拆分网关、管理服务、第三方中间件依赖等镜像,便于灵活扩容。

RestCloud API企业微服务API开发

http://www.restcloud.cn/restcloud/mycms/apigateway.html

RestCloud API网关是完全自主研发的面向企业级的API网关,一且以简单、易用、轻量级为目标进行研发,同时兼顾作为企业级的服务总线可以替换企业原有的ESB产品,RestCloud是集ESB和API网关于一体的企业级网关产品。这个不仅仅提供了API网关, 也提供了微服务快速开发平台,API服务治理平台,DaaS等相关组件。

另外RestCloud本身还提供了Http Rest API接口的快速开发平台,可以将数据库表,表对象,1多多对象关系的快速的发布为Http Rest API接口服务,同时支持多数据库接口适配。