联系我

淘宝技术架构演进之路

2020.05.31

前言

很多做后端开发的同学也许都可以根据自己的经验和学习的知识对一个网站应有的技术架构演进进行分析说道,但很少同学能够比较体系的说明整体脉络。今天就为大家推演一下整体的技术演进过程,方便大家及时查漏补缺。

基础知识

在介绍具体的架构演进之路之前,需要大家有一些基础知识,了解的同学可以略过不看,不了解或者概念比较模糊的同学可以简单看看回顾一下。

分布式

分布式简单理解就是系统的不同功能模块部署在不同的机器设备上,通常比如说电商领域当中的订单模块、支付模块、用户模块等等,分布式强调的更多的是不同的功能模块。其实分布式不一定就是不同的组件,同一个组件也可以,关键在于是否通过交换信息的方式进行协作。比如说 Zookeeper 的节点都是对等的,但它自己就构成一个分布式系统。

集群

集群是指同一种组件的多个实例,形成的逻辑上的整体。比如我们后台有一个订单系统模块集群,它们由多个经过负载均衡的 HTTP 服务器组成,它们之间不会互相通信

高可用

高可用是指系统中部分节点失效时,其他节点能够接替它继续提供服务。

负载均衡

负载均衡是高可用架构的一个关键组件,主要用来提高性能和可用性,通过负载均衡将流量分发到多个服务器,同时多服务器能够消除这部分的单点故障。

正向代理 & 反向代理

  • 正向代理类似一个跳板机,代理访问外部资源。比如我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。
  • 反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个服务器。反向代理有两个主要作用:
    • 保证内网的安全,可以使用反向代理提供 WAF 功能,阻止 web 攻击
    • 负载均衡,通过反向代理服务器来优化网站的负载

架构演进之路

有了上面的基础,下面我们就进入正题,看看我们的淘宝到底是如何一步一步成长壮大的。

最简单的架构--单机系统

此时存在的特征:

  • 应用简单
  • 应用数量少
  • 用户少

此时的请求处理方式也非常简单,用户只需要去DNS服务器上用域名找到对应的真实IP地址,随后访问该真实IP地址的应用服务器就可以获得想要的数据了,数据链路非常简单,单个机器就搞定。

有何不足?用户量稍微增长一些,由于Tomcat和数据库都部署在同一台机器上面,会存在系统资源争抢的问题,单机支撑不了业务的发展了。

演进一:Tomcat和数据库分离部署

此时存在的特征:

  • 用户略微增长
  • 业务形态依旧比较简单
  • 应用服务器和数据库分别独占服务器资源

有何不足?用户继续增长,并发读写数据库会成为未来发展的瓶颈。

演进二:引入本地缓存及分布式缓存

此时存在的特征:

  • 用户进一步增长
  • 并发访问进一步增加
  • 首页、热门商品详情页等热点数据访问量增大
  • 本地cache和分布式cache一起抗流量冲击

在这一架构模式当中,通常选用Memcached作为本地cache,Redis作为分布式cache,当然也会暴露一些缓存击穿、雪崩之类的问题,这里不展开讨论。

有何不足?随着用户增长,并发压力就主要落在了单机Tomcat的响应能力上了,越往后就会发现系统响应越来越慢。

演进三:引入反向代理

如前所述,既然瓶颈出现在单机Tomcat上面,那么我们非常自然的想法就是横向增加Tomcat服务器,使得负载可以均衡地散布在不同地服务器上。

此时存在的特征:

  • 系统访问量进一步增长
  • 应用服务器集群解决单机流量冲击
  • 可较为自由的扩充应用服务器

这里假设一下,单机Tomcat支持的并发量级为100,Nginx最多支持50000个并发,那么理论上就可以把并发请求分发给500台应用服务器上,抗住50000并发(当然实际上还有一些别的系统资源开销,因此理论计算值仅作理解)

