java 单机接口限流处理方案
310
2022-10-31
本文目录一览:
服务编排/数据聚合 指的是可以通过一个请求来依次调用多个微服务,并对每个服务的返回结果做数据处理,最终整合成一个大的结果返回给前端。
例如一个服务是“查询用户预定的酒店”,前端仅需要传一个订单ID,后端会返回整个订单的信息,包括用户信息、酒店信息和房间信息等。
这个服务背后可能对应着以下几个操作:
微服务架构上对功能做了解耦,使用服务编排可以快速从各类服务上获取需要的数据,对业务实现快速响应。总的来说,编排有以下几点优势:
Goku API Gateway (中文名:悟空 API 网关)是一个基于 Golang 开发的微服务网关,能够实现高性能 HTTP API 转发、服务编排、多租户管理、API 访问权限控制等目的,拥有强大的自定义插件系统可以自行扩展,并且提供友好的图形化配置界面,能够快速帮助企业进行 API 服务治理、提高 API 服务的稳定性和安全性。
Goku API Gateway支持一个编排API对应多个后端服务,每个后端服务的请求参数可以使用前端传入的参数,也可以在编排里自定义(写静态参数或从返回数据里获得)。每个后端服务的返回数据支持过滤、删除、移动、重命名、拆包和封包等操作;编排API能够设定编排失败时的异常返回。
Goku API Gateway 的社区版本(CE)同时拥有完善的使用指南和二次开发指南,内置的插件系统也能够让企业针对自身业务进行定制开发。
项目地址:
官网地址:
我们将编排的整个操作放到网关进行,由网关对数据做处理与转换,这样无需对后端服务做改动。一个请求到达网关,网关调用多个后端服务,并且在网关上对各个服务的返回数据做处理(操作有过滤、移动、重命名、封包、拆包,后面会对各操作做详细解释),最后由网关将数据整合好返回给前端。
网关将编排过程中对 API的转发处理过程 (转发-获取返回数据-数据处理)称为一个 Step 。
添加一个转发服务,该服务为 查询订单详情API,配置相应的转发地址、传入的参数、对返回数据做何种处理等。
由于篇幅原因,后续的Step(查询用户详情、查询酒店详情、查询房间详情)就不一一展示了。
网关将编排过程中对 API的转发处理过程 (转发-获取返回数据-数据处理)称为一个 Step。
我们将处理查询订单详情API称为 Step1 ,其中Step1的返回数据有:用户ID、酒店ID、房间ID。同理,将查询用户信息这步称为 Step2 ,将查询酒店信息称为 Step3 ,将查询房间信息称为 Step4 。
传参规则:
以下为转发路径的传参写法:
Step2中需要接收Step1里返回的userID作为参数,同时需要接收前端传入的Authorization参数
在网关里Step2的请求参数配置如下所示,请求参数存在多个的话用换行表示:
1.查询订单详情的API,返回数据称为json1,内容如下:
2.查询用户详情的API,返回数据称为json2,内容如下:
3.查询酒店详情的返回数据,称为json3,内容如下:
4.查询房间详情的返回数据,称为json4,内容如下:
5.可以在每一个Step里对返回Json做处理,网关会将处理过的数据最后整合起来,再返回前端,例如这是通过网关返回的最终数据:
这里以查询酒店详情API的返回数据json3为例,讲解网关如何在编排过程中对返回数据做处理。
查询酒店详情API返回的原始数据如下:
从网关返回给前端的数据中截取酒店信息的数据如下:
从原始数据到处理后的数据需要经过以下操作:
字段黑名单的作用是排除某些字段,支持数组形式。
在网关的Step3里配置如下:
经过网关处理后,实际的返回数据如下,可以看到data对象里的id字段已经被过滤掉:
拆包是指将指定对象的内容提取出来作为该步骤(step)的返回结果。其中匹配目标只能为object,匹配目标为空时,结果为 {},可用于清除数据。
在网关的Step里配置如下:
经过网关处理后,实际的返回数据如下,可以看到data对象被拆开,最终数据仅保留了data对象里面的字段:
字段封包会将当前的数据整体打包为最终返回数据中的一个对象,不支持*,不支持数组。
在网关的Step里配置如下:
经过网关处理后,实际的返回数据如下,数据被整体打包为hotelinfo对象:
经过三个步骤,就可以将原始数据变成最终的数据。
本文仅列举了编排过程中部分数据处理的操作,如需了解更多编排细则,可通过文末给出的教程链接。
相关链接
Micro的api就是api网关
API参考了 API网关模式 为服务提供了一个单一的公共入口。基于服务发现,使得micro api可以提供具备http及动态路由的服务。
Micro的API基于HTTP协议。请求的API接口通过HTTP协议访问,并且路由是基于服务发现机制向下转发的。 Micro API在 go-micro 之上开发,所以它集成了服务发现、负载均衡、编码及基于RPC的通信。
因为micro api内部使用了go-micro,所以它自身也是可插拔的。 参考 go-plugins 了解对gRPC、kubernetes、etcd、nats、及rabbitmq等支持。另外,api也使用了 go-api ,这样,接口handler也是可以配置的。
ACME( Automatic Certificate Management Environment)是由 Let’s Encrypt 制定的安全协议。
可以选择是否配置白名单
API服务支持TLS证书
API使用带分隔符的命名空间来在逻辑上区分后台服务及公开的服务。命名空间及http请求路径会用于解析服务名与方法,比如 GET /foo HTTP/1.1 会被路由到 go.micro.api.foo 服务上。
API默认的命名空间是 go.micro.api ,当然,也可以修改:
我们演示一个3层的服务架构:
完整示例可以参考: examples/greeter
先决条件:我们使用Consul作为默认的服务发现,所以请先确定它已经安装好了,并且已经运行,比如执行 consul agent -dev 这样子方式运行。
向micro api发起http请求
HTTP请求的路径 /greeter/say/hello 会被路由到服务 go.micro.api.greeter 的方法 Say.Hello 上。
绕开api服务并且直接通过rpc调用:
使用JSON的方式执行同一请求:
micro api提供下面类型的http api接口
请看下面的例子
Handler负责持有并管理HTTP请求路由。
默认的handler使用从注册中心获取的端口元数据来决定指向服务的路由,如果路由不匹配,就会回退到使用”rpc” hander。在注册时,可以通过 go-api 来配置路由。
API有如下方法可以配置请求handler:
通过 /rpc 入口可以绕开handler处理器。
API处理器接收任何的HTTP请求,并且向前转发指定格式的RPC请求。
RPC处理器接收json或protobuf格式的HTTP POST请求,然后向前转成RPC请求。
代理Handler其实是内置在服务发现中的反向代理服务。
事件处理器使用go-micro的broker代理接收http请求并把请求作为消息传到消息总线上。
Web处理器是,它是内置在服务发现中的HTTP反向代理服务,支持web socket。
/rpc 端点允许绕过主handler,然后与任何服务直接会话。
示例:
更多信息查看可运行的示例: github.com/micro/examples/api
解析器,Micro使用命名空间与HTTP请求路径来动态路由到具体的服务。
API命名的空间是 go.micro.api 。可以通过指令 --namespace 或者环境变量 MICRO_NAMESPACE= 设置命名空间。
下面说一下解析器是如何使用的:
RPC解析器示例中的RPC服务有名称与方法,分别是 go.micro.api.greeter , Greeter.Hello 。
URL会被解析成以下几部分:
带版本号的API URL也可以很容易定位到具体的服务:
代理解析器只处理服务名,所以处理方案和RPC解析器有点不太一样。
URL会被解析成以下几部分:
了解着名的Nginx服务器(微服务必不可少的东西)如何用作API网关。
现代应用程序体系结构的核心是HTTP API。 HTTP使应用程序能够快速构建并轻松维护。无论应用程序的规模如何,HTTP API都提供了一个通用接口,从单用途微服务到无所不包的整体。通过使用HTTP,支持超大规模Internet属性的Web应用程序交付的进步也可用于提供可靠和高性能的API交付。
有关API网关对微服务应用程序重要性的精彩介绍,请参阅我们博客上的构建微服务:使用API网关。
作为领先的高性能,轻量级反向代理和负载均衡器,NGINX Plus具有处理API流量所需的高级HTTP处理功能。这使得NGINX Plus成为构建API网关的理想平台。在这篇博文中,我们描述了许多常见的API网关用例,并展示了如何配置NGINX Plus以便以高效,可扩展且易于维护的方式处理它们。我们描述了一个完整的配置,它可以构成生产部署的基础。
注意:除非另有说明,否则本文中的所有信息均适用于NGINX Plus和NGINX开源。
API网关的主要功能是为多个API提供单一,一致的入口点,无论它们在后端如何实现或部署。并非所有API都是微服务应用程序。我们的API网关需要管理现有的API,单块和正在部分过渡到微服务的应用程序。
在这篇博文中,我们引用了一个假设的库存管理API,即“仓库API”。我们使用示例配置代码来说明不同的用例。 Warehouse API是一个RESTful API,它使用JSON请求并生成JSON响应。但是,当部署为API网关时,使用JSON不是NGINX Plus的限制或要求; NGINX Plus与API本身使用的架构风格和数据格式无关。
Warehouse API实现为离散微服务的集合,并作为单个API发布。库存和定价资源作为单独的服务实施,并部署到不同的后端。所以API的路径结构是:
例如,要查询当前仓库库存,客户端应用程序会向/ api / warehouse / inventory发出HTTP GET请求。
使用NGINX Plus作为API网关的一个优点是,它可以执行该角色,同时充当现有HTTP流量的反向代理,负载平衡器和Web服务器。如果NGINX Plus已经是应用程序交付堆栈的一部分,那么通常不需要部署单独的API网关。但是,API网关所期望的某些默认行为与基于浏览器的流量的预期不同。出于这个原因,我们将API网关配置与基于浏览器的流量的任何现有(或未来)配置分开。
为实现这种分离,我们创建了一个支持多用途NGINX Plus实例的配置布局,并为通过CI / CD管道自动配置部署提供了便利的结构。 / etc / nginx下的结果目录结构如下所示。
所有API网关配置的目录和文件名都以api_为前缀。这些文件和目录中的每一个都启用API网关的不同特性和功能,并在下面详细说明。
所有NGINX配置都以主配置文件nginx.conf开头。要读入API网关配置,我们在nginx.conf的http块中添加一个指令,该指令引用包含网关配置的文件api_gateway.conf(下面的第28行)。请注意,默认的nginx.conf文件使用include伪指令从conf.d子目录中引入基于浏览器的HTTP配置(第29行)。本博文广泛使用include指令来提高可读性并实现配置某些部分的自动化。
api_gateway.conf文件定义了将NGINX Plus公开为客户端的API网关的虚拟服务器。此配置公开API网关在单个入口点(第13行)发布的所有API,受第16到21行配置的TLS保护。请注意,此配置纯粹是HTTPS - 没有明文HTTP侦听器。我们希望API客户端知道正确的入口点并默认进行HTTPS连接。
此配置是静态的 - 各个API及其后端服务的详细信息在第24行的include伪指令引用的文件中指定。第27到30行处理日志记录默认值和错误处理,并在响应中讨论错误部分如下。
一些API可以在单个后端实现,但是出于弹性或负载平衡的原因,我们通常期望存在多个API。使用微服务API,我们为每个服务定义单独的后端;它们一起作为完整的API。在这里,我们的Warehouse API被部署为两个独立的服务,每个服务都有多个后端。
API网关发布的所有API的所有后端API服务都在api_backends.conf中定义。这里我们在每个块中使用多个IP地址 - 端口对来指示API代码的部署位置,但也可以使用主机名。 NGINX Plus订户还可以利用动态DNS负载平衡,自动将新后端添加到运行时配置中。
配置的这一部分首先定义Warehouse API的有效URI,然后定义用于处理对Warehouse API的请求的公共策略。
Warehouse API定义了许多块。 NGINX Plus具有高效灵活的系统,可将请求URI与配置的一部分进行匹配。通常,请求由最具体的路径前缀匹配,并且位置指令的顺序并不重要。这里,在第3行和第8行,我们定义了两个路径前缀。在每种情况下,$ upstream变量都设置为上游块的名称,该上游块分别代表库存和定价服务的后端API服务。
此配置的目标是将API定义与管理API交付方式的策略分开。为此,我们最小化了API定义部分中显示的配置。在为每个位置确定适当的上游组之后,我们停止处理并使用指令来查找API的策略(第10行)。
使用重写指令将处理移至API策略部分
重写指令的结果是NGINX Plus搜索匹配以/ _warehouse开头的URI的位置块。第15行的位置块使用=修饰符执行完全匹配,从而加快处理速度。
在这个阶段,我们的政策部分非常简单。位置块本身标记为第16行,这意味着客户端无法直接向它发出请求。重新定义$ api_name变量以匹配API的名称,以便它在日志文件中正确显示。最后,请求被代理到API定义部分中指定的上游组,使用$ request_uri变量 - 其中包含原始请求URI,未经修改。
API定义有两种方法 - 广泛而精确。每种API最合适的方法取决于API的安全要求以及后端服务是否需要处理无效的URI。
在warehouse_api_simple.conf中,我们通过在第3行和第8行定义URI前缀来使用Warehouse API的广泛方法。这意味着以任一前缀开头的任何URI都代理到相应的后端服务。使用基于前缀的位置匹配,对以下URI的API请求都是有效的:
如果唯一的考虑是将每个请求代理到正确的后端服务,则广泛的方法提供最快的处理和最紧凑的配置。另一方面,精确的方法使API网关能够通过显式定义每个可用API资源的URI路径来理解API的完整URI空间。采用精确的方法,Warehouse API的以下配置使用精确匹配(=)和正则表达式(〜)的组合来定义每个URI。
此配置更详细,但更准确地描述了后端服务实现的资源。这具有保护后端服务免于格式错误的客户端请求的优点,代价是正常表达式匹配的一些小额外开销。有了这个配置,NGINX Plus接受一些URI并拒绝其他URI无效:
使用精确的API定义,现有的API文档格式可以驱动API网关的配置。可以从OpenAPI规范(以前称为Swagger)自动化NGINX Plus API定义。此博客文章的Gists中提供了用于此目的的示例脚本。
随着API的发展,有时会发生需要更新客户端的重大更改。一个这样的示例是重命名或移动API资源。与Web浏览器不同,API网关无法向其客户端发送命名新位置的重定向(代码301)。幸运的是,当修改API客户端不切实际时,我们可以动态地重写客户端请求。
在下面的示例中,我们可以在第3行看到定价服务以前是作为库存服务的一部分实现的:rewrite指令将对旧定价资源的请求转换为新的定价服务。
动态重写URI意味着当我们最终在第26行代理请求时,我们不能再使用$ request_uri变量(正如我们在warehouse_api_simple.conf的第21行所做的那样)。这意味着我们需要在API定义部分的第9行和第14行使用稍微不同的重写指令,以便在处理切换到策略部分时保留URI。
HTTP API和基于浏览器的流量之间的主要区别之一是如何将错误传达给客户端。当NGINX Plus作为API网关部署时,我们将其配置为以最适合API客户端的方式返回错误。
顶级API网关配置包括一个定义如何处理错误响应的部分。
第27行的指令指定当请求与任何API定义都不匹配时,NGINX Plus会返回错误而不是默认错误。此(可选)行为要求API客户端仅向API文档中包含的有效URI发出请求,并防止未经授权的客户端发现通过API网关发布的API的URI结构。
第28行指的是后端服务本身产生的错误。未处理的异常可能包含我们不希望发送到客户端的堆栈跟踪或其他敏感数据。此配置通过向客户端发送标准化错误来进一步提供保护。
完整的错误响应列表在第29行的include伪指令引用的单独配置文件中定义,其前几行如下所示。如果首选不同的错误格式,并且通过更改第30行上的default_type值以匹配,则可以修改此文件。您还可以在每个API的策略部分中使用单独的include指令来定义一组覆盖默认值的错误响应。
有了这种配置,客户端对无效URI的请求就会收到以下响应。
在没有某种形式的身份验证的情况下发布API以保护它们是不常见的。 NGINX Plus提供了几种保护API和验证API客户端的方法。有关基于IP地址的访问控制列表(ACL),数字证书身份验证和HTTP基本身份验证的信息,请参阅文档。在这里,我们专注于API特定的身份验证方法。
API密钥身份验证
API密钥是客户端和API网关已知的共享密钥。它们本质上是作为长期凭证发布给API客户端的长而复杂的密码。创建API密钥很简单 - 只需编码一个随机数,如本例所示。
在顶级API网关配置文件api_gateway.conf的第6行,我们包含一个名为api_keys.conf的文件,其中包含每个API客户端的API密钥,由客户端名称或其他描述标识。
API密钥在块中定义。 map指令有两个参数。第一个定义了API密钥的位置,在本例中是在$ http_apikey变量中捕获的客户端请求的apikey HTTP头。第二个参数创建一个新变量($ api_client_name)并将其设置为第一个参数与键匹配的行上的第二个参数的值。
例如,当客户端提供API密钥7B5zIqmRGXmrJTFmKa99vcit时,$ api_client_name变量设置为client_one。此变量可用于检查经过身份验证的客户端,并包含在日志条目中以进行更详细的审核。
地图块的格式很简单,易于集成到自动化工作流程中,从现有的凭证存储生成api_keys.conf文件。 API密钥身份验证由每个API的策略部分强制执行。
客户端应在apikey HTTP头中显示其API密钥。如果此标头丢失或为空(第20行),我们发送401响应以告知客户端需要进行身份验证。第23行处理API键与地图块中的任何键都不匹配的情况 - 在这种情况下,api_keys.conf第2行的默认参数将$ api_client_name设置为空字符串 - 我们发送403响应告诉身份验证失败的客户端。
有了这个配置,Warehouse API现在可以实现API密钥身份验证。
JWT身份验证
JSON Web令牌(JWT)越来越多地用于API身份验证。原生JWT支持是NGINX Plus独有的,可以在我们的博客上验证JWT,如使用JWT和NGINX Plus验证API客户端中所述。
本系列的第一篇博客详细介绍了将NGINX Plus部署为API网关的完整解决方案。可以从我们的GitHub Gist仓库查看和下载此博客中讨论的完整文件集。本系列的下一篇博客将探讨更高级的用例,以保护后端服务免受恶意或行为不端的客户端的攻击。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~