1.1 网关简介
随着微服务架构的流行,API网关逐渐进入人们的视野,并且越来越受到欢迎。在微服务体系架构中,我们将应用程序划分为多个低耦合的服务。每个服务都具有特定的功能,并交给不同的团队维护。尽管微服务具有许多优势,比如程序易于开发、维护和部署,将大团队拆分成小团队利于敏捷实践落地等,但是也带来一些问题,最为直观的就是由于接口过于繁杂,客户端难以快速、安全地访问到所需的信息。
API网关的出现解决了上述问题,它可以充当调用这些微服务的客户端的中央入口。客户端统一发送请求到网关层,再由网关层进行路由转发,使客户端访问接口的复杂度大大降低。当然现代API网关的作用已不仅仅局限于此,更多高度抽象的通用功能都由网关层进行统一处理。网关层随着系统架构升级逐步演化,在整个系统架构中的位置也变得愈发重要。
注意
我们在网络上还能搜到关于网关的更多定义,比如网关(Gateway)又称网间连接器、协议转换器。网关默认在网络层以上实现网络互联,是最复杂的网络互联设备,仅用于两个高层协议不同的网络互联。网关既可以用于广域网互联,也可以用于局域网互联。
此处定义的网关更接近于底层,偏向网络基础协议,而本书中讨论的网关特指API网关,是软件架构中的中间层,偏向于应用和业务需求。
1.1.1 网关的由来
API网关层的兴起离不开微服务。微服务的概念最早在2012年提出。在Martin Fowler等人的大力推广下,微服务在2014年后得到了大力发展。在微服务架构中,有一个组件可以说是必不可少的,那就是微服务网关。微服务网关具有负载均衡、缓存、路由、访问控制、服务代理、监控、日志等多项功能。API网关在微服务架构中正是以微服务网关的身份存在。
同时,由于企业间信息交流和共享变得日益频繁,企业需要将自身数据、能力等向外开放,通常以接口的方式向外提供,如淘宝开放平台、腾讯的QQ开放平台和微信开放平台。开放平台的引入必然涉及客户应用接入、API权限管理、调用次数管理等多项功能的完善,此时需要有一个统一的入口对它们进行管理,这也正是API网关出现的缘由。
1.1.2 网关的作用
笔者所在公司曾经开发过一个基于OpenResty的定制化网关。下面我们通过这个案例一起来了解一下网关层的功能。网关系统架构如图1-1所示。
该架构中网关层统一接收来自外部的流量,然后转发到内部系统。这些流量具体可以划分为两个部分,一部分统称为内部流量,主要是公司网页端应用、移动端App、微信小程序等终端发送的请求。这些应用都是公司内部研发的,可以理解为受信流量。另外一部分统称为外部流量,包括一些外部商户的业务调用以及公司对外开放的一些OpenAPI接口调用。网关层对这两部分流量的处理方式大致相同,当接收到外部请求后,首先会对接口做一些基本校验,接下来会进行解密、验签操作。这里内外部流量的处理方式会稍有不同:内部流量采用了公司内部约定的加解密方案,由网关层统一处理,流程比较简单;外部流量的处理方式相对复杂,因为每家公司使用的加解密方案和策略不同,在开发联调过程中具体使用哪家公司的方案尚未可知,这样网关层抽象处理加解密的能力就被大幅度限制了。笔者所在公司最终选择的解决方案是对外提供一套可以与公司网关层匹配的SDK。由于笔者所在公司使用的是Java技术栈,最后SDK以Jar包形式提供。在与外部公司的联调过程中,如果对方公司愿意使用我们的SDK包,那么网关层就可以发挥加解密的作用;如果对方公司因为语言栈不同而无法接入,或者对方公司没有采纳我们的SDK包,那么网关层就仅完成流量转发,加解密功能将留到业务侧实现。
图1-1 网关系统架构
注意
这里可能存在一个误解,即SDK包与公司底层技术栈语言关系并不大。加解密的算法本身是通用的,SDK包可以用各语言栈都实现一遍,只是各家公司技术资源有限,且大多是中小型公司,实现业务需求所需的时间已经很紧迫,只能挑选实现成本最低的编程语言编制SDK,或者挑选当前环境下使用者较多的语言栈优先实现。
在完成解密和验签之后,网关层就会根据自定义的路由匹配规则,将请求转发到对应的后端服务。在转发请求过程中,网关层还会在请求参数或者请求头中塞入一些框架层或者业务侧所需的自定义参数。这些参数有些会影响程序执行结果,有些是为了做业务统计,具体的实现细节可以根据实际需求做定制。
读者看到这里可能会觉得网关层本身并没有什么特别之处,仅仅是一个流量转发的中转站,处理了一些加解密、验签问题。在日常开发、部署过程中,这些问题可能仅需运维人员手动处理,或者添加一台Nginx服务器就可以完美解决。加解密的步骤完全可以放在业务侧实现,网关层无足轻重。
确实,如果我们身处一家业务功能极其简单的创业公司,或者公司规模很小,业务场景没有那么复杂,技术面主要以功能代码为主,那么这个想法是完全正确的。但是随着公司不断壮大,业务形态越来越复杂,系统从单体应用迁移到微服务架构,网关层的重要性越发凸显。如果没有高度可定制化的网关层组件,系统瓶颈马上就会显现,小则影响生产环境服务稳定性,大则影响整个研发、交付流程,大大影响产品迭代效率。
注意
现代软件工程体系已经相当完善,研发人员工作模式也早已区别于之前陈旧的开发模式,不再只是写好手头上的代码即可,而是已经参与到产品迭代的方方面面。敏捷思想也不再是换汤不换药的一纸空谈,技术驱动+管理工具的提升正在切实可行地提高软件工程的研发效率。当今环境下,技术架构中的每一环都不可或缺,木桶理论的短板效应尤为明显,这里我们其实不仅强调了网关层的重要性,也再度重申了每一个中间层都非常重要。
这里笔者分享一些在真实开发场景中,如果没有统一的网关层,或者网关层不完善带来的严重问题。
·网关层在整个系统架构中处于门面位置,是系统中的流量中枢。所有的请求都最先流入网关层。网关服务器每天需要面对千万级,甚至亿级的流量冲刷,包括活动期间瞬时爆发的流量洪峰。网关层的健壮性与稳定性对于整个系统的重要性不言而喻,如果网关层发生宕机或者服务不可用,后果可想而知。
·微服务架构思想在现代系统架构设计中已经全面铺开,不仅大公司已经有了很好的实践方案,中小公司也开始纷纷效仿做架构升级。在落地过程中,无论是技术栈升级变迁,如PHP迁移到Node或Go,还是引入BFF(Backend For Frontend)层做服务聚合中间层等,都离不开网关层的支持。
·再回到之前的加解密和验签问题,读者会发现笔者所在公司之前给出的解决方案并不尽善尽美。除加解密之外,鉴权、黑白名单管控等一些零散的安全配置定制化需求也非常多,但在实际开发过程中,留给研发人员开发调试的时间极为有限。更重要的是,每次更新网关层代码不能影响到生产环境的实时流量,这又给网关层的运维带来相当大的挑战。
·微服务架构将大型应用程序拆分成小型的独立功能,极大地提高了研发、部署效率,但带来的问题是每个独立小应用需要各自实现日志管理、限流熔断、服务注册发现等众多通用功能。读者可能会想到使用统一的底层架构封装来解决问题,但如果微服务架构本身是跨多语言栈的,就需要多套底层框架同时支持,之后的框架迭代也需要同步进行,这带来的研发成本是巨大的。
除上述几点外,缓存、监控、动态路由配置等一系列问题也有待解决,而且这些仅仅是技术层面暴露出来的可预知风险点。如果我们带着DevOps理念重新看待现在的产品研发流程,即技术人员需要参与产品开发、测试、交付、维护等所有环节,一个高效能的网关层无疑极大地解放了技术人员。Kong网关作为全新一代的API网关,对上述罗列的不少问题已经给出了完美的解决方案。下一节我们重点介绍Kong网关,以及其他成熟的网关产品。