大型网站技术架构

1.大型网站软件系统的特点

1)高并发,大流量

2)高可用

3)海量数据

4)用户分布广泛,网络情况复杂

5)安全环境恶劣

6)需求快速变更,发布频繁

7)渐进式发展

2.大型网站架构演化发展历程

(1)初始阶段的架构

应用程序、数据库、文件等所有的资源都在一台服务器上。


大型网站技术架构_第1张图片

(2)应用服务与数据服务分离

数据量增加,单台服务器性能及存储空间不足,需要将应用和数据分离,并发处理能力和数据存储空间得到了很大改善。

挑战:数据库压力太大导致访问延迟。


大型网站技术架构_第2张图片

(3)使用缓存改善网站性能

系统访问特点遵循二八定律,即80%的业务访问集中在20%的数据上。缓存分为本地缓存远程分布式缓存

本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况。

分布式缓存可以使用集群的方式,部署大内存的服务器作为专门的缓存服务器,可以在理论上做到不受内存容量限制的缓存服务。

缺点:单一应用服务器能够处理的请求连接有限,在网站访问高峰期,应用服务器成为网站的瓶颈。

(4)使用应用服务器集群改善网站的并发处理能力

使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,提升系统的并发处理能力,使得服务器的负载压力不再成为整个系统的瓶颈。

(5)数据库读写分离

应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库,这样当应用服务器读数据的时候,就可以通过从数据库获得数据。

(6)使用反向代理和CDN加速网站响应

为了应付复杂的网络环境和不同地区用户的访问,通过CDN和反向代理加快用户访问的速度,同时减轻后端服务器的负载压力。

CDN与反向代理的基本原理都是缓存,区别在于CDN部署在网络提供商的机房,使用户在请求网络服务时,可以从距离自己最近的网络提供商机房获取数据;而反向代理则部署在网站的中心机房,当用户请求到达中心机房后,首先访问的服务器是反向代理服务器,如果反向代理服务器中缓存着用户请求的资源,就将其直接返回给用户。

(7)使用分布式文件系统和分布式数据库系统

分布式数据库是网站数据库拆分的最后手段,只有在单表数据规模非常庞大的时候才使用。不到不得已的时候,网站更常用的数据库拆分手段是业务分库,将不同业务的数据库部署在不同的物理服务器上。

(8)使用NoSQL和搜索引擎

随着业务越来越复杂,对数据存储和检索的需求也越来越复杂,系统需要采用一些非关系型数据库如NoSQL和分数据库查询技术如搜索引擎。应用服务器通过统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。

(9)业务拆分

将一个网站拆分成许多不同的应用,每个应用独立部署维护。应用之间可以通过一个超链接建立关系,也可以通过消息队列进行数据分发,当然最多的还是通过访问同一个数据存储系统来构成一个关联的完整系统。

(10)分布式服务

既然每一个应用系统都需要执行许多相同的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。由这些可复用的业务连接数据库,提供共用业务服务,而应用系统只需要管理用户界面,通过分布式服务调用共用业务服务完成具体业务操作。


大型网站技术架构_第3张图片

3.网站架构模式

(1)分层

Ø应用层:负责具体业务和视图展示,如网站首页及搜索输入和结果展示

Ø服务层:为应用层提供服务支持,如用户管理服务,购物车服务等

Ø数据层:提供数据存储访问服务,如数据库、缓存、文件、搜索引擎等

(2)分割

如果说分层是将软件在横向方面进行切分,那么分割就是在纵向方面对软件进行切分。网站越大,功能越复杂,服务和数据处理的种类也越多,将这些不同的功能和服务分割开来,包装成高内聚低耦合的模块单元,一方面有助于软件的开发和维护;另一方面,便于不同模块的分布式部署,提高网站的并发处理能力和功能扩展能力。

(3)分布式

Ø分布式应用和服务

Ø分布式静态资源

Ø分布式数据和存储

Ø分布式计算

Ø分布式文件系统

Ø分布式配置

Ø分布式锁

(4)集群

多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务。

(5)缓存

CDN:即内容分发网络,部署在距离终端用户最近的网络服务商,用户的网络请求总是先到达他的网络服务商那里,在这里缓存网站的一些静态资源(较少变化的数据),可以就近以最快的速度返回给用户。

CDN能够缓存的一般是静态资源,如图片、文件、CSS、Script脚步、静态网页等。

反向代理:反向代理属于网站前端架构的一部分,部署在网站的前端,当用户请求到达网站的数据中心时,最先访问到的就是反向代理服务器,这里缓存网站的静态资源,无需将请求继续转发给应用服务器就能返回给用户。

