【已填坑】从一个小的网站项目到大型项目要跨越什么?网站架构进化史

最近自己在练手一个小型的网站,结合团队这几个月的开发项目以及看的一本书《程序员修炼之道》,突然在思考一个问题:一个小型的网站和一个大型的网站最主要的区别是什么?因为这些区别遇到了什么问题?为了解决这些问题诞生了哪些技术?
我预感:如果能够把这个问题捋一捋捋清楚,那么对我接下来的技术栈的积累以及对于工具的定位使用会有更好的帮助。
我会先尝试给出自己的答案,然后再搜集资料慢慢把这条线捋清楚。(从单机系统到如今的能承受几E流量的系统。)

0. 最本质的区别,最核心的追求

小型系统与大型系统最本质的区别在于:人流量。一个小的小型系统可能摊下来一天个位数的访问,但是一个大型系统一天可能有上E的流量,并且这种流量存在局部性特征——时间局部性与空间局部性,提一嘴,我一直觉得局部性原理是计算机体系中最美的定理之一,也是工程师追求不可能三角中最好的帮手。

0.1 时间局部性

时间局部性是指:访问系统的流量不是服从均匀分布的,它更可能是在某一个时间点突然爆发性地涌入(例如双十一0点,鹿晗宣布恋情)。

0.2 空间局部性

空间局部性是指:访问系统的流量不是服从地域上的均匀分布的,流量来源可能集中来自某一个区域,该区域一般会有这样一个特征:

  1. 集中了大量人群;
    例如,足球比赛、演唱会。

这两个局部性并不是互斥,它们更可能是同时发生。
当它们发生时,会带来什么影响:对系统的各个(甚至可能是某个)节点造成极大的访问压力,一旦某个节点没顶住压力,就会造成整个系统的瘫痪与宕机。因为现如今的系统往往采取分布式结构,就像人体的器官,各个系统节点各司其职维持系统的正常运作。一旦少了谁,直接瘫痪。
回到主题,问题已经在这里了,回避不了,那我们追求一个什么样的结果呢?——快,准,即响应要快,结果要准。相信我,现在要是网页响应超过5S大家一定会把投诉电话打包。
在数据流量爆炸的场景下,仍然要保持“快,准”的追求,这个时候,就是工程师们斗智斗勇的时刻了,而这也开启网站系统架构的升级打怪之路。

1. 最原始的架构——单点结构

场景一:我要开始创业了,想做一个中国的亚马逊在线商城,受限于资金以及保险起见,我得先验证我的商业逻辑,此时我决定先花一点钱做出这个网站并上线,验证这个idea是否有市场。
最开始的网站架构都是单点结构,把Web程序、数据库、相关文件等放在同一台服务器上,特别适合个人捣鼓学习框架或者弄一个小博客。一般这个阶段考虑的是把网站搭起来且能用,不会追求性能上的表现,功能相对简单,主要是提供一些信息的展示和提供一些文件数据的下载。
一般的系统
服务器系统:Linux;
数据库:Mysql、SqlServer、Oracle;
Web程序:Maven+SSH,Maven + Spring + Spring MVC + Mybatis;Django+mysql。
在这里插入图片描述

2. 开启分工——web系统与数据库分离

场景二:网站上线之后访问量逐步上升,服务器的负载慢慢提高,通过访问数据我发现服务器的性能在开始逼近极限,预计在2-3个月后服务器将无法承受这个负载,这时我们开始第一次升级。
我们在对数据的传递链路review的时候发现:

  1. 对于Web程序,它的功能是为尽可能多的客户提供连接响应以及业务服务,它需要一个强大的CPU;
  2. 对于数据库来说,它的功能是数据的存取以及安全性,它需要一个更大的磁盘保证能存放尽可能多的数据,需要一个足够大的缓冲保证尽可能高的数据IO吞吐量;
  3. 对于文件系统来说,它的功能是存储一些用户上传的文件资源,它需要一个更大的磁盘;
    找一台同时满足上面需求的服务器难,成本也不可控,但找三台分别满足上面需求的服务器很简单,因此我们决定将这三部分分别使用三个具有对应功能的服务器进行存放。此时结构如图:
    在这里插入图片描述
    此时不仅提高了单台机器的负载能力,也提高了容灾能力,降低修复成本。三台服务器同时坏的概率会比一台服务器坏的概率低,缺点是一台服务器罢工就会导致整个服务链路的崩溃,因此此时维护成本会提高。
    这个时候要解决的问题主要是各个系统之间的通信与连接(分布式系统)。

3. 引入缓存,克服数据库IO瓶颈

