【源码揭秘Dubbo技术内幕】分布式架构的演进

概述

随着社会的发展与进步,软件架构也在不断地改进,软件架构改进的根本原因在于需要不断地去适应时代需求的变化,一个企业最初可能只需要面对几万甚至几千的用户,那么简单的单体架构其实是最合适的,因为它不需要很高的成本,业务较简单,维护难度也不大。我们必须要明白架构是没有绝对的优劣之分的,架构是为项目服务的,所以不要盲目地去追求最新的最高端的架构,合适企业当前所需的就是最好的架构。

不可否认的是随着用户的大规模增长,企业需要通过不断改进架构来支撑大规模用户带来的流量洪峰,而分布式架构被赋予了可以解决大规模流量洪峰的能力,所以很多企业开始纷纷采用分布式架构去构建分布式系统,不管是使用单体架构还是分布式架构,对于用户来说是无感知的,处理的请求来自哪一台服务器,数据存储在哪个数据库都不是固定的。

如今分布式架构已经朝着细粒度化、独立化、融合化的方向发展,微服务架构的出现正是这种发展趋势的结果。微服务(Microservice)这个概念最早是在 2012 年由 Martin Fowler 提出的,虽然没有非常明确的定义,但是基本上业界已经形成了一个这样的共识,一个微服务只需要提供特定的功能,可以独立的运行,并且不会影响到整体架构的稳定性。微服务的这种“独立性”使得企业在项目研发中采用多人多组开发的方式变得习以为常。2015 年可以说是微服务的元年,因为越来越多的企业、论坛、社区开始对微服务进行讨论、实践,不断地推动着微服务的落地和发展,毫不客气地说如果没有这些先驱者的不断摸索和尝试,微服务不可能会成为当今最流行的软件架构。

架构演进

我们都知道一个大型项目的系统架构并非一开始就是完美的,架构都是需要一个不断改进和完善的过程,对于企业来说前期先满足功能实现,快速出产品才是最重要的,因为市场才是真正的老板,只有让市场这个老板满意企业才能生存,才能发展。
并且架构并没有固定的模板,现如今软件开发包含了多种强大的框架、中间件、数据库等等,能够让企业里的架构师灵活决定技术选型,搭建出不同的系统架构。
架构是为项目服务的,针对不同的项目需求,架构也会有不同的侧重点,例如对于淘宝天猫这样的站点架构来说,需要优先满足海量商品下单、支付和交易等业务;对于微信、QQ这样的后端架构来说,需要优先满足亿海量用户的即时通讯业务;对于抖音这样的后端架构来说,需要优先满足海量视频播放的业务。

作者由于曾经设计参与过电商项目的完整周期,所以下面我将简单来模拟一个电商项目架构的演进过程。通过该演进过程,读者朋友可以进一步理解架构的演进过程,以及每一次架构演进的侧重点是在哪里,或者说目的是什么。

单体架构

在这里插入图片描述
在电商项目的初期,企业的目标是非常明确的,那就是要求产品快速上线,因为市场不等人,谁能最先抢占市场,谁就越有话语权。说一个真实案例,在移动支付领域,国内市场可以说目前已经被支付宝和微信占领,他们也是最早一批投入移动支付领域的企业,京东后来也想在移动支付领域分一杯羹,可惜为时已晚,当时刘强东将最重要的财力物力都投入到京东物流上面,导致没有过多关注移动支付领域,在后来接受媒体采访时刘强东也坦诚,早期没有将财力物力投入到移动支付领域是他本人最后悔的一件事。

所以项目初期快速出产品是企业的第一个目标,在这个阶段为了提高研发效率同时又能节约成本,应用和数据库通常集成在一台服务器,这是最简单最基础软件架构,这种架构没有集群、没有负载均衡、更没有高可用。虽然说这种架构很脆弱,但并非一无是处,由于代码和数据库都在本地,没有分布式的管理和调用消耗,处理请求速度会非常快,用户体验极佳。这种架构非常适合初创项目或者给客户演示的 Demo 。

应用与数据库分离

在这里插入图片描述

伴随着用户量的增长,应用需要和数据库去竞争资源,单个服务器已经无法再正常支撑系统的业务处理,响应速度开始变慢,甚至开始部分出现调用异常的情况,用户体验不佳,企业迫切需要解决单机性能瓶颈问题。最简单的方法就是让应用和数据库分离,让他们各自独占一台服务器资源,减轻了各自带来的压力,提升了系统的负载能力,用户的良好体验又回来了。

这种架构理论上来说对比单体架构并没有质的变化,系统仍然非常脆弱,不过从企业的角度来看,通过只增加一台服务器的成本便可以暂时维持系统目前所需的负载能力,不得不说投入产出比还是相当高的。

应用集群和数据库读写分离

在这里插入图片描述
让应用独占一台服务器资源的架构,最终还是避免不了会遇到单机性能瓶颈,这时候对于企业来说,单台应用服务器已经无法再支撑现阶段用户带来的流量冲击,系统由于之前并没有具备高可用能力,宕机情况将会时常出现,这不仅会给用户带来糟糕的体验,甚至还可能会造成部分用户数据的丢失,这是所有企业都不能容忍的。将现有系统转建成分布式系统,走分布式架构,已经变得刻不容缓。