反向代理功能

1)安全:来自互联网的访问请求必须经过代理服务器,相当于在Web服务器和可能的网络攻击之间建立了一个屏障

2)可以通过配置缓存功能加速Web请求

3)负载均衡

本地缓存:在应用服务器本地缓存着热点数据,应用程序可以在本机内存中直接访问数据,而无需访问数据库。

分布式缓存:大型网站的数据量非常庞大,即使只缓存一小部分,需要的内存空间也不是单机能承受的,所以除了本地缓存,还需要分布式缓存,将数据缓存在一个专门的分布式缓存集群中,应用程序通过网络通信访问缓存数据。

(6)异步

异步架构是典型的生产者消费者模式。使用异步消息队列有如下特性:

Ø提供系统的可用性

Ø加快网站消息速度

Ø消除并发访问高峰

(7)冗余

服务器冗余运行,数据库冗余备份。数据库的冷备份和热备份

(8)自动化

(9)安全

4.核心要素

架构是“最高层次的规划,难以改变的规定”。主要关注五个要素:

Ø性能

Ø可用性(Availability)

Ø伸缩性(Scalability)

Ø扩展性(Extensibility)

Ø安全性

5.性能优化

根据网站分层架构,可以分为三大类:

(1)Web前端性能优化

1)浏览器访问优化

Ø减少http请求

Ø使用浏览器缓存

Ø启用压缩

ØCSS放在页面最上面,JavaScript放在页面最下面

Ø减少Cookie传输

2)CDN加速:本质是一个缓存,一般缓存静态资源

3)反向代理

(2)应用服务器性能优化:主要手段有缓存、集群、异步

Ø分布式缓存(网站性能优化第一定律:优化考虑使用缓存优化性能)

Ø异步操作(消息队列,削峰作用)

Ø使用集群

Ø代码优化

a)多线程(设计为无状态,使用局部对象,并发访问资源使用锁)

b)资源复用(单例,对象池)

c)数据结构

d)垃圾回收

(3)存储服务器性能优化

a)机械硬盘vs.固态硬盘

b)B+树vs. LSM树

c)RAID vs. HDFS

6.应用服务器集群的Session管理

集群环境下,Session管理主要有以下几种手段:

(1)Session复制

应用服务器开启Web容器的Session复制功能,在集群中的几台服务器之间同步Session对象,使得每台服务器上都保存所有用户的Session信息,这样任何一台机器宕机都不会导致Session数据丢失,而服务器使用Session时,也只需要在本机获取即可。

(2)Session绑定

Session绑定可以利用负载均衡的源地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上,这样在整个会话期间,用户所有的请求都在同一台服务器上处理。

(3)利用Cookie记录Session

(4)Session服务器

利用独立部署的Session服务器统一管理Session,应用服务器每次读写Session时,都访问Session服务器。

7.高可用的服务策略

(1)分级管理

运维上将服务器进行分级管理,核心应用和服务优先使用更好的硬件,在运维响应速度上也格外迅速。

(2)超时设置

在应用程序中设置服务调用的超时时间,一旦超时,通信框架就抛出异常,应用程序根据服务调度策略,可选择继续重试或将请求转移到提供相同服务的其他服务器上。

(3)异步调用

应用对服务的调用通过消息队列等异步方式完成,避免一个服务失败导致整个应用请求失败的情况。

(4)服务降级

在网站访问高峰期,服务可能因为大量的并发调用而性能下降,严重时可能会导致服务宕机。为了保证核心应用和功能正常运行,需要对服务进行降级。降级有两种手段:拒绝服务和关闭服务。

拒绝服务:拒绝低优先级应用的调用,减少服务调用并发数,确保核心应用正常使用;或者随机拒绝部分请求调用,节约资源,让一部分请求得以成功,避免要死大家一起死的惨剧。

关闭功能:关闭部分不重要的服务,或者服务内部关闭部分不重要的功能,以节约系统开销,为重要的服务和功能让出资源。

(5)幂等性设计

在服务层保证重复调用和调用一次产生的结果相同,即服务具有幂等性。

8.负载均衡

(1)HTTP重定向负载均衡

(2)DNS域名解析负载均衡

(3)反向代理负载均衡

(4)IP负载均衡

(5)数据链路层负载均衡

数据链路层负载均衡是指在通信协议的数据链路层修改mac地址进行负载均衡。在Linux平台上最好的链路层负载均衡开源产品是LVS。

9.分布式缓存的一致性Hash算法

