http api服务网关

标签: http api 服务 | 发表时间:2015-07-30 13:29 | 作者:顽石
出处:http://www.iteye.com

http服务网关系统是一个对http服务进行治理的系统,通过该系统可以对调用方进行身份认证、服务授权许可(许可调用方使用某个http服务)、服务鉴权(是否能调用http服务)、请求流控、失败恢复、调用度量数据统计分析、服务依赖视图等。

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

 

1.api服务网关

api服务网关是一个java web应用,域名:apigw.xxx.com。api服务网关类似企业应用集成中的ESB,为服务调用提供一个统一的访问点。

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

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

B)nginx+lua脚本、OpenResty

C)spring integration

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

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

2.网关控制台

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

 

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

 

3.服务注册

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

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

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

{“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;

endpoint为http服务地址,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服务网关中唯一。每个资源下面可有多个urlOperation(url+http method的组合,url+http method在resourceName内唯一)的组合,urls中的内容就是描述这些组合,其中的name是功能方法的人性化名称,url以/开头,如果根据url中的path和http method已经可以唯一确定一个urlOperation,url可以没有query string,否则要在url中加入queryString的key来限定该url,key放在[]中,如果有多个key,用,分隔,例如/users?qs=[name],name就是queryString中的key。如果url中有模板参数,需要将模板参数放在{}中,例如/users/{name},可以使用/user/abc或/user/u657来匹配该模板。模板参数缺省是字符串,如果要限定是整数,可以在模板参数后面加入@d,例如/users/{id@d},这样只能使用/user/123之类的url来调用。对java spring mvc,url就是controller @RequestMapping中的value值。Method是http方法名称,可取GET、PUT、POST、DELETE、HEAD。serverTimeout是服务提供者推荐的调用超时时间(不考虑跨机房调用延时),单位是毫秒。

 

 

服务注册请求头:

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 code,body为{"result":"success","gwToken":"xxxxxxxx"}

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

 

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

 

4.服务心跳

 

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

心跳检测也可使用etcd集群来实现。

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

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

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

调用http头

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

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

consumerAppId:服务消费者的appId

resourceName:资源名称,主要是为方便进行消息路由。用请求url和http method(GET/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方法来调用,功能是获取用户账号信息。

服务消费者应用id为store,它调用该功能的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服务网关收到该请求后,会对该请求进行认证鉴权,通过后对该调用进行路由,假设路由选取的endpoint为http://23.34.5.6:8080?urlPrefixPattern=/api,则调用后端服务时的url为http://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头(invokeId、consumerAppId、resourceName、gwToken)。

 

认证鉴权失败时的响应:返回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.系统部署

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

9.可选方案

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



 

 

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



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [http api 服务] 推荐:

http api服务网关

- - 互联网 - ITeye博客
http服务网关系统是一个对http服务进行治理的系统,通过该系统可以对调用方进行身份认证、服务授权许可(许可调用方使用某个http服务)、服务鉴权(是否能调用http服务)、请求流控、失败恢复、调用度量数据统计分析、服务依赖视图等. 整个系统架构如下图,分为三大部分:api网关、网关控制台、度量数据采集分析(这个未在图中体现).

RedBridge: Redis for HTTP API[推荐]

- yonghai - 运维进行时
       RedBridge 是一款基于redis 的 HTTP API. 使用LUA 直接跟redis 交互. (类似数据库的存储过程) 高效的实现复杂的业务逻辑. 项目网址:http://code.google.com/p/redbridge/. RedBridge 具有以下特征:. 使用C+epoll 编写的Web Server,支持HTTP GET操作.

Android中HTTP相关的API

- - 技术小黑屋
Android中大多数应用都会发送和接受HTTP请求,在Android API中主要由两个HTTP请求的相关类,一个是HttpURLConnection,另一个是Apache HTTP Client. 这两个类实现的HTTP请求都支持HTTPS协议,基于流的上传和下载,可配置超时时间,IPv6和连接池.

Android 平台 HTTP网速测试 案例 API 分析

- - CSDN博客推荐文章
作者 : 万境绝尘  . 工信部规定的网速测试标准 : 除普通网页测速采用单线程外,用户宽带接入速率测试应使用多线程(多TCP连接)HTTP下载进行测速,测试中使用的线程数量为N(N≥4). -- 建立连接 : 用户终端设备发起测试请求后,与测速平台建立 N 条 TCP 连接,并在每一条 TCP 连接上发送HTTP[GET]请求发起一次测试过程.

服务间通信之Http框架

- - CSDN博客推荐文章
2.jersey代理连接池. 1.1 java原生HttpURLConnection. 这个用的不多,在正式项目中几乎没有用过,写一些小的demo的时候偶尔用过,使用的原因更多是当时懒得再引入其他第三方的http框架了,用法如下:. 不多说,用法还是挺复杂的,简单的请求甚至需要数十行才能完成,并且不易于理解,当时写完调试了半天才通,挺后悔用原生的HttpURLConnection来进行当时功能的测试,感觉比我当时写的一个http-server还要麻烦,在正式的项目中一般不会用到原生http请求类.

comet 服务器 icomet 提供 Android API

- - 开源中国社区最新新闻
支持百万连接和 comet/push 服务器 icomet 日前提供了可用于 Android 移动开发的 Java API - iCometClient4j, 用于实现手机上的消息推送功能. 结合 icomet 的 HTTP endless chunk 模式, 可提供节省电池的长连接服务.. iCometClient4j项目地址: https://github.com/DuoZhang/iCometClient4j/.

实现了一个比nginx速度更快的HTTP服务器

- jyf1987 - 博客园-clowwindy的杂草牧场
在上次的FreeBSD和linux的nginx静态文件性能对比测试 后,我萌发了自己动手做一个简单的Web Server来搞清楚nginx高性能背后的原理的想法. 最后成功实现了一个基于epoll的简单的HTTP服务器,实现了200,404,400,304响应,并且性能比nginx高了一点点. 本文主要介绍这个HTTP服务器的原理和设计过程.

Comet:基于 HTTP 长连接的“服务器推”技术

- - k1121
转自:https://www.ibm.com/developerworks/cn/web/wa-lo-comet/. Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻. 任何 Ajax 的新信息都能在这里找到. 订阅 Ajax 相关文章和教程的 RSS 提要.

怎么用API网关构建微服务|架构

- - 企业架构 - ITeye博客
转于http://www.tuicool.com/articles/bMnEbmv. 当选择将应用程序构建为一组微服务时,需要确定应用程序客户端如何与微服务交互. 在单体应用程序中,只有一组(通常是重复的、负载均衡的)端点. 然而,在微服务架构中,每个微服务都会暴露一组通常是细粒度的端点. 在本文中,我们将讨论一下这对客户端与应用程序之间的通信有什么影响,并提出一种使用API网关的方法.

Api Blocking

- - xiaobaoqiu Blog
4.RateLimiter实现限流. 接口限流是保证系统稳定性的三大法宝之一(缓存, 限流, 降级).. 本文使用三种方式实现Api限流, 并提供了一个用Spring实现的Api限流的简单Demo, Demo的git地址: https://github.com/xiaobaoqiu/api-blocking.