首页 > 编程知识 正文

人类文明演进的历程(演进式架构pdf)

时间:2023-05-06 16:18:24 阅读:96938 作者:1984

00-1010观看前请点赞,并有良好的习惯。

几乎所有的大规模应用都是从一个小应用开始的,好的互联网产品都是慢慢运营的,而不是一开始就开发出来的,所以在这篇文章中,我们来谈谈应用架构的演进。

如何创建高可用性、高性能和易于扩展的应用程序?让我们首先了解大规模应用程序的特征:

高可用性:系统需要持续提供服务,无单点故障,高并发。在大流量的冲击下,系统仍然稳定地提供服务。大数据:应用每天都会产生大量的数据,需要很好的存储和管理。

前言

刚启动应用,流量不大,所以只需要一台服务器。此时的架构如下:

应用程序、文件和数据库通常部署在一台服务器上。应用程序可以用Java开发,部署在Tomcat服务器上,数据库可以使用开源的MySQL。

最简单的架构

随着应用业务的日益复杂和应用访问量的不断增加,性能越来越差,存储空间严重不足。这时候我们考虑把服务增加到三个(加机器能解决的问题不算问题);将应用服务器、数据库服务器和文件服务器分开。

应用服务器需要处理大量的访问,所以性能较好的CPU数据库服务器需要存储大量的数据和快速的检索,所以磁盘的检索速度较快,存储空间较大。文件服务器需要存储上传的文件,并且需要更大的磁盘。现在,通常会选择第三方存储服务

根据每台服务器对应的场景,对服务器进行配置后,可以大大提高应用的性能,可以更好地支持业务的发展。但随着业务的发展和访问量的增加,这种架构将再次面临挑战,应用服务器的处理能力下降,存储空间不足。

应用与数据服务分隔

在高并发、大流量的情况下,一台服务器肯定处理不了。此时,添加服务器并部署集群来提供服务,以分担每台服务器的压力。集群部署的另一个优势是可扩展性。比如双11流量大的时候可以增加服务器共享流量,双11之后可以降低服务器成本。架构如下:

如果应用服务器是Tomcat,那么可以部署一个Tomcat集群,并且可以在外部部署一个负载平衡器。随机、轮询或一致哈希算法可用于将用户请求分发到不同的应用服务集群。通常的自由负载平衡是nginx。在这种架构下,应用服务器的负载不会成为整个应用的瓶颈;

虽然在这个框架下应用程序的处理速度有了很大的提高,但是会暴露出一个问题,大大增加了数据库的压力,导致访问响应延迟,影响整个应用程序的性能。这种架构还有另一个问题。通常,应用程序是有状态的,需要记录用户的登录信息。如果每个用户的请求被随机路由到后端应用服务器,用户的会话将会丢失。这个问题的两个解决方案:

一致的散列用于将用户的请求路由到同一个Tomcat。如果服务器崩溃,该服务器上的用户信息将会丢失。通过配置Tomcat集群之间的会话复制,实现了共享。这个计划没有效率。两个方案都不太好,那么还有其他方案吗?请继续往下看。

00-1010按照2月8日的原则,80%的业务集中在访问20%的数据上,这通常被称为热数据,但这20%的数据占用的内存不会小。如果每个应用服务器存储一个副本,会浪费一些存储空间,所以需要考虑加入分布式缓存服务器(Redis);是常用的)。引入分布式缓存服务器,可以解决上述方案的问题。将用户会话存储在缓存服务器中不仅可以防止用户数据丢失,而且效率低下。架构如下:

毕竟分布式缓存服务器是远程存储的,需要经过网络,所以获取数据还是需要一点时间的。本地缓存访问速度更快,但内存空间有限,会与应用程序争夺资源。因此,该架构与分布式缓存和本地缓存相匹配。本地缓存存储少量常用的热数据,然后在本地缓存没有命中时转到集中缓存。

引入缓存后,可以在一定程度上缓解数据库的访问压力。

应用服务器集群

ow-right">数据库读写分离

虽然在加入了缓存之后,部分数据可以直接走缓存,不需要访问数据库,但是仍然会有一些请求,会访问数据库,比如:缓存失效,缓存未命中;当流量大的时候,数据库的访问量也不小。这时候我们需要考虑搭建数据库集群,读写分离

当应用服务器有写操作时,访问主库,当应用程序有读操作时,访问从库;大多数的应用都是读的操作远远大于写的操作,所以可以配置数据库一主多从来分担数据库的压力;为了让应用程序对应主库和从库无感知,通常需要引入一些读写分离的框架做一个统一的数据访问模块。