那么什么是分布式系统呢?分布式系统是建立在网络上的软件系统,应用通常有多个备份,并且分布在不同的机器上,分布式系统是由通信网络互联的多服务体系结构上执行任务的系统,项目采用分布式系统能够通过横向扩展应用,突破单机性能瓶颈问题,具备支撑和处理大规模流量冲击的能力。那分布式架构和分布式系统又是什么关系呢?其实非常简单,采用分布式架构来部署的系统就是分布式系统,分布式架构是分布式系统的基础。

想要将系统从单体架构转建为分布式架构至少需要解决两个问题:
• 应用有多个备份,如何将用户的请求转发到具体的应用服务器?
• 用户每次请求的目标服务器如果不是固定的,如何处理会话问题?
为了能够将用户的请求转发到具体的应用服务器,我们需要在用户和应用服务器之间增加一个负载均衡组件。反向代理软件 Nginx 是当前最流行的负载均衡组件之一,用户的请求通过 Nginx 转发到具体的应用服务器上,同时为了保证 Nginx 的高可用,通常需要配合 HAProxy 来实现健康检查和故障切换等功能。
为了处理分布式系统带来的会话共享问题,采用分布式缓存来处理是个不错的选择,分布式缓存市面上有很多可选的方案,例如 Redis、Memcached、MongoDB,都是不错的选择,他们都能够在并发访问的情况下保证数据的一致性,可以完美解决分布式系统带来的会话共享问题。

解决了分布式系统带来的问题之后,系统终于可以承载大规模用户的访问,应用之间相互备份,具备了容灾和扩展功能,同时数据库也可以进一步的完善,利用两台数据库服务器分离读写业务,一台为读库,一台为写库,搭建出主从读写分离的持久层架构,这不仅加快了数据库的读写操作,而且主从数据库之间由于具备了数据备份的功能,从而大大降低了数据丢失的风险。

缓存集群和数据库集群

在这里插入图片描述

在完成单体架构过渡到分布式架的之后,对于应用服务器来说,伴随用户不断增长,只需要横向扩展应用即可,似乎不再需要考虑其他问题,处于该阶段的架构往往需要将更多的注意力集中到数据持久层上,如何才能支撑越来越大规模的用户数据成为了该阶段的核心问题,因为单个数据库性能瓶颈成为了整个系统的瓶颈。

通常的解决方案有两步骤:
• 第一步:数据库采用集群方式部署,把不同的业务数据保存到不同的数据中,降低单个数据库的访问压力,并且可以针对访问压力大的业务部署更多的数据库来支撑。
• 第二步:将单表数据量大的表拆分成多个小表,存储到多个数据库上。拆分的方法很多,比如按照主键 ID 的 hash 值进行拆分,又比如按照时间段、年月份等进行拆分,市面上开源的分库分表中间件 MyCAT 和 Sharding-JDBC 都是不错的选择。

完成了数据库持久层的扩容之后,缓存层通过集群来扩容也将被提上日程,因为数据库集群大表拆分小表之后,检索速度将进一步变慢,让热数据预先存储到缓存层,在处理热数据查询时不通过数据库持久层,而是在缓存层直接拦截返回,这种处理方案能够有效提升业务处理速度,被业内广泛采用,所以为了支撑这种处理方案就需要对缓存层进行集群部署,同时需要注意处理好缓存穿透和缓存雪崩等问题。

微服务架构

在这里插入图片描述
系统经过横向扩容、数据库集群和缓存集群改造之后稳定运行了一段时间,不久之后,伴随着业务的增长,工程师们发现了两个亟需解决的问题:
• 代码太臃肿。项目代码从单体架构开始就没有进行过大的结构性调整,功能模块耦合在一起,模块边界模糊不清、依赖关系复杂、代码质量参差不齐,整个项目看起来异常复杂,团队新成员需要花费巨额时间成本来熟悉项目,并且开发新功能时步履蹒跚,牵一发而动全身,版本迭代效率急速下降。
• 维护成本加大。伴随业务的增长,就连单体项目的易维护性也不复存在,项目构建和部署的时间变得越来越长,无法针对核心业务模块进行单独扩展,由于功能模块都耦合在一块,项目运行往往需要更大的服务器资源,并且缺陷修复更新变慢,因为缺陷修复代码需要同步到所有的应用服务器上,这大大增加了系统出错的概率。