一致性Hash算法通过一个叫做一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射,如下图所示:

具体算法过程是:

①先构造一个长度为0~2^32(2的32次幂)个的整数环(又称:一致性Hash环),根据节点名称的Hash值将缓存服务器节点防置在这个Hash环中,如上图中的node1,node2等;

②根据需要缓存的数据的KEY值计算得到其Hash值,如上图中右半部分的“键”,计算其Hash值后离node2很近;

③在Hash环上顺时针查找距离这个KEY的Hash值最近的缓存服务器节点,完成KEY到服务器的Hash映射查找,如上图中离右边这个键的Hash值最近的顺时针方向的服务器节点是node2,因此这个KEY会到node2中读取数据;

当缓存服务器集群需要扩容的时候,只需要将新加入的节点名称(如node5)的Hash值放入一致性Hash环中,由于KEY总是顺时针查找距离其最近的节点,因此新加入的节点只影响整个环中的一部分。如下图中所示,添加node5后,只影响右边逆时针方向的三个Key/Value对数据,只占整个Hash环中的一小部分。

最后,设置虚拟节点提高平衡性

10.如何设计一个秒杀系统

秒杀架构设计理念

限流:鉴于只有少部分用户能够秒杀成功,所以要限制大部分流量,只允许少部分流量进入服务后端。

削峰:对于秒杀系统瞬时会有大量用户涌入,所以在抢购一开始会有很高的瞬间峰值。高峰值流量是压垮系统很重要的原因,所以如何把瞬间的高流量变成一段时间平稳的流量也是设计秒杀系统很重要的思路。实现削峰的常用的方法有利用缓存消息中间件等技术。

异步处理:秒杀系统是一个高并发系统,采用异步处理模式可以极大地提高系统并发量,其实异步处理就是削峰的一种实现方式。

内存缓存:秒杀系统最大的瓶颈一般都是数据库读写,由于数据库读写属于磁盘IO,性能很低,如果能够把部分数据或业务逻辑转移到内存缓存,效率会有极大地提升。

可拓展:当然如果我们想支持更多用户,更大的并发,最好就将系统设计成弹性可拓展的,如果流量来了,拓展机器就好了。像淘宝、京东等双十一活动时会增加大量机器应对交易高峰。

设计思路

1)将请求拦截在系统上游,降低下游压力:秒杀系统特点是并发量极大,但实际秒杀成功的请求数量却很少,所以如果不在前端拦截很可能造成数据库读写锁冲突,甚至导致死锁,最终请求超时。

2)充分利用缓存:利用缓存可极大提高系统读写速度。

3)消息队列:消息队列可以削峰,将拦截大量并发请求,这也是一个异步处理过程,后台业务根据自己的处理能力,从消息队列中主动的拉取请求消息进行业务处理。

前端方案

页面静态化:将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素。通过CDN来抗峰值。

禁止重复提交:用户提交之后按钮置灰,禁止重复提交。

用户限流:在某一时间段内只允许用户提交一次请求,比如可以采取IP限流。

后端方案

1)服务端控制器层(网关层)

限制uid(UserID)访问频率:我们上面拦截了浏览器访问的请求,但针对某些恶意攻击或其它插件,在服务端控制层需要针对同一个访问uid,限制访问频率。

2)服务层

上面只拦截了一部分访问请求,当秒杀的用户量很大时,即使每个用户只有一个请求,到服务层的请求数量还是很大。比如我们有100W用户同时抢100台手机,服务层并发请求压力至少为100W。

采用消息队列缓存请求:既然服务层知道库存只有100台手机,那完全没有必要把100W个请求都传递到数据库啊,那么可以先把这些请求都写到消息队列缓存一下,数据库层订阅消息减库存,减库存成功的请求返回秒杀成功,失败的返回秒杀结束。

利用缓存应对读请求:对类似于12306等购票业务,是典型的读多写少业务,大部分请求是查询请求,所以可以利用缓存分担数据库压力。

利用缓存应对写请求:缓存也是可以应对写请求的,比如我们就可以把数据库中的库存数据转移到Redis缓存中,所有减库存操作都在Redis中进行,然后再通过后台进程把Redis中的用户秒杀请求同步到数据库中。

数据库层

数据库层是最脆弱的一层,一般在应用设计时在上游就需要把请求拦截掉,数据库层只承担“能力范围内”的访问请求。所以,上面通过在服务层引入队列和缓存,让最底层的数据库高枕无忧。

http://brianway.github.io/2017/01/18/reading-note-architecture-design/#top

你可能感兴趣的:(大型网站技术架构)