技术选型上,可以选用Nginx、HAProxy,都工作在网络模型的第七层,主要支持HTTP协议。也可以选用封装好的OpenResty等技术。

有何不足?从图中可以看出单机应用服务器资源瓶颈问题暂时解决了,但是数据库只有一台,既要读又要写的,压力也非常大,所以接着数据库方面会成为未来发展的瓶颈。

演进四:数据库读写分离

还是前面提到的,单个数据库既然管写数据,还要管读数据,这样一来读写压力就很大,那怎么办呢,当然是把写库和读库分开啦,然后读库定期同步写库的数据就好了。如果对于数据的实时性要求比较高,刚写入的数据在读的时候能够获取到最新的数据,那就可以在写的时候双写,写库写一份,缓存写一份,然后读的时候就通过缓存来获取最新的数据。

此时存在的特征:

  • 数据库读写分离
  • 数据库存储依旧比较紧凑,界限不明显

这里可选用的技术就有Mycat、Sharding JDBC等等,Sharding JDBC工作在数据库驱动层面,无需额外的proxy;Mycat基于proxy,将Mycat server伪装成一个MySQL数据库。

有何不足?业务增多,且业务交叉访问,有的业务访问量很大,有的访问量比较小,这些业务都直接地去竞争数据库,相互影响性能。

演进五:按业务分库

此时存在的特征:

  • 不同业务不同库
  • 业务数据库资源竞争降低
  • 可以继续切分扩展数据库
  • 跨表连接不方便,需要额外的补充手段来解决

有何不足?业务不断膨胀,单机写库扛不住。

演进六:分表

按照水平切割的方式进行分表的操作,切割判断标准有很多可供选择,比如按照ID进行Hash,按照时间进行切割等。

此时存在的特征:

  • 写库性能提高
  • 数据库可实现灵活水平扩展
  • 数据库运维难度增加

有何不足?应用服务器和数据库都可以水平扩展了,随着用户进一步增加,单机的Nginx扛不住。

演进七:使用LVS或F5使多个Nginx负载均衡

图中的 LVS 和 F5 是工作在网络第四层的负载均衡解决方案,其中 LVS 是软件,运行在操作系统内核态,可对 TCP 请求或更高层级的网络协议进行转发,因此支持的协议更丰富,并且性能也远高于 Nginx,可假设单机的 LVS 可支持几十万个并发的请求转发;

F5 是一种负载均衡硬件,与 LVS 提供的能力类似,性能比 LVS 更高,但价格昂贵。

由于 LVS 是单机版的软件,若 LVS 所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点。

可使用 keepalived 软件模拟出虚拟 IP,然后把虚拟 IP 绑定到多台 LVS 服务器上,浏览器访问虚拟 IP 时,会被路由器重定向到真实的 LVS 服务器

当主 LVS 服务器宕机时,keepalived 软件会自动更新路由器中的路由表,把虚拟 IP 重定向到另外一台正常的 LVS 服务器,从而达到 LVS 服务器高可用的效果。

有何不足?如果LVS也达到了瓶颈,也就是说用户数达到了千万甚至上亿级别后,用户分布在不同的地区,与服务器机房距离不同,导致了访问的延迟会明显不同,该怎么办。

演进八:通过DNS轮询

如上图所示,DNS服务器当中可以配置多个IP地址,每个IP地址对应不同机房的虚拟IP,这样当用户访问淘宝的时候,DNS服务器就会使用轮询策略选个某一个IP供用户访问。

此时存在的特征:

  • 系统可做到机房级水平扩展

  • 千万级、亿级并发量可以通过增加机房解决

有何不足?业务越来越多,数据形式越来越多,还有一些检索、分析数据的需求,仅靠类似于MySQL的结构型数据库无法满足这些需求。

演进九:引入NoSQL和搜索引擎技术