为了处理这两个大问题,我们研发团队进行了长时间的技术探索和实践,微服务就是在这个阶段进入了我们的视野,最终我们决定对现有的项目结构进行一次彻底的微服务化改造。细粒度化和融合化是进行微服务改造的思想,平台化和功能模块化是进行微服务改造的目标:
• 服务拆分。我们明确了要将原来系统业务改造成业务中台层和基础服务层,由基础服务支撑业务中台。确定服务的边界,将整个项目按照服务边界抽离出来,形成一个个微服务,降低服务之间的耦合度。
• 规划出接入层。将网关、容错限流、负载均衡、安全加解密、权限认证等功能归集到该层。这一层介于应用层和业务中台之间,为系统起到了遮风挡雨的作用,进一步提升了系统的稳定性、扩展性和安全性。
• 前后端分离。在最初的单体架构中前后端代码是耦合在一块的,期间进行的架构升级过程中前后端也没有进行彻底分离,终于在这次微服务化改造中实现了前后端的彻底分离,前端项目拥有自己独立的架构和研发、测试、部署流程,和后端完全解耦。
• 公共组件下沉。微服务改造过程,我们将一些公共组件下沉到基础设施层,例如消息队列、定时任务、文件服务器、检索服务等等,这些组件交给单独的团队进行维护,由他们来支撑微服务和业务中台。
• 研发分组化。代码伴随着服务一起被拆分,服务模块得以明确,企业根据服务模块将研发团队分成多个平台组和服务组,各组功能明确,相互依赖同时又相互解耦。研发分组化不仅提升了研发效率,而且降低了维护的成本,版本功能迭代步伐加快了不少。
• 运维监控平台化。微服务化的改造让系统拆分出来更多的服务,短时间内维护成本确实增加了不少,但随着我们对运维监控平台的不断完善,建成 DevOps 团队,由他们负责日志平台、监控平台、服务容器化、自动化部署等工作,运维变得更加专业化,维护成本逐步降低。
• 优化持久层。在系统进行分布式架构改造的过程中,我们已经对持久层进行过处理,读写分离、集群、分库分表,所以在这次系统微服务改造过程中,我们只需要根据服务的拆分对数据库也同步进行业务拆分即可。

微服务解决方案

有一句话说的挺好的,“没有具体落地方案的架构设计就是耍流氓”。所以下面我们就来介绍一下微服务架构的解决方案,目前最流行的微服务解决方案有两种:Spring Cloud Netflix 和 Spring Cloud Alibaba 。这两种方案都是 Spring 官方社区的开源项目。其中 Spring Cloud Netflix 仍然是目前国内最流行的微服务解决方案,它的五大组件 Eureka、Feign、Ribbon、Zuul、Hystrix 被国内企业广泛使用。然而可惜的是在 2018 年 12 月份,Spring 官方社区发布了一篇博客声明,Netflix 宣布旗下的大部分微服务组件进入维护模式 ( Maintenance Mode ) ,并警告使用者如果继续使用需要自己去承担风险后果。进入维护模式意味着这些组件将不再进行迭代升级和添加新功能,只会修复严重级别的 bug ,这对之前使用该方案的企业来说确实是个不小的打击,虽说短期内继续使用问题不大,但长期使用会严重制约企业的技术升级。

Spring Cloud Alibaba

Spring Cloud Netflix 的停更让国内很多企业纷纷将目光转投到另外一个新的微服务解决方案 Spring Cloud Alibaba 。Spring Cloud Alibaba 是阿里巴巴开源的微服务解决方案,2018 年 10 月份正式入驻 Spring 官方孵化器,并于 2019 年 7 月份完成毕业,成为了 Spring 社区的正式项目,也是社区目前为止唯一的一个来自我国的开源项目。目前 Spring Cloud Alibaba 的最新版是 2.1.0 。
在这里插入图片描述
Spring Cloud Alibaba 提供了完整的微服务组件、中英文文档、案例,能够让开发者迅速将项目接入微服务,降低后续的开发和运维难度。
图片来源于阿里云开发者社区

主要功能

服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

组件

Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。
Dubbo:Apache Dubbo™ 是一款高性能 Java RPC 框架。
Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。
Alibaba Cloud ACM:一款在分布式架构环境中对应用配置进行集中管理和推送的应用配置中心产品。
Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。
Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。
Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

Dubbo

在这里插入图片描述
Dubbo 是 Spring Cloud Alibaba 解决方案的组件之一,它是一款高性能、轻量级的 Java RPC 框架,主要负责处理微服务之间的数据通信问题。它提供了高性能的基于代理的远程调用能力,还提供了强大的集群容错、负载均衡、服务治理等功能,并且具备良好的扩展性,后面的课程将会详细介绍 Dubbo 底层的实现原理,并通过对其进行源码解析的形式,帮助读者朋友们彻底掌握 Dubbo 的核心内容:
• 扩展性 SPI
• 服务暴露过程
• 服务引用过程
• 远程调用过程
• 集群容错
• 负载均衡算法
• 网络协议
• 编解码
• 优雅停机实现机制
• 事件通知实现机制
• 整合 Spring Cloud Alibaba 其他组件等

小结

文章主要介绍架构演进的过程,从单体架构、集群、数据库集群、再到现在最流行的分布式微服务架构。接着我们介绍了微服务架构的落地解决方案 Spring Cloud Netflix 和 Spring Cloud Alibaba。Spring Cloud Alibaba 是国产的方案,在该方案中服务间的远程通讯将使用 Dubbo 框架。Dubbo 框架已经在阿里各大系统中使用,经受过双十一的考验,表现优异,被国内各互联网企业广泛采用,非常值得我们仔细研究。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值