点击围观!腾讯 TAPD 助力金融行业研发提效、敏捷转型最佳实践! 了解详情
写点什么

业务网关的落地实践

  • 2020-12-28
  • 本文字数:3071 字

    阅读完需:约 10 分钟

业务网关的落地实践

前言


随着系统规模变大、复杂度越来越高,微服务架构渐渐成为主流。当一个单体应用被拆分成许许多多的微服务应用后,也带来了一些问题。一些与业务非强相关的功能,比如权限控制、日志输出、数据加密、熔断限流等,每个微服务应用都需要,因此存在着大量重复的代码实现。而且由于系统的迭代、人员的更替,各个微服务中这些功能的实现细节出现了较大的差异,导致维护成本变高。另一方面,原先单体应用下非常容易做的接口管理,在服务拆分后没有了一个集中管理的地方,无法统计已存在哪些接口、接口定义是什么、运行状态如何。


网关就是为了解决上述问题。作为微服务体系中的核心基础设施,一般需要具备接口管理、协议适配、熔断限流、安全防护等功能,各种开源的网关产品(比如 zuul)都提供了优秀高可扩展性的架构、可以很方便的实现我们需要的一些功能、比如鉴权、日志监控、熔断限流等。


但是,仅有这些功能还不够。企业内部系统一般都是异构的,存在多种协议的接口,而对外提供服务的接口依然是 http 协议的。因此,协议转换是非常现实的需求。还有数据聚合的能力,开源产品提供的都是一对一路由功能,并不直接提供聚合、编排的能力。而在实际开发中,需要对一些小接口进行聚合是很常见的,如果需要去写代码、发布就会很繁琐,而且以后小接口升级还得同步更新。


因此,我们参考 SpringCloud 网关产品的优秀设计理念,在基础网关的功能上支持多种下游协议、支持服务编排功能,并提供可视化的配置平台。


1 技术选型


1.1 方案对比


我们选择了 Java 微服务体系中三个主流的 API 网关框架 Zuul1、Zuul2 和 SpringCloud Gateway,在线程模型、协议适配、熔断限流,服务编排等方面进行了对比。



三种框架的优缺点都很明显,但是都缺少了对 dubbo 的支持,同时也没有数据聚合(服务编排)的能力,因此我们借鉴它们的优秀架构,自研业务网关。下面看一下 Zuul2 的系统架构。


1.2 系统架构



这是典型的网关系统架构,由三种功能 Filter 以及异常 Filter 组成。Inbound Filters 主要负责对 request 的校验、加工、拦截,Endpoint Filter 负责路由 & 下游接口调用,Outbound Filters 负责对 response 的校验、加工、日志监控等,Exception Filter 则负责功能 Filter 中的异常处理。这套架构简单清晰、可扩展性强,可以很容易实现模块化、并且各个模块(Filter)间彼此无耦合,类似 Plugin 的独立性。


2 体系结构


先看一下网关的体系结构。



校验拦截层提供了网关的基础能力,通过 Inbound Filters 和 Outbound Filters 来实现,可无限扩展。


服务调度层和接口通信层提供了核心能力,通过 EndPoint Filter 来实现。


异常处理统一交由 Exception Filter 来处理,之后会重新流转到 Outbound Filters 中。



3 创新之处


3.1 协议转换


公司内部 rpc 服务采用 dubbo 这套解决方案的基础上二次开发,大量的微服务采用 dubbo 协议,网关也必须要支持 dubbo 接口的转发。dubbo 的泛化调用非常适合网关的场景,它需要接口定义和接口配置(zkaddress、group、version 等)两部分信息。其中,接口定义信息手工填写非常繁琐,为了避免人为因素导致的配置错误,网关会根据 jar 包的 maven 坐标去拉取 jar 包进行扫描,获取到接口的具体方法签名。


