此处应有背景

近几年微服务架构如日中天,微服务化亦是大势所趋,严选的微服务化改造也已初具规模,基于Sidecar模式的服务网格渐趋稳定,其基本架构如下:(图片引自网络) pic

数据面部分,Sidecar代理采用nginx,并基于nginx扩展,包括服务发现,负载均衡,健康检查等。其控制面为Consul管理平台。 同时部分sidecar功能,也被嵌入到tomcat容器或第三方Client中,如链路跟踪,流量采样等,其控制面为apolloY配置中心。 关于Sidecar的介绍,没有比原图更直观的了!(图片引自网络) pic

与此同时,作为微服务架构中不可或缺的组成部分:API Gateway,也就应运而生。

合适的才是最好的

根据活跃度、语言、支持功能、上手难易等,对开源社区(Tky,MicroGateway,Zuul,Kong等)进行比较分析。 除了网关基本功能之外,我们更关注于性能以及可扩展性,因此倾向于非Java的实现,同时考虑到入门门槛、后续的发展,最终锁定了Kong。 Kong的详细介绍,参考官方文档:https://konghq.com/kong-community-edition/。 Openresty部分,从原理到应用,可参看官方文档。

一切从源码开始

从官方Fork了当时最新版本0.2.3(截至本文书写时,官方已更新至1.0.0版本),参考编译安装手册,依次安装Openresty,Luarocks,Kong,PostgreSQL。除了LUA环境、Openssl依赖小有波澜,一切进展顺利,首个进程轻松启动。 良好的开始是成功的一半!实践证明,这里只是整个进度条的1%!之后我们优化了Openresty的依赖模块,标准化了环境变量的路径以及应用的安装路径,最终输出了严选API网关的编译安装手册以及自动化脚本。

大道至简,天下归一

在已有场景下,一个应用节点更新,首先需要到Consul平台进行下线(很nice),而另外还需要SA协助从入口Nginx调整域名的Upstream配置(很简陋)。一者,服务更新的复杂度高,再者,额外依赖了SA的操作。结果就是导致服务更新的笨重!因此,网关引入consul-module,集成Sidecar的服务注册发现功能,之后,不论访问方式如何,业务只需要关心Consul平台的配置即可,简单易行,皆大欢喜。 同时,已有Kong配置,缺少对API的有效标识,在严选Consul架构下,网关对单个Location进行有效的定义:产品名+服务名+接口名,一方面,将无意义的Location进行命名,方便记忆;另一方面,根据定义好的名字,可以快速检索配置。

物以类聚,分而治之

集群部署隔离

商业版提供了完整的管理平台,对集群、插件、监控等进行管理。而严选环境下,我们也需要根据网络环境、使用场景、入口业务进行集群区分,进而实现资源隔离! 根据网络环境,目前区分了:测试网关集群,内网网关集群,外网网关集群等; 根据使用场景,目前区分了:出口网关集群,ABTest网关集群,压测网关集群等; 根据入口业务,目前区分了:主站网关集群,活动网关集群,Openapi网关集群等; pic 如上图所示,实际我们先根据网络环境区分大集群,然后根据业务、场景再细分子集群。

接口访问隔离

  • 业务接口的访问:

依赖于身份验证插件,进行接口级别的租户信息验证。为此,我们扩充了租户管理,可以配置租户的验证策略,以及租户级别的频控等策略。

  • 管理接口的暴露:

仅支持本地IP访问,且只暴露监控数据的获取接口;

配置管理隔离

基于严选已有的权限中心,我们结合API网关的配置页面,细化了面向API网关的访问权限。

  • 用户:

可以走openpid进行登录的所有corp账号,创建是需要指定所属的角色;

  • 角色:

可以定制不同角色可见的模块,比如业务方只需要查看监控模块、插件配置,不可进行操作;

  • 群组:

API创建时,需要指定其所属群组,群组下可以添加具体的用户,此时,该用户只能看到该群组下的API配置信息; pic

如上图所示, 用户 – 角色 – API:操作权限控制 用户 – 群组 – API:API业务隔离

战战兢兢,如履薄冰

可维护

作为所有业务的总入口,一旦有风吹草动,那必然是一石激起千层浪!除了服务稳定性,我们把日常的运维工作作为重中之重!

  • 统计报表

多维度实时查看线上流量、响应错误码、响应时间、TCP链接数等,方便第一时间确认问题点。

  • 监控告警

基于实时平台,对异常日志、错误请求进行实时监控。 基于运维平台,对系统基础资源,包括CPU,内存,磁盘等进行实时监控。 一旦出现异常及时告警,目前我们依赖了锦衣卫以及邮件进行相关的告警通知。 pic 由于网关数据流量大,在此仅对异常请求数据进行入库,目前使用Elasticsearch进行存储,方便问题的定位分析。