这种架构通常需要警惕的一个问题是主从延迟,当在高并发的场景下,主库刚写成功,数据库还未成功同步完从库,这时候另一个请求进入读取数据发现不存在;解放方案是在应用程序中高并发的场景下设置强制走主库查询

兄弟们,请不要白嫖哦,文章看一半,请先点个赞


反向代理和CDN

假如随着业务的不断扩大,全国各地都会使用到我们的应用,由于各地区的网络情况不同,所以有的人请求响应速度快,有的人请求响应速度慢,这会严重的影响到用户的体验。为了提高响应速度需要引入反向代理和CDN;CDN和反向代理都是采用的缓存,目的:

尽可能快的把数据呈现给用户减轻后端服务器的压力

架构图如下:

CDN: 部署在网络提供商的机房,当用户来访问的时候,从距离用户最近的服务器返回数据,尽快呈现给用户;通常情况下在CDN中缓存的是静态资源(html,js,css),达到动静分离;但是有时候遇到了某些数据访问量特别大的时候,后端会生成静态资源放入到CDN,比如:商城的首页,每个用户进入都需要访问的页面,如果每次请求都进入到后端,那么服务器的压力肯定不小,这种情况下会把首页生成静态的文件缓存到cdn和反向代理服务器

反向代理:部署在应用的中心机房,通常也是缓存的静态资源,当用户通过CDN未请求到需要的数据时,先进入反向代理服务器,如果有缓存用户访问的数据,那么直接返回给用户;这里也有特殊情况,对于有些场景下的热点数据,在这里根据用户的请求去分布式缓存服务器中获取,能拿到就直接返回。

这种架构已经把缓存做到了4级

第一级:CDN 缓存静态资源第二级:反向代理缓存静态资源以及部分热点数据第三级:应用服务器的本地缓存第四级:分布式缓存服务器

通常情况下经过了这4级缓存,能够进入到数据库的请求也不多了,很好的释放了数据库的压力


搜索引擎和NoSQL

随着业务的不断扩大,对于数据的存储和查询的需求也越来越复杂,通常情况我们需要引入非关系型数据库,比如搜索引擎和NoSQL数据库

有时候我们的查询场景很复杂,需要查询很多数据表,经过一系列的计算才能完成,这时候可以考虑通过数据同步工具(比如canal)拉去数据到大数据平台,使用批处理框架离线计算,把输出的结果存放到搜索引擎或者NoSQL数据库中,应用程序直接查询计算的结果返回给用户。也有可能我们需要汇总多个表的数据做一张宽表,方便应用程序查询

由于引入的数据存储方式增多,为了减轻应用程序的管理多个数据源的麻烦,需要封装统一数据访问模块,如果使用的时Java,可以考虑spring-data


业务纵向拆分

互联网公司通常的宗旨是小步迭代试错快跑,当业务发展到足够大,对于单体应用想要达到这个宗旨是有难度的,随着业务的发展,应用程序越来越大,研发、维护、发布的成本也越来越大,这时候就需要考虑根据业务把单体应用拆分为多个服务,服务之间可以通过RPC远程调用和消息队列来一起完成用户的请求。

由于业务的拆分,通常情况下也会相应的对数据库进行拆分,达到一个服务对应一个数据库的理想状态

引入MQ的好处:

提高系统的可用性:当消费服务器发送故障时,消息还在消息队列中,数据不会丢失加快请求的响应:当用户请求到达服务器后,把请求中可以异步处理的数据放入到MQ,让系统逐一消费,不需要用户等待,加快了响应速度削峰填谷:当大量请求都同时进入到系统之后,会全部放入到消息队列,系统逐一消费,不会对系统造成很大的冲击

总结

还有一个情况未谈及到,就是数据库的水平拆分,这也是数据库拆分的最后手段,只有当单表数据特别大,不能满足业务的需要才使用。使用最多的还是进行数据库的业务纵向拆分,把数据库中不同业务的数据放到不同的物理服务器上。

应用当前到底选择什么架构,一定要根据实际业务的需求进行灵活的选择,驱动技术架构发展的主要动力还是在于业务的发展,不要为了技术而技术。


写在最后

首先感谢大家可以耐心地读到这里。点关注,不迷路当然,文中或许会存在或多或少的不足、错误之处,有建议或者意见也非常欢迎大家在评论交流。最后,白嫖不好,创作不易,希望朋友们可以转发评论关注三连,因为这些就是我分享的全部动力来源

作者:Silently9527链接:https://juejin.cn/post/6903301691551498248

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。