DJI(大疆创新)http api服务网关

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/iteye_13806/article/details/82638275

DJI(大疆创新)http服务网关系统是用于对http服务进行治理的系统,支撑微服务的落地和开放平台open api的接入。支持跨多机房的服务路由,通过该系统可以对调用方进行身份认证、服务授权&鉴权、服务流控、服务降级、调用度量数据统计分析、服务依赖视图等。

整个系统架构如下图,分为三大部分:api网关、网关控制台、度量数据采集分析(这个未在图中体现)。

 

1.api服务网关

api服务网关是一个java web应用,域名:apigw.xxx.com。api服务网关类似企业应用集成中的ESB,为服务调用提供一个统一的访问点,支持服务流控和服务异常情况下的fail-fast。

服务网关实现可采用的技术和组件:

A)mule、camel、servicemix/JBI等中间件

B)nginx+lua脚本、OpenResty

C)spring integration

考虑到代码的维护性和开发技能,没有使用这些技术。

 为了提高性能和并发,全程采用异步方式,上图中的拦截器(过滤器)、servlet(包括servlet异步io)http client均为异步。

2.网关控制台

 网关控制台是一个java web应用,域名apiadmin.xxx.com。提供domain管理、应用管理、服务授权、服务监控、统计和度量数据展示、查看服务全局视图等功能。 

 

服务消费者和服务提供者都要在网关控制台进行应用注册,控制台为每个应用分配应用id(appId唯一)和应用密钥(appSecret)。注册时需要提供的信息:应用名称、应用描述、应用负责人、负责人手机&邮箱。

 

3.服务注册

http服务可用任意语言实现,如ruby、php、java。服务提供者要向服务网关注册其提供的http服务。

服务注册接口urlhttp://apigw.xxx.com/registry/services,http方法PUT

服务提供者启动后,调用该接口将其服务注册到服务注册中心,服务注册请求http bodyjson字符串,格式如下:

{“appId”:”${appId}”,

“httpServices”: {“endpoint”:[“http://${ip}:${port}?urlPrefixPattern=/xxx”,…],

services”:[ {“resourceName”:”${resourceName}”,

                        “version”:”${version}”

urls”:[{“name”:”${name}”,”url”:”/xxx/xxx”,”method”:”GET”,

”serverTimeout”:${ms}},…

]

},…

  ]

}

}

说明:appId为服务提供者的应用id

endpointhttp服务地址,urlPrefixPattern是可选的,为url前缀模式,对java应用,就是servlet url pattern的前缀匹配模式字符串,urlPrefixPattern/开头,例如/api

endpoint示例["http://58.1.1.1:8080","http://59.2.61.34?urlPrefixPattern=/api"]

services是包含的http rest资源服务,每个rest资源都有一个resourceName,在整个api服务网关中唯一。每个资源下面可有多个urlOperationurl+http method的组合,url+http methodresourceName内唯一)的组合,urls中的内容就是描述这些组合,其中的name是功能方法的人性化名称,url/开头,如果根据url中的pathhttp method已经可以唯一确定一个urlOperationurl可以没有query string,否则要在url中加入queryStringkey来限定该urlkey放在[]中,如果有多个key,用,分隔,例如/users?qs=[name],name就是queryString中的key。如果url中有模板参数,需要将模板参数放在{}中,例如/users/{name},可以使用/user/abc/user/u657来匹配该模板。模板参数缺省是字符串,如果要限定是整数,可以在模板参数后面加入@d,例如/users/{id@d},这样只能使用/user/123之类的url来调用。对java spring mvcurl就是controller @RequestMapping中的value值。Methodhttp方法名称,可取GETPUTPOSTDELETEHEADserverTimeout是服务提供者推荐的调用超时时间(不考虑跨机房调用延时),单位是毫秒。

 

 

服务注册请求头:

Content-Type: application/json; charset=utf-8

register Time:${utc秒数}

registerToken:${token}

 

registerTime头是注册时的utc秒数。

registerToken用于身份验证,HMAC-SHA1加密,base64(HMAC-SHA1(http body+ registerTime)),密钥为应用注册时分配的appSecret

 

服务注册response

注册成功返回200 status codebody{"result":"success","gwToken":"xxxxxxxx"}

gwToken用于api服务网关调用服务提供者时的身份认证,服务提供者保存该token

 

注册失败返回400 status code, body{"result":"failed","errormsg":"xxxxxxxx"}

 

4.服务心跳 

服务提供者需要提供一个http url,服务网关会周期性访问url来检测服务提供者的存活和健康状况。如果连续三次都调用超时或失败则将该服务提供者设置为offline。在offline状态,连续两次调用成功,则切换为online状态。

 

