大型网站架构的发展演变过程
什么是大型网站
如何定义一个网站是不是大型网站,一般我们会从两个纬度去考衡,访问量以及数据量,二者缺一不可。
我们以javaweb为例,来搭建一个简单的电商系统,从这个系统中来看系统的演变历史;要注意的是,接下来的演示模型,关注的是数据量、访问量提升,网站结构发生的变化, 而不是具体关注业务功能点。其次,这个过程是为了让大家更好的了解网站演进过程中的一些问题和应对策略。
假如我们系统具备以下功能:
用户模块:用户注册和管理
商品模块:商品展示和管理
交易模块:创建交易及支付结算
架构的发展演变过程
阶段一 单应用架构
网站的初期也可以认为是互联网发展的早起,我们经常会在单机上跑我们所有的程序和软件。
把所有软件和应用都部署在一台机器上,这样就完成一个简单系统的搭建,这个时候的讲究的是效率
单体架构的缺陷
1.复杂性高 整个项目包含的模块非常多,模块的边界模糊,依赖关系不清晰,代码质量参差不齐,整个项目非常复杂。每次修改代码都心惊胆战,甚至添加一个简单的功能,或者修改一个BUG都会造成隐含的缺陷。 2.技术债务逐渐上升 随着时间推移、需求变更和人员更迭,会逐渐形成应用程序的技术债务,并且越积越多。已使用的系统设计或代码难以修改,因为应用程序的其他模块可能会以意料之外的方式使用它。 3.部署速度逐渐变慢 随着代码的增加,构建和部署的时间也会增加。而在单体应用中,每次功能的变更或缺陷的修复都会导致我们需要重新部署整个应用。全量部署的方式耗时长、影响范围大、风险高,这使得单体应用项目上线部署的频率较低,从而又导致两次发布之间会有大量功能变更和缺陷修复,出错概率较高。 4.扩展能力受限,无法按需伸缩 单体应用只能作为一个整体进行扩展,无法结合业务模块的特点进行伸缩。 5.阻碍技术创新 单体应用往往使用统一的技术平台或方案解决所有问题,团队的每个成员都必须使用相同的开发语言和架构,想要引入新的框架或技术平台非常困难。 由于单体架构的缺陷日益明显,所以越来越多的公司采用微服务架构范式解决上面提到的单体架构中的问题。 不同于构建单一、庞大的应用,微服务架构将应用拆分为一套小且互相关联的服务。
阶段二 应用服务器和数据库服务器分离
随着网站的上线,访问量逐步上升,服务器的负载慢慢提高,在服务器还没有超载的时候,我们应该做好规划,提升网站的负载能力。假如代码层面的优化已经没办法继续提高,在不提高单台机器的性能,增加机器是一个比较好的方式,投入产出比非常高。这个阶段增加机器的主要目的是讲web服务器和数据库服务器拆分,这样不仅提高了单机的负载能力,也提高了容灾能力
阶段三 应用服务器集群-应用服务器负载告警,如何让应用服务器走向集群
随着访问量的继续增加,单台应用服务器已经无法满足需求。在假设数据库服务器还没有遇到性能问题的时候,我们可以增加应用服务器,通过应用服务器集群将用户请求分流到各个服务器中,从而继续提升负载能力。此时多台应用服务器之间没有直接的交互,他们都是依赖数据库各自对外提供服务
架构发展到这个阶段,各种问题也会慢慢呈现
- 用户请求由谁来转发到具体的应用服务器
- 用户如果每次访问到的服务器不一样,那么如何维护session
阶段四 数据库压力变大,数据库读写分离
架构演变到这里,并不是终点。上面我们把应用层的性能拉上来了,但是数据库的负载也在慢慢增大,那么怎么去提高数据库层面的负载呢?有了前面的思路以后,自然会想到增加服务器。但是假如我们单纯的把数据库一分为二,然后对于后续数据库的请求,分别负载到两台数据库服务器上,那么一定会造成数据库不统一的问题。所以我们一般先考虑读写分离的方式
这个架构的变化会带来几个问题
- 主从数据库之间的数据同步 ; 可以使用mysql自带的master-slave方式实现主从复制
- 对应数据源的选择 ; 采用第三方数据库中间件,例如mycat
阶段五 使用搜索引擎缓解读库的压力
数据库做读库的话,尝尝对模糊查找效率不是特别好,像电商类的网站,搜索是非常核心的功能,即便是做了读写分离,这个问题也不能有效解决。那么这个时候就需要引入搜索引擎了
使用搜索引擎能够大大提高我们的查询速度,但是同时也会带来一些附加的问题,比如维护索引的构建。
阶段六 引入缓存机制缓解数据库的压力
随着访问量的持续增加,逐渐出现许多用户访问统一部分内容的情况,对于这些热点数据,没必要每次都从数据库去读取,我们可以使用缓存技术,比如memcache、redis来作为我们应用层的缓存;另外在某些场景下,比如我们对用户的某些IP的访问频率做限制,那这个放内存中又不合适,放数据库又太麻烦,这个时候可以使用Nosql的方式比如mongDB来代替传统的关系型数据库
阶段七 数据库的水平/垂直拆分
我们的网站演进的变化过程,交易、商品、用户的数据都还在同一个数据库中,尽管采取了增加缓存,读写分离的方式,但是随着数据库的压力持续增加,数据库的瓶颈仍然是个最大的问题。因此我们可以考虑对数据的垂直拆分和水平拆分
垂直拆分:把数据库中不同业务数据拆分到不同的数据库
水平拆分:把同一个表中的数据拆分到两个甚至跟多的数据库中,水平拆分的原因是某些业务数据量已经达到了单个数据库的瓶颈,这时可以采取讲表拆分到多个数据库中
阶段八 应用的拆分
随着业务的发展,业务越来越多,应用的压力越来越大。工程规模也越来越庞大。这个时候就可以考虑讲应用拆分,按照领域模型讲我们的用户、商品、交易拆分成多个子系统。
这样拆分以后,可能会有一些相同的代码,比如用户操作,在商品和交易都需要查询,所以会导致每个系统都会有用户查询访问相关操作。这些相同的操作一定是要抽象出来,否则就会是一个坑。所以通过走服务化路线的方式来解决
那么服务拆分以后,各个服务之间如何进行远程通信呢?
通过RPC技术,比较典型的有:webservice、hessian、http、RMI等等
前期通过这些技术能够很好的解决各个服务之间通信问题,but,互联网的发展是持续的,所以架构的演变和优化还在持续。
总结
我们通过这个例子来讲解了电商网站的架构演进。我要强调一下,这个架构的演进不是某个网站真实的例子,实际上是通过这样一个演进过程给大家带来一个全局的观念和感受。以及给大家在后续课程学习过程中的一些思路。
如何把单击扩展到分布式
前面我们讲到了冯.诺依曼模型,计算机一共由5个部分组成,从用户角度来看,分布式系统就像一台超级计算机。理论上也应该由输入、输出、运算、存储和控制这5部分组成。
输入设备的变化
在分布式系统架构中,输入设备可以分两类,第一类是互相连接的多个节点,在接收其他节点传来的信息作为该节点的输入;另一种就是传统意义上的人机交互的输入设备了
输出设备的变化
输出和输入类似,也有两种,一种是系统中的节点向其他节点传输信息时,该节点可以看作是输出设备;另一种就是传统意义上的人际交互的输出设备,比如用户的终端
控制器的变化
在单机中,控制器指的是CPU中的控制器,在分布式系统中,控制器主要的作用是协调或控制节点之间的动作和行为;比如硬件负载均衡器;LVS软负载;规则服务器等
运算器
在分布式系统中,运算器是由多个节点来组成的。运用多个节点的计算能力来协同完成整体的计算任务
存储器
在分布式系统中,我们需要把承担存储功能的多个节点组织在一起,组成一个整体的存储器;比如数据库、redis(key-value存储)
原文地址:https://www.cnblogs.com/-wenli/p/10956930.html