数据库增长到一定规模以后,就不再适合复杂查询了,容易把数据库“拖垮”。此时就需要引入HDFS、Hbase、Redis、ElasticSearch等等适配于不同特征数据类型的中间件或存储引擎来作为专门的分析查询解决方案。

有何不足?此时一个应用当中包含了非常多的业务代码,不好维护,升级迭代也变得困难。

演进十:应用拆分

按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。这时候应用之间可能会涉及到一些公共配置,可以通过分布式配置中心 Zookeeper 来解决。

有何不足?不同应用之间拥有共同的模块,相同功能模块代码存在多份,耦合严重,公共功能升级时全部应用代码都要跟着升级。

演进十一:微服务

此时,如用户管理、订单、支付等功能在多个应用中都存在,那么就可以把这些功能的代码单独抽取出来形成一个单独的服务来管理

这样的服务也就是我们常说的微服务了,应用和服务之间通过 HTTP、TCP 或 RPC 请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理。

此外,可以通过 Dubbo、SpringCloud 等框架实现服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性。

有何不足?不同服务的接口访问方式不同,应用代码需要适配多种访问方式才能使用服务,此外,应用访问服务,服务之间也可能相互访问,调用链将会变得非常复杂,逻辑变得混乱。

演进十二:引入企业总线ESB

为什么要引入企业总线ESB呢,前面提到,不同应用服务之间要相互访问,但接口访问方式不一样,就像巴别塔语言不通问题一样,这时候就需要一种技术能够屏蔽服务接口的访问差异,它就是ESB了。实际上这种架构就是所谓的SOA(面向服务)架构了。简单区分微服务和SOA,SOA是指一种拆分服务并且使得服务接口访问变得统一的架构,SOA架构当中包含了微服务的思想。

有何不足?应用和服务不断增多,服务部署变得异常复杂难维护,如果多个应用服务部署在同一台服务器上还极有可能出现环境冲突的问题。另外,电商类公司常有大促等活动,要求能够灵活扩缩容,该怎么办?

演进十三:容器化部署管理

针对前面提到的痛点,我们可以将应用或服务打包成Docker镜像,然后使用K8s动态分发和部署镜像。有了容器化技术,我们可以有效的隔离环境,灵活部署项目应用,减少运维的难度。

有何不足?使用容器化技术后服务动态扩缩容问题得以解决,但是机器还是需要公司自身来管理,在非大促的时候,还是需要闲置着大量的机器资源来应对大促,机器自身成本和运维成本都极高,资源利用率低。

演进十四:云平台承载

到了这一步,我们就可以把系统部署至公有云上面,比如阿里云服务,利用公有云的海量机器资源,解决硬件资源动态取放的问题。还是拿电商领域来说,在618或者双十一这样的大促期间,公司可以临时申请足够的资源,利用上面提及的Docker和K8s快速部署应用服务,然后在大促结束以后释放之前申请的资源,做到按需按量付费。如此,公司的产能便能极大提高。

此外,云平台不仅可以按需动态获取硬件资源,还有一些公有的技术组件(如云数据库、OSS等)供用户选用,有的时候用户甚至都不用关心内部到底是怎么运作构成的就可以部署自己的应用服务,非常弹性和人性化。

云平台当中有以下几个概念需要了解:

  • IaaS:基础设施即服务。对应于上面所说的机器资源统一为资源整体,可动态申请硬件资源的层面;

  • PaaS:平台即服务。对应于上面所说的提供常用的技术组件方便系统的开发和维护;

  • SaaS:软件即服务。对应于上面所说的提供开发好的应用或服务,按功能或性能要求付费。

最后

以上就是淘宝技术架构演进的一些知识点了,大家有什么不懂的可以继续查询相关资料,勤动手勤动脑,我们一起加油吧。

参考链接

[1]: https://juejin.im/post/5dc7d7e3e51d453dd32c066e
[2]: https://www.cnblogs.com/anker/p/6056540.html
[3]: https://www.zhihu.com/question/64709787