场景三:我的idea那是真不错,流量蒸蒸日上,看着后台的数据我做梦都笑醒。但此时,我收到了越来越多的老用户的吐槽,他们纷纷向我反映系统越来越卡,体验越来越差。以客户的满意为追求的我怎么能忍受这种情况的发生,马上update!
通过分析,我们了解到瓶颈在于数据库的IO,每个人每访问一次网站上的某个商品都会发生一次数据库的读写IO。读要时间,写也要时间。这时,聪明的我发现:某些热门商品的数据读出来以后,可以不用马上写回数据库,因为这些商品的数据大概率还会再次被访问到,即二八定律(计算机叫局部性原理)。因此,我们可以设置缓存专门存储商品数据,隔一段较长时间才把数据写回数据库。
果然改善了用户体验。
缓存又分为Web程序的本地缓存和使用专门的缓存服务器,本地缓存容量小但相对成本低,连接管理较为方便,缓存服务器成本高但性能更加强大,可缓存更多的数据。
此时的系统架构图:
在这里插入图片描述
引入的新技术:
缓存数据库:redis。

4. 负载均衡,持续升级

场景四:我想我应该是踩中风口了,访问量还在上升,开始有投资人来找我了~啊呸,这个时候我的老用户又在跟我发牢骚:“怎么回事,我买个单花费的时间怎么越来越久,要转好久的圈圈!”秉承用户第一的原则,我又开始了优化模式。
原来是因为流量的激增,单点的web服务已经逼近到极限,开始出现较大的延迟。如果更换CPU更快的服务器,那么是解决不了问题的。CPU的处理性能的提升速度根本赶不上流量的增长速度,最好的方法是提供多台web服务器,并使用反向代理服务器将海量的用户连接请求分散到不同的web服务器上去处理。这才是应对流量激增而单点处理能力更不上的方法。
与此同时,由多台服务器构成的web服务集群也具有伸缩性,可根据不同的时段(比如大促时期)选择性地增加或减少服务器,更好地应对变化。
在这里插入图片描述
这时,单点的服务器不再称为局限。

负载均衡:将客户端的请求按照一定的规则分配到一群服务器上,并将处理结果返回给相应的客户端。
引入的新技术:
负载均衡调度器:可分为硬件或软件,甚至纯算法。
1.单独的专门做负载均衡的硬件设备。如F5,工作在网络层
2.软件方式,不需要特定的设备。如nginx,工作在应用层

5. 将数据库继续优化——读写分离

场景五:已经拿到风投的我笑嘻嘻得看着数据,梳理数据流,分析状态。突然发现,数据库在写数据回去的时候会严重限制读操作,这里存在一个潜在的优化点。
通常写的数据不一定是读的数据,但是写的数据一定会妨碍数据的读取,此时的我手握大把钞票,直接上两台数据库服务器,主从数据库,主数据库负责写操作,从数据库负责读操作,通过设置立即更新策略:使得主从数据库保持一致。读写分离,进一步提升IO速度。
在这里插入图片描述
引入的新技术:
读写分离:主从数据库,主数据库负责写操作,从数据库负责读操作。
大部分数据库都支持主从模式。
需要支出额外的成本:数据库服务器数量翻倍。
优势:更高的抵御风险能力,一旦遭遇宕机可马上进行主从切换。

6. CDN+反向代理

场景六:A轮融资,有人称呼我们为中国的亚马逊。正当业务蒸蒸日上的时候,大西北地区的小伙伴打来电话说他们那边打开网站很慢,响应不及时。作为一个用户体验至上的团队,不能忍。
首先解决的是打开网站慢的问题。打开网站的流程简单讲就是:客户端请求资源->服务器返回请求的资源->客户端展示页面。
由于偏远地区可能离我们的机房太远,所以导致资源请求和返回的时间过长,那么我们怎么办呢?全中国建机房也不太现实。答案是:CDN(Content Delivery Network,内容分发网络)。CDN简单说就是使用其他人的服务器存放自己的网站数据,当附近有人请求网站数据时,直接利用CDN的服务器将资源返回给请求方;不存在就将请求发送到服务器。(就是租了别人分布在世界各地的仓库)
在这里插入图片描述
反向代理则是另一种方法,用户将请求发送到反向代理服务器后,反向代理服务器会检查自己的缓存是否存放用户所要请求的资源,如果有则直接返回资源给客户端;否则会从服务器集群中(负载均衡+一组服务器构成)选择合适的服务器组,将请求交由该服务器组处理。

正向代理是内网通过代理访问外网,这个代理就是正向代理。而反向代理是指,外网通过代理访问内网,那这个代理就是反向代理。

反向代理软件:nginx,CDN
负载均衡和反向代理的区别:https://zhuanlan.zhihu.com/p/345647607
我个人理解反向代理与负载均衡的区别在于:反向代理自己本身具有处理请求返回资源的能力,并且具备转发请求的能力;而负载均衡只是作为一个请求分发的角色存在,本身不具备处理请求返回资源的能力。
CDN和nginx往往可以打包一起使用,什么都好,就是贵。
CDN和nginx还有一个好处:减少网络拥塞。

7. 全面分布式

场景七:在过去的717大促中,网站的数据十分优秀,营业额翻了几十倍,真可谓是春风得意马蹄疾,一日看尽长安花。但是我嗅到了一丝危险的味道:主从数据库的访问能力几乎到了极限,所幸这次大促顶住了,但下次可能就没这么幸运了。为此,我们要把危险消灭于无形中。
方法是将多个数据库服务器组织成一个分布式数据库系统,将数据分开存储。(每个数据库服务器仍旧由一组主从数据库服务器构成)。
分开存储的方法就是分库分表。分表是数据库内部表层面的操作,分库是在数据库之间做的操作。