可管控

Kong自身的配置方式,没有权限控制,没有历史跟踪,简单粗暴,不适用于生产环境。因此我们再现有配置基础之上,包装了基于Mongodb的配置管理,支持历史版本的回溯,版本回退,版本比较等功能。

  • 引入工单协同系统

有效的与其他工单系统配合,实现完整的配置申请、审批、执行、审核等操作,在流程上对配置更新进行把控。

  • 扩展灰度发布功能

可以在指定节点运行更新内容,将配置出错的影响降到最低。

插件!插件!插件!

Kong在Openresty上做的最大贡献,莫过于对插件的规范,插件支持热插拔,以及灵活的动态配置。在此框架下,可以从心所欲,业务心有多大,我们就可以做多大!

  • 公共插件

目前扩充了频控插件,路由插件,以及拦截器,请求/响应转换插件等等。

  • 定制插件

前期帮助业务定制了加解密插件,超时重试插件,ABTest分流插件等。随着接入业务的扩充,我们将插件开发进行开放,由业务来实现插件,向Serveless迈进了一小步! pic

门户虽开,恶人勿近

网关作为所有访问的大门,我们在这个大门上装上了扫描器WAF(Web Application Firewall),用于识别是来访者是正常用户请求,还是恶意的攻击。对于恶意的访问,可以提前拒绝,确保应用服务器资源的有效利用。 WAF以插件的形式嵌入到调用链中,支持匹配规则、触发策略的动态配置。

  1. 规则管理

pic 如图所示,将规则分成两级进行维护,方便规则的检索、统计等。

  1. 触发策略

具体触发策略包括拦截、流量二次清洗、蜜罐等等。

  1. API定制

API开启WAF插件之后,可以在此进行规则以及触发策略的定制,方便统一的管理。

Just Run!

至此,终于可以发布我们的第一个线上版本(命名为Yanxuan-Ianus)!然而,要SA每次到线上机从Compile开始,势必会被吐槽至死!

  • RPM包 采用RPM包的方式发布,针对不同的环境,制作相应的RPM包,免去线上环境配置修改的烦恼。 如:首次部署,openresty更新,nginx更新,module更新

  • GIT-CI 实际操作过程中,频繁的更新包版本,仍会给SA带来不少的麻烦,也降低了部署效率。 因此,我们额外增加了GIT-CI部署方式,在仅涉及LUA脚本,配置文件的更新时,直接走CI方式发布即可。 同时,鉴于LUA脚本热加载特性,如果只是更新脚本,则通过Reload方式加载,可以支持实时更新,进一步简化更新流程。 如:Kong更新,插件更新,配置更新

线上部署发现,PostgreSQL操作均通过线上节点执行,而线上节点暴露给外部,存在安全风险,因此针对线上DB的操作,额外引入pgproxy服务,该模块只支持对PostgreSQL的操作,且只允许管理平台访问,进而保证DB的安全性。最终,

  • 网关对外依赖如下:

pic

  • 网关部署方式如下:

pic

  • 网关管理平台功能如下: pic

骡子 or 马

系统的轮子转起来之后,接下来我们就开始往里面添加各种需要加工的材料,也就是将各个业务的流量导入到网关,让网关真正开始做事。 整个流量导入的过程是相当漫长的,从七月份到如今,我们把测试环境、内网环境的域名访问的90%流量均导入到了网关,同时外网环境的主要入口的流量也导入到网关。 在整个导流的过程中,顺便将业务管理进行了规范化,统一注册到了Consul,在此,非常感谢各个业务的密切配合。 而双十一期间日最高访问量达到了15亿,最高访问量为400w/min。系统表现稳定。同时,由于网关的动态配置特性,结合Consul的标签,很好的完成了服务分流功能。

基于严选API网关,我们搭建了面向不同业务的集群:

  • 开放平台: 作为OpenApi的接入层,规范接口访问,支持租户管理,身份验证,数据加密,流量控制,访问审计等。

  • 门户网关: 替换现有的门户网关,方便门户新增业务门户入口。

  • 出口网关 当前提供给供应商使用,统一各个业务对外访问的出口,并可定制除业务功能外的扩展功能,如超时重试机制。

  • 活动网关 替换活动自建的Nginx,活动本身特性决定,业务访问会有较多的静态页面,将页面直接缓存到网关侧,提升性能。

  • 活动ABTEST平台 利用网关的分流及灰度策略,做为Ab压测的入口,实现AB分流功能。

此处应有总结

目前严选API网关的部署架构已基本成形,而流量的导入工作仍在持续进行。随着业务的不断状态,网关的形态也会不断分化。 但是,这一切不会止步于网关!一方面,我们会引入更多的网关形态,另一方面,基于网关的基础设施,我们希望产出更多其他业务设施!