网关管理所有的 Dubbo Reference,监听配置平台的推送消息,动态管理 Reference 的生命周期以及运行参数,比如实时调整 dubbo 接口的超时时间、实时升级 dubbo 接口的版本等。所有的 Reference 对象都在初始化后才交付给执行器,保证接口的执行效率。



3.2 服务编排


微服务架构下会更依赖通过各微服务之间的协作来实现一个完整的业务流程,这种协作就是服务编排。编排涉及到 RPC、分布式事务等,需要有完善的编排框架来支撑。


编排的实现,需要解决四个关键点:


  1. 复杂依赖:存在 M:N 的依赖关系

  2. 执行时机:如何并行,如何避免阻塞等待

  3. 数据传递:如何根据上游数据构建下游参数

  4. 异常处理:异常时应该整体中断,还是服务降级


其中,复杂依赖和执行时机是难点。


复杂依赖:采用服务自治的思路,通过定义每个服务所关心的服务即可。通过分析,发现这是个有向无环图,通过成环检测可以发现不合理的依赖关系。


执行时机:采用面向协作的思路,通过消息的交互序列来控制各个服务的交互,参与交互的服务都是对等的,没有集中的控制。如上图所示,所有服务通过消息总线共享事件通知,决定自身是否执行。



3.3 嵌入式网关


为什么需要嵌入式?要解决什么问题?


一般主要业务接口都会附带着调用很多小接口,并随着主接口的数据一并返给调用方。主业务接口一般比较稳定,但是小接口的迭代相对比较频繁。此时,因为小接口的迭代导致修改主业务接口所在的工程,就显得那么的多余。我们希望能把与主业务接口无耦合的小接口透传化,达到小接口升级、主接口无感知的目标。


我们将网关的核心能力抽象出来形成一个 jar 包,主要包括配置同步、服务编排、协议转换,称作“嵌入式网关”。宿主工程引入嵌入式网关,并将调用下游接口的地方改成嵌入式网关的执行入口就行了,剩下的就是去配置平台配置这个接口的相关信息。如果是 dubbo 接口的话,还可以顺便将依赖的 api jar 包删掉,因为泛化调用不需要引入 jar 包。


嵌入式网关提供了宿主工程透传化改造的能力,可以实现非强耦合下游接口的数据纯透传化,降低宿主工程的业务复杂度,并且可享受网关系统的所有能力。


4 高可用探索


如何考量一个网关产品的优劣?常用的性能指标包括:吞吐量、耗时、错误率。有个非常关键的指标:高可用性,也就是传说中的几个 9。


高可用性涵盖了内部和外部的各种不确定因素,这里讲一下网关系统在高可用性方面做的努力。



5 落地效果


5.1 人效


网关上线后,最直接的收益是人效方面。因为减少了一个协作团队,因此相应节省了开发与测试的工时。


选择了几个比较独立的业务做数据分析,整体节省了大概 27%左右的工时。



注:节省工时包括“ API 层服务团队的开发、自测联调,以及对应 QA 的工时”。前端跟后端按 2:1,开发跟 qa 按 3:1 算,=前端*67%


注:”商品售卖“通过嵌入式网关实现了与主接口的解耦,迭代过程中无主工程的发布。


5.2 故障处理


由于网关具备了调整数据的能力,对于一些由于数据不规范或者缺失导致的故障,提供了快速恢复的手段。


故障案例:



6 典型案例


1、新开发一个纯透传的接口


常规:写代码调用下游接口,定义 bean,将结果添加到 response 中。当下游增加字段时,需要代码迭代。


网关:在配置平台上配置下游服务,无需定义 bean,纯透传,下游接口增加字段无需任何改动。


2、活动首页配置获取接口,新增一个维度的配置,该配置数据由一个新接口提供(数据聚合)


常规:写代码调用新的下游接口,将结果添加到 response 中。


网关:在配置平台上增加一个下游服务,将结果挂载到 response 中,后续迭代无需任何改动。


3、touch 接口的跨域解决


常规:针对下游接口做 ng 转发,或者由下游接口做跨域处理。当下游使用 jsonp 时,还可能存在 xss 漏洞隐患。