分库分表就是按照一定的规则,对原有的数据库和表进行拆分,把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上

同理,文件系统也采用分布式文件系统,将文件分开保存。
分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才使用。不到不得已时,网站更常用的数据库拆分手段是业务分库,将不同业务的数据库部署在不同的物理服务器上。(游戏一般采用一些特殊的映射规则,比如id哈希)
在这里插入图片描述
分布式数据库:mongo
话说CDN和反向代理存放的就是最常访问的资源,这背后又是局部性原理。

8. 引入NoSQL和搜索引擎

场景八:随着流量的节节攀升,公司的关注度也越来越高,我也隐隐成了明日之星(飘了)。但是随着售卖的商品的数量和种类更是种类繁多,有一个问题开始逐渐成为业务场景中的阻塞环境,导致用户体验极具下降。这个环节就是?猜一猜嘛,提示我们对数据库做了一波升级之后,数据的存储已不再是瓶颈。
答案是:数据的检索。在浩瀚如海的数据中,准确且快速得查找出用户需要的数据,这成了我们新的挑战。
解决方法有一套:引入NoSQL数据库和搜索引擎。

其实关于Mysql的优化也是持续进行,但是这不在本篇的讨论范围,所以就不深究如何对MySQL进行查询优化,在这里简单提一下MySQL的一些优化思路(分库分表也是一种):参考文章:https://developer.aliyun.com/article/779151
一、避免不走索引的场景
二、SELECT语句其他优化
三、增删改 DML 语句优化
四、查询条件优化
五、建表优化

在这里先解释一些什么是NoSQL数据库

NoSQL数据库是一类数据库的泛指,一般来说NoSQL数据库指的是非关系型数据库,更指的是Not only SQL。常见的如redis、mongo都属于NoSQL数据库。
惯例贴文章:

https://zhuanlan.zhihu.com/p/269227465
https://developer.aliyun.com/article/96769

在这里插入图片描述
NoSQL的强项在于检索数据,同时对于支持多种多样的数据类型,比如JSON、图片、文档都可以存储在NoSQL数据库。
新的技术:
强大的搜索引擎
NoSQL数据库服务器:Mongo、redis

9. 对业务拆分

场景九:随着流量的攀升,我们开始在网站上上线了越来越多的业务,比如可以看直播的“大卖场”,可以点外卖的“饱了么”,可以看房子的“今日有套房”。然后,服务器又一次亮起了红灯,咋回事?原因很简单,太多的业务堆叠在同一套系统中,当这些业务的流量持续提升时,最终会导致该系统逼近极限从而崩溃。类似地,我们要杜绝潜在的隐患。
方法是:对业务进行梳理将其分为不同的产品线,每个产品线对应不同的应用,应用之间独立部署,应用之间通过超链接跳转或者消息队列的方式进行通信协作,并且通过访问同一套数据存储系统来保障彼此之间成为一个完整的关联系统。
在这里插入图片描述
关于各个业务之间的架构安排以及服务调用其实也是很深的技术活,在这里我们极度抽象了模型,简化了很多内部细节,限于笔者目前功力有限,也只能简单地说个大概。

服务器(进程间)通信方式:
消息队列:rabbitMQ

10. 分布式服务

场景十:公司目前已经走到独角兽规模,各项业务都是芝麻开花节节高,业务也越来越多,存储越来越庞大,整体复杂度急剧上升,部署维护越来越困难。我们决定对应用服务进行新一轮的分工细化,让各个业务系统只专注于自己专属的独有的业务,把一些公共支撑的功能抽出来作为中间件服务对外提供服务。这么做的目的在于为单点业务进行减负,同时通过分布式服务调用保证整个业务的连续性与完整性不被破坏。
在这里插入图片描述

一般来说,业务数量多的大公司会把统一数据访问模块、统一登陆模块都设置为中间件,对集团所有业务提供相关的支持,为的是追求复用、专注、敏捷、安全。
例如微服务架构,RPC框架都可以用于解决业务间调用。

https://blog.csdn.net/u011474078/article/details/81427579

总结

整个演变轨迹是沿着一些可见的思路在进行:

  1. 分析链路,寻找问题节点;
  2. 对于性能薄弱的点,有两种解决方式:
    1. 将单点服务器变为集群;
    2. 将该服务器上的业务进行拆分,按照关联度从低到高一个个抽离,抽离出的业务会安排到其它服务器;
  3. 重复上述过程。

待解决的问题

  1. 高并发模式下的数据安全保障,包括不限于:数据库层面的保障、所使用的语言层面的保障、框架本身的并发支持、通过不同的编码方式保障。
  2. 各个系统之间的通信模型,是使用HTTP还是RPC还是其它?有什么优点和缺点?

参考:

  1. https://www.cnblogs.com/jakey-hong/p/11216363.html
  2. 李智慧《大型网站技术架构》
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值