网关平台架构分享

概述

由于物种起源、历史变革等不可控因素,我们的后端服务有A、B平台之分。A平台开发之初,对外出口就设定在网关上,一直被叫做A网关。B平台的架构大致是,后端各个业务系统,服务治理、RPC,使用dubbox,对外有两个web 服务层应用(controller层),分别对应车机和手机端入口,通过注册中心获取各个业务服务提供者信息,rpc调用之。后端服务层应用,其实是没分车机和手机的。再上面就是nignx了,做反向代理和web服务层的负载均衡。B的服务架构优缺点比较明显,就说说主要的缺点了(为后面说网关做铺垫),web层的两个应用,需要依赖后端对外提供服务的所有应用,耦合度太大,不容易扩展;各个业务开发小组都会去开发和维护这两个应用,导致混乱和相互干扰;并且在这层的处理逻辑不统一,有简单的参数校验、也有写了业务处理逻辑;每次系统更新上线,基本是每个小组负责人都要通宵。目前的情况是,B平台在做服务改造(牛X的说法,微服务改造);首先,接入网关系统,丢弃掉web层的两个应用,这样就省去了都去开发维护这两个应用的工作,业务开发人员能更集中关注自己的独立业务服务;网关通过泛化调用,与各个业务服务没有耦合、强依赖。上线流程也能做到各服务独立、不限时段上线。这样统一了网关这个出入口,也是为了后面平台上云,服务其他车厂提供能力。
以后就没有A网关啦,只有大斑马网关。吼吼哈哈。。。

特点

  • 高扩展性,可以任意增加部署节点;
  • 高稳定性,线上环境持续运行,无任何异常出现;
  • 高性能,这是网关最基本也是最重要的特性;
  • API动态开放、测试、发布;
  • 实时的API、车架号调用情况统计报表展示
  • 支持接口灰度发布,根据灰度策略,动态路由调用;
  • 熔断、超时保护,异常调用量达到设置的比率时,会开启熔断机制;

架构图

网关的主要功能在于统一对外调用的出入口,达到对外部请求的统一安全校验、认证、参数校验、对内部服务的发现、路由、负载均衡调用,统一封装格式化输出等。同时网关会记录每个调用请求的信息,包括API名称、版本号、入参、输出、总的消耗时间、RPC消耗时间等。每条记录信息会发送到MQ,由流计算统计功能处理,得到准实时的API调用情况报表。

网关平台架构分享

对照上图,图中连线上的序号表示在逻辑上的先后;没序号的为通过MQ消息来异常处理的逻辑
(1) 部署开发完成的微服务应用,成功部署后,开放的服务接口信息会注册到服务注册中心;
(2) 开发人员在网关管理台,录入需要开放的API信息,网关管理台服务端会保存开放的API元数据信息到数据库;
(3) 网关系统会定时到数据库加载API元数据信息到网关服务的内存中,会涉及内存中API信息的增、删、改。目前API数目在600左右,所以这样定时全量加载不会有性能问题。后面API数目增长很大的话,可使用外部缓存或者网关控制台有API的增删改时通过mq消息通知来单条操作;
(4) 网关系统根据加载的API元数据信息,初始化并缓存该API对应的RPC服务引用;同时通过服务注册中心,监听和刷新服务提供者注册在注册中心的信息;
(5) 终端通过http/https请求到网关,网关根据参数协议解析请求参数,再做权限校验、安全认证、参数校验等处理;
(6) 根据调用的API信息,路由到具体的后端服务,进行rpc;对捕获的各种异常,做对应的解析,得到异常码和异常信息;对调用结果做格式化输出(json/xml),返回终端;
(7) 网关对每个外部调用都会记录该次调用的信息,包括API名称、版本、入参、请求时间、返回时间、rpc消耗毫秒数、总消耗毫秒数、请求IP、服务端IP、异常码等;记录信息会通过异步方式发送到MQ;

Storm流计算服务通过拉取MQ中的每条调用信息记录,做实时的统计,维度包括每日总调用量、总异常调用量、业务异常调用量、服务异常调用量,API、appKey、车架号维度的统计基本相同,增加异常调用的异常码和对应的异常数量。