网关:在公司 touch 域名下增加了/gw 的 location 配置,开发人员无需考虑跨域问题。还支持 jsonp,并且做了 xss 漏洞防御。


4、从一个接口获取酒店列表,然后从另一个接口给每一个酒店补充评论信息


常规:调用第一个接口获取酒店列表,做简单业务判断后,对列表做循环调用第二个评论接口,并将数据补充进去。


网关:定义两个下游接口,将第二个评论接口设置为依赖”第一个酒店列表接口“,并且指定循环用的字段路径,还可以指定失败时的降级内容。



头图:Unsplash

作者:施黎明

原文业务网关的落地实践

来源:Qunar 技术沙龙 - 微信公众号 [ID:QunarTL]

转载:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2020-12-28 23:023634
用户头像

发布了 81 篇内容, 共 10.2 次阅读, 收获喜欢 145 次。

关注

评论 1 条评论

发布
用户头像
服务编排是否又走上ESB的老路了
2020-12-30 09:25
回复
没有更多了
发现更多内容

不交“人脉”交朋友:新荣耀的底气与新机

脑极体

漫谈分层架构:为什么要进行架构分层?

AI乔治

Java 架构 高可用系统的架构 高可用架构

第1周架构方法总结

Richard

UML 需求分析 概要设计 软件架构设计 详细设计

花火交易所系统开发、雷达模式系统搭建开发

W13902449729

花火交易所系统开发 雷达模式系统搭建开发

助力ARM生态 —Dragonwell新增aarch64支持

阿里云基础软件团队

新的方式-谷歌浏览器插件的使用【天猫超市抢购飞天茅台】

谙忆

探索 React 合成事件

pingan8787

大前端 React 28天写作

原理竟然是这!GitHub上标星13k的《Android面试突击版》,醍醐灌顶!

欢喜学安卓

android 程序员 面试 移动开发

音频特征提取方法和工具汇总

行者AI

音视频

DAPP智能合约交易系统开发、DAPP系统开发的详细解释

W13902449729

DAPP智能合约交易系统开发 DAPP系统开发

12月阿里蚂蚁金服四面(已拿offer)Java技术面经总结:项目+源码+jvm调优+MySQL

Java 学习 编程 程序员 面试

重学JS | 改变函数上下文的3种方式

梁龙先森

大前端 编程语言 28天写作

redis中的一致性hash

原来不悔

redis 一致性hash

前端性能优化

roadup

大前端 性能调优

不可多得的干货!耗时两个礼拜,8000字安卓面试长文,内含福利

欢喜学安卓

android 程序员 面试 移动开发

跪了!Alibaba内部出品贼火的Java面试手册,全面对标蚂蚁金服、头条、拼多多等

Java架构之路

Java 程序员 架构 面试 编程语言

博弈论 - 海盗分金

石云升

博弈论 28天写作 海盗分金

巧合?达摩院2021十大科技是十九世纪那场幻想的升级版?

Java架构师迁哥

架构师训练营第七周作业

zamkai

Synchronized 精讲

伯阳

Java 多线程 高并发 synchronized java关键字

Spring5.0源码学习系列之Spring AOP简述

AI乔治

Java spring 架构

跨界

张老蔫

28天写作

SpringBoot太强了、ShardingSphere上榜

spring 编程 框架

CSS ( Cascading Style Sheets )

roadup

CSS

凭借这份Java超硬核面试 “备战” 手册!我刚面试完字节跳动、阿里、华为、小米等后端岗位

Java架构之路

Java 程序员 架构 面试 编程语言

理财之我见

三石

理财 28天写作

python 输入输出

赵开忠

Python 28天写作

计算机网络基础

roadup

TCP 网络 HTTP 计算机 HTTP3.0

精选算法面试-队列

李孟

算法 队列 28天写作

业务网关的落地实践_文化 & 方法_Qunar技术沙龙_InfoQ精选文章