热爱技术,追求卓越
不断求索,精益求精

网站架构的进化过程,从单一应用到分布式微服务再到动态API网关

网站架构1.0(All in one)

公司创业初期还处于移动互联网不太盛行的时代,整个业务系统一开始只有PC Web,所以只有一个API网关工程main——基于spring mvc,当时底层的业务系统还只有一个工程——openapi,作为上层业务的支撑。main和openapi之间是通过Hessian进行数据交互,最开是的网站架构大致如下图所示:

image

最开始的openapi业务还是比较简单的,里面只包含了产品(product)、订单(order)、用户(user)、支付(pay)等简单的业务逻辑。随着业务的拓展、电商玩法的多样、产品经理需求的增多,大家不断的往openapi加功能,导致openapi越来越臃肿,到最后openapi里面涵盖了产品(product)、订单(order)、促销(promotion)、活动(activity)、用户(user)、支付(pay)、预订(booking)、点评(review)、邮件(mail)、通知(notice)等业务。到了这个阶段,openapi “All in one”的缺点暴露出来,不同的业务开发组都在维护openapi这个工程,谁都在修改,最恐怖的时候,一天openapi要发6、7次版本,系统耦合严重,工程内部接口调用混乱,每到大促活动,系统就会瘫痪几个小时。最后把openapi和main集群部署也不能很好的解决问题,开发人员是说不出来的痛啊,同时由于main里面也是不断的加功能,main也变得臃肿复杂,代码无注释,多人员开发赶进度,代码风格不统一,工程越来越难以维护。

网站架构2.0(分布式&集群)

随着移动互联网的快速发展,手机浏览器用户和手机客户端用户越来越受到重视,于是我们在原来的网关工程main之后新增了wap(针对m站)和mobile(针对app客户端)。或许有人会问,为什么不直接使用main作为api网关呢?由于上文提到main这个工程已经过于臃肿、代码混乱,已经很难维护,而且移动端的需求和数据交互有时候跟web端有极大差异,所以当时的研发人员先加了一个wap用于快速支持移动端的业务。wap这个工程也是赶工出来的,部分业务代码是从main里copy出来的,部分业务代码是按照当时的需求写的,所以后来会从wap中看到main中痛苦的影子。后来招了客户端的研发人员,开启了app开发之旅,大家都意识到问题的存在,所以一个新的支持客户端的网关工程mobile出现了,主要是提供一些移动端、wap、小程序等的一些API接口。由于最开始所有业务都融合在openapi中,业务发展到一定阶段,不得不对这个工程进行业务拆分,于是我们引入了dubbo,为了提高性能我们引入了redis(缓存)和rocketmq(异步)。并把项目按照业务和公共的角度进行划分,比如短信(sms)、邮件(mail)、推送(push)等属于公共服务;产品(product)、订单(order)、用户(user)、支付(pay)等属于业务服务。每一个工程都可以集群部署,这个时候我们的整个业务系统已经分布式化和集群化:

image

网站架构2.0让我们的研发人员省心了不少,虽然还存在一些严问题,比如令人害怕的代码、冗余的代码、调用链混乱等,但整体性能是提升了不止一个数量级,至少不会出现业务高峰宕机的现象咯,我们的工程也由原来的openapi拆分到了十几个、二十几个。

网站架构3.0(API动态网关)

经过几年的业务积累,业务流程等已经基本固化下来,但还是偶尔有一些细节需要调整,但由于原来的网关接口分布在main、wap、mobile中,有时候一个相同需求的变动,研发人员要去修改三个不同的工程,而且每个工程都有一些比较复杂的逻辑、代码逻辑混乱、代码风格可读性不好,维护起来比较困难。于是我们开启了API网关的重构之旅,重构后的系统大致如下图所示:

image

API GATEWAY CLUSTER : API网关集群。每个实例功能相同,主要负责统一的身份认证和鉴权,动态路由,API负载均衡,多区域水平扩展等,这一层可以提供一些业务逻辑处理,同时也可作为 “http api 服务集群”的反向代理及负载均衡器。

HTTP SERVICE CLUSTER: http api 服务集群。这一层是API网关层的有效补充,每个垂直业务可以是一个小集群(如用户、产品等),主要负责一些边缘化的业务,如活动、优惠、促销等,可随时上下线,API网关集群根据配置的动态路由可实现API的热部署。

这个时候我们的整个系统架构如下:

image

整个系统现在可以实现动态上下线API,实现灰度发布。主要是有了这个“API Gateway”后,我们可以随心所欲的重构main、mobile、wap等项目,把一些公共的业务逻辑整合到“common api”中,以后只需要维护一份代码即可降低了维护成本。“other api”是一些边缘的接口,可随时热部署上下线,不影响主业务的运行。同时还可以支持“API Gateway”直接通过dubbo的方式调用后端的“业务集群”。网站架构3.0是基于zuul的,很多项目都从原来的spring 3.x升级到sproing boot了,一些业务还使用了spring cloud,但由于整个系统最开始都是基于dubbo的,所以会有dubbo和spring cloud一起使用的现象,但是现在的API网关架构给我们带来了这些好处:

  1. 验证与鉴权: 识别面向各类资源的验证请求并拒绝那些与要求不符的请求。
  2. 审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。
  3. 动态路由: 以动态方式根据需要将请求路由至不同后端集群处。
  4. 压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。
  5. 负载分配: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。
  6. 静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。
  7. 多区域弹性: 跨域垮区进行请求路由,旨在实现负载均衡、屏蔽内部细节、使用多样化并保证边缘位置与使用者尽可能接近。

网站架构4.0(分布式配置中心&分布式任务调度)

引入API网关后,我们还引入了分布式配置中心(apollo)、分布式任务调度(elastic job)、搜索引擎(es、solr)、代码质量管理(Sonar)等,系统还在一步一步的完善和强大。从这些亲身实战的重构经验来看,每次重构都是一次偿还技术债务的工作、偿还别人留下的或者是自己留下的,但看到系统越来越稳定就是一个技术人员最欣慰的事情。

重构感想

重构过程中要根据自己的业务,重构不是凭空想象,不是别人用什么牛逼的技术你就选什么,而是要选择符合自己系统的(比如我们不会全部迁移到spring cloud);重构过程中要尽量保证原有业务的完整性,保证影响点降低到最小;重构不一定是一刀切(比如我们并不是一下全废弃main、wap、mobile的所有接口全新开发,而是使用网关层进行路由控制,每上一个功能切换一个路由),而是合理的架构逐步迭代直到全部升级完成。有新的业务就会有重构,业务不休,重构不止。

赞(3)
未经允许不得转载:LoveCTO » 网站架构的进化过程,从单一应用到分布式微服务再到动态API网关

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

热爱技术 追求卓越 精益求精