网关管理台服务端也会去拉取MQ中的每条调用信息记录,批量存储到odps,可做离线分析。
网关管理台的主要功能有,API录入、API开放管理、API测试、API批量测试、API文档、API调用监控报表等。

内部结构图

网关集群部署,相互独立。通过前端负载均衡服务,对外提供服务。网关服务内部主要逻辑模块有网关上下文、请求上下文、调用器、熔断器、调用链数据采集等组成。

网关平台架构分享

网关支持不同的后端微服务平台,在录入API时,可以选择不同的服务协议。初始化网关上下文时,根据配置开关,确定是否加载对应的微服务平台环境配置(Env)。不同的Env对应不同的调用器(IInvoker),不同的调用器,有自己的前后处理器链(PreHandler、AfterHandler)。这样就能做到针对不同的后端平台服务,做不同的调用前后逻辑处理。

网关的熔断器通过Hystrix实现,主要关注的配置项有如下几个:
1) 对依赖调用隔离策略,使用信号量隔离。信号量使用300;
2) 熔断后,允许再次尝试请求的间隔毫秒数;使用3000毫秒;
3) 10秒内失败请求量占总请求量(大于20)的百分比大于50%时,开启熔断;失败请求包括服务异常、超时、超信号量拒绝;
4) 调用后端服务,超时时间毫秒数默认为5000毫秒;该配置项在API的管理页面可修改,实时生效;

Hystrix内部对每个Command的配置做了缓存,防止每次调用时,都要去初始化和加载各个配置项。针对第4项,网关做了对应的改造,为了使某个API的超时时间修改能实时生效,网关增加了类来继承Hystrix的HystrixPropertiesStrategy类,重写了类中的getCommandPropertiesCacheKey方法,该方法返回的字符串即为缓存Command配置的key。重写后返回的key由API的key加上超时时间组成。这样超时时间改变后,能重新加载。

性能

网关初始化时,通过上下文,缓存了所有依赖的对象或资源。对API元数据和rpc服务引用,采用初始化时缓存,后台线程定时刷新;对服务引用对象ReferenceService,其实缓存的是他的包装类ReferenceServiceWarp,该包装类内部持有ReferenceService和一个AtomicInteger类型的计数值。某个ReferenceService对象被几个API引用,该计数值就为几;当计数数值为0时,该ReferenceServiceWarp对象就可以被注销回收了。ReferenceService与API是一对多的关系,就如一个服务接口类包含多个方法一样的道理。
外部请求进来,在网关的处理逻辑中不涉及数据库操作、外部缓存交互等;主要的性能瓶颈有两个地方,一个是用户认证和权限校验接口,另一个是后端服务业务接口;
针对后端业务接口,需要优化处理逻辑,对依赖调用需要设置超时时间;对热点接口,还可以增大dubbo线程池的线程数。
测试同事对网关做过很多次性能以及稳定性测试,下面列出一组单机性能测试数据,
200并发,TPS:6537,平均响应时间:31.65ms,网关部署硬件:4核 8G
以上的测试结果,是在后端业务接口,无复杂逻辑和耗时操作的情况下的。所以最后的瓶颈在施压机上。

安全

安全性方面,目前网关做的有以下几个方面:
1)https调用;
2)对于指定需要授权的API,调用时需要传入公共参数token,网关做token有效性验证;
3)签名校验,每个外部调用都需要带上公共参数sign,网关做签名串sign校验。要通过网关接入后端服务能力接口,需要在第三方开发者系统里申请和创建应用,每个应用会分配对应的appKey和appSecret。签名串就是通过入参、appKey、appSecret,并根据一定的规则生成得到;
4)时间戳,每个调用url有效性为生成该url时间的前后10分钟以内;

B平台服务为后接入,并且车机和手机端调用方式和参数已不可能更改;所以对B服务接口调用时有效性和权限等的校验,网关委托给一个专门的服务接口,该接口会做token验证、用户和车架号关系验证、是否车主调用验证等。

最后

目前整个网关系统已作为后端基础服务,为各个业务应用对外提供稳定的能力输出,在业务服务的开发流程中,网关管理台也提供有力支撑,包括接口测试、调用监控、异常信息查看等;
下一篇会列出网关的主要一些类图,方便理解。

上一篇:Flink 生态:一个案例快速上手 PyFlink


下一篇:Leetcode——500. 键盘行(Java)