5.服务消费者的服务调用

服务消费者向api网关发起http请求,调用的url为http://apigw.xxx.com/gwapi/${服务提供的url},例如

http://apigw.xxx.com/gwapi/users/2356api网关收到请求后进行认证鉴权等处理,再由异步httpclient路由转发到服务提供者,httpclient收到服务提供者的响应后,由异步servlet将响应转发到服务消费者。

调用http

服务消费者在调用服务时,需要如下http:

invokeId:每请求调用id,通常是uuid生成,在同一应用实例中唯一。

consumerAppId:服务消费者的appId

resourceName:资源名称,主要是为方便进行消息路由。用请求urlhttp methodGET/POST/PUT/DELETE)也可进行路由。 

accessToken用于服务消费者的身份认证。

 

accessToken的获取

accessToken的有效期为3小时(可配置),其获取流程如下:

 

 服务网关的对服务请求的路由转发

收到服务消费者的服务请求后,服务网关结合服务的健康状况采用round-robin的策略来转发请求到后端的服务节点。

以一个例子为例来描述服务网关的路由转发。

假设有个rest资源服务名称为user.account,其所在endpoint[”http://23.34.5.6:8080?urlPrefixPattern=/api”,” http://23.34.5.7:8080?urlPrefixPattern=/api”],该资源有个url:/users/{userId},采用GET方法来调用,功能是获取用户账号信息。

服务消费者应用idstore,它调用该功能的http请求如下:

GET /gwapi/users/2356 HTTP/1.1

Host:apigw.xxx.com

Connection: keep-alive

invokeId:1acd-3acb-bca2-ffcc

consumerAppId:store

resourceName: user.account

accessToken: 4fcb-89d3-cbde-aef7

api服务网关收到该请求后,会对该请求进行认证鉴权,通过后对该调用进行路由,假设路由选取的endpointhttp://23.34.5.6:8080?urlPrefixPattern=/api,则调用后端服务时的urlhttp://23.34.5.6:8080/api/users/2356.

服务网关调用该服务的http如下:

GET /api/users/2356 HTTP/1.1

Host:23.34.5.6:8080

Connection: keep-alive

invokeId: 1acd-3acb-bca2-ffcc

consumerAppId: store

resourceName: user.account

gwToken: 85a7-99df-bc11-653d

 

转发请求时去掉了accessToken头,增加了gwToken头,gwToken是服务注册时由服务网关生成的,前面对此有说明。服务提供者在注册时,要保存服务网关返回的gwToken,以便用于验证服务网关转发的请求。

 

api网关处理请求失败时的响应

当拦截器验证失败时,网关不会将请求转发到后端的服务提供者,而是直接返回响应。

请求不合法时的响应:400 Bad Request。请求中没有规定的http(invokeIdconsumerAppIdresourceNamegwToken)

 

认证鉴权失败时的响应:返回http status code 401 Unauthorized。具体的原因是consumerAppId未注册、accessToken不存在或失效或非法、resourceName非法、服务操作未授权。

流控未通过时的响应:返回http status code 503 Service Unavailable(flow control)

路由失败时返回的响应:返回http status code 503 Service Unavailable(gw route)。具体原因是没有找到可用的endpoint(例如后端服务全部down)。

 

请求超时时的响应:504 Gateway Timeout(gw)

 

 

6.领域模型


 

7.失败重试

这里的失败重试是指服务提供者返回http 5xx、或服务提供者处理超时、服务提供者返回io exception异常时的重试。当重试时,网关会重新转发。是否重试可以在控制台中对服务授权时,可以设置对urlOperation是否重试,当进行重试转发时,会增加一个http头retryTimes,其值为重试次数。

 

8.日志采集处理

   服务网关部署在多个机房中,日志采集使用flume,在每个机房中都部署有flume。服务网关(GW)使用log4j flume appender将日志发送到本地flume,最后汇聚到杭州机房中的flume。

   

 

   

9.系统部署

为了保证高可用和负责均衡,网关控制台和api服务网关均为多机部署,前面是负载均衡器LVS+keepalived。

10.可选方案

上面的方案是中心化的http服务治理方案,http服务调用要经过api服务网关转发,另一种是去中心化的方法(先前文章中有介绍),服务消费者直接调用服务提供者,前者对目前的代码改动较少,后者改动较多,但性能和可靠性更高。



 

 

服务消费者在调用服务之前,要通过服务发现找到可调用服务的endpoint,并到服务中心进行服务授权,获得服务调用token,在调用请求头中带上该token,服务提供者收到请求后,对该token进行认证鉴权。

展开阅读全文

没有更多推荐了,返回首页