架构的含义:

一种比较通俗的说法是"最高层次的规划,难以改变的决定"这些规划和决定奠定了事物未来发展的方向和最终蓝图。具体到软件架构,系统的各个重要组成部分及其关系构成了系统的架构,这些组成部分可以是具体的功能模块,也可以是非功能的设计和决策,他们相互关联组成一个整体。共同构成软件系统的架构。

5个架构要素:

性能、可用性、伸缩性、扩展性、安全性

架构设计中需要平衡这5个要素之间的关系以实现需求和架构目标

 

 

性能

性能是网站的一个重要指标,除非没得选择(例如:12306)。否则用户无法忍受一个响应缓慢的网站。

衡量性能手段:响应时间,并发数,吞吐量

性能优化:

性能问题无处不在,所以优化的手段也非常多,从用户浏览器到到数据库,影响用户请求的所有环节都可以进行性能优化

Web前端性能优化:

一般来说,Web前端指网站业务逻辑之前的业务,包括浏览器加载,网站视图模型,图片服务,CDN服务可以通过浏览器缓存,使用页面压缩,合理布局页面,减少cookie传输,主要优化手段有优化浏览器访问、使用方向代理、CDN等

一、浏览器访问优化:

1、减少http请求:Http是无状态的应用层协议,意味着每次Http请求都需要简历通信链路进行数据传输。在服务器端每个Http都需要独立的线程去处理,这些通信和服务的开销都很昂贵,减少Http请求的数目可有效提高性能访问。主要手段有合并css,合并javaScript,合并图片(多张图片通过一张图片由样式偏移区分)。

2、使用浏览器访问:对于一个网站而言,CSS、javaScript、Logo、图标这些静态资源更新的频率都比较低,而这些文件又是每次http请求都需要的,所以可以考虑将这些资源缓存在浏览器端,可以极好的改善性能。

3、启用压缩:在服务端对文件进行压缩,在浏览器端进行解压缩,可有效减少通信传输的数据量。

4、减少cookie传输:Cookie包含在每次请求和响应中,太大的Cookie会严重影响数据传输,因此那些数据需要写入Cookie需要慎重考虑,尽量减少Cookie中传输的数据量。

二、CDN(内容分发网络)加速:

CDN本质任然是一个缓存,而且将数据缓存在用户最近的地方,使用户以最快的速度获取数据,即所谓网络访问第一跳,CDN能够缓存的一般是静态资源,将其缓存在CDN可极大的改善网页的打开速度。

三、反向代理:

方向代理在网站架构中的作用很多,作为请求总入口,可以保护网站安全(过滤请求等。。)、通过负载均衡改善网站高并发情况下的性能、配置缓存(静态资源)功能加速Web请求。

应用服务器端优化:

应用服务器就是处理网站业务的服务器,网站的业务代码都部署在这里,是网站开发最复杂,变化最多的地方,优化的手段有缓存、集群、异步等。

一、缓存:

网站性能优化第一定律:优先考虑使用缓存优化性能。

缓存指将数据存储在较高访问速度的存储介质中,以供系统处理。一方面缓存访问速度快,可以减少数据访问的时间,另一当面如果缓存的数据是经过计算处理得到的,那么被缓存的数据无需重复计算可直接使用,因此缓存还起到计算计算时间的作用。

网站数据访问通常遵循二八定律,即80%的访问落在20%的数据上,因此可以利用将这20%的数据缓存起来,可很好的改善系统性能,提高数据访问能力,降低存储访问压力。

二、异步操作:

将用户请求发送至消息队列等待后续任务处理,而当前请求直接返回响应给用户。

在不使用消息队列的情况下,用户的请求数据直接写入数据库,在高并发的情况下,会对数据库造成很大的压力,同时也使得响应延迟加剧,在使用消息队列后,用户请求的数据发送给消息队列后立即返回,再由消息队列的消费者进程从消息队列中获取数据异步写入数据库,用户的响应延迟可得到有效改善。消息队列还具有很好的削峰作用--即通过异步处理,将短时间高并发产生的事物消息存储在消息队列中,从而削平高峰期的并发事务。

三、集群:

一台用户服务器处理能力始终有限,此时我们应该增加多台服务器分担压力。

在网站高并发的场景下,使用负载均衡技术作为一个应用构建一个由多台服务器组成的服务器集群,将并发请求分发到多台服务器上处理,避免单一服务器因负载压力过大而响应缓慢,使用户请求具有良好的响应延迟。

 

 

可用性

网站可用性:网站可有效访问特性

对于大型网站而言,特别是知名网站,网站宕掉,服务不可用是一个重大事故。

网站的高可用架构设计的目的就是保证服务器硬件故障时,服务依然可用,数据依然保存并能够被访问。

主要手段:

实现高可用架构的主要手段是数据和服务的冗余备份及失效转移,一旦某些服务器宕机,就将服务切换到其他可用的服务器上,如果磁盘损坏,则从备份的磁盘读取数据。

高可用的应用:

应用层主要处理网站应用的业务逻辑,因此有时也被称为业务逻辑层,应用的一个显著特点是应用无状态性(无状态应用是指应用服务器不保存业务的上下文信息,而仅根据每次请求提交的数据进行相对应的业务逻辑处理,多个服务器实例完全对等,请求到任意服务器,处理结果都是完全一样的),因此实现集群很方便,不过也有一些需要注意的地方。

一、通过负载均衡进行无状态服务的失效转移:

当Web集群中有一台应用服务器宕机时,负载均衡通过心跳检测机制发现该服务器失去响应,就会把它从服务器列表中剔除,而将请求发送到其他服务器上面。

二、应用服务器集群的Session管理:

应用服务器的高可用架构设计主要基于服务无状态这一特性,但是事实上,业务总是有状态的,例如在社交网站中,需要记录用户的当前登录状态,Web应用中将这些多次请求修改使用的上下文对象称作会话(Session)。在单机应用中,会话交由Web容器管理(tomcat等),在集群中,请求可能被分发到任意一台应用服务器中,所以摆正每次请求依然能够获得正确的Session比单机要复杂的多,通过在集群中有以下手段处理Session问题

1、Session复制:

顾名思义,多台服务器之间进行Session的复制,这种方案早期有被使用,而现在有的大型网站核心应用集群就是数千台服务器,这种方案显然不合理。因此这种方案只适合小型集群。

2、利用Cookie记录Session:

将Session记录在客户端,每次请求服务器的时候,将Session放在请求中发送给服务器,服务器处理完请求后再将修改过的Session响应给客户端。

利用Cookie记录session也有一定的缺陷,比如受Cookie大小限制(H5新增LocalStore容量比cookie大)能记录的信息有限、还有一个前面有提到过,每次请求都需要传输Cookie影响性能、如果用户关闭Cookie,访问就会不正常。但是由于Cookie的简单易用,可用性高,支持应用服务器的线性伸缩,而大部分应用需要记录的Session信息又比较小。因此事实上,许多网站都或多或少地使用Cookie记录Session。

3、Session服务器;

session服务器是现在常用的解决方案,利用独立部署的Session服务器(redis比较常用)统一管理Session,应用服务器 每次读写Session时,都访问Session服务器。

这种解决方案事实上是将服务器的状态分离,分为无状态的应用服务器和有状态的Session服务器,然后针对这两种服务器的不同特性分别设计其架构。

高可用的服务:

可复用服务模块为业务产品提供基础公共服务,大型网站中这些服务通常都独立分布式部署,被具体应用远程调用。可复用的服务和应用一样,也是无状态服务,因此也可以通过负载均衡结合集群实现高可用,不过有一些服务策略需要注意。

一、分级管理

运维上将服务器分级管理,核心应用和服务优先使用更好的硬件。

二、超时设置

由于服务器宕机、线程死锁等原因,可能导致应用程序对服务端调用失去响应,进而导致用户请求长时间得不到响应。在应用程序中设置超时时间,一旦超时,通信框架抛出异常,应用程序根据服务调度策略,选择转移或者重试。

三、异步调用

高可用的数据

对许多网站而言,数据是其最宝贵的资源,保护网站的数据就是保护企业的命脉。

一、数据备份

数据备份是一种古老又有效的数据保护手段。通常有数据冷备和数据热备份两种方案。数据冷备指的是定期将数据复制到某种存储介质中,一旦系统存储损坏,就从冷备的存储数据中恢复数据。数据热备份就是现在常见的主从复制,读写分离。操作数据时,对主数据库进行写入操作,之后同步至从数据库。

二、失效转移

数据服务器集群和应用服务器集群并无差异,宕机时需要转移。

 

 

伸缩性

网站的伸缩性是指不需要改变网站的软硬件设计,仅仅通过改变部署的服务器数量就可以扩大或者缩小网站的服务处理能力。

网站的伸缩性设计可分为两类,一类是根据功能进行物理分离实现伸缩,一类是单一功能通过集群实现伸缩。前者是不同的服务器部署不同的服务,提供不同的功能;后者是集群内多台服务器部署相同的服务,提供相同的功能。

不同功能进行物理分离实现伸缩:

网站发展早期--通过增加服务器提高网站处理能力时,新增服务器总是从现有服务器中分离部分功能和服务。每次分离都会有更多地服务器加入网站,使用新增的服务器处理某种特定的服务。

单一功能通过集群规模实现伸缩:

将不同的功能分离部署可以实现一定程度的伸缩性,但是随着网站访问量的逐步增加,即时分离到最小粒度的独立部署,单一的服务器也不能满足业务规模的要求。因此必须使用服务器集群,即将相同服务部署在多台服务器上构成一个集群整体对外提供服务。

一个具有良好伸缩性架构设计的网站,其设计总是走在业务发展的前面,在业务需要处理更多的访问和服务之前,就已经做好充足准备,当业务需要时,只需要购买或者租用服务器简单部署实施就可以了。

 

 

扩展性

指对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力。表现在系统基础设施稳定不需要经常变更,应用之间较少依赖和耦合,对需求变更可以敏捷响应。当系统新增新功能时,不需要对现有系统的结构和代码进行修改。

主要手段

利用分布式消息队列降低系统耦合性

如果模块之间不存在直接调用,那么新增模块或者修改模块就对其他模块影响最小,这样系统的可扩展性无疑更好一些。消息队列(kafka等)利用发布--订阅模式工作,消息发送者发布消息,一个或者多个消息接收者订阅消息。对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站的可扩展设计。

利用分布式服务打造可复用的业务平台

使用分布式服务是降低系统耦合性的另一个重要手段。如果说分布式消息队列通过消息对象分解系统耦合性,不同子系统处理同一个消息;那么分布式服务则通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用。

 

 

安全性

衡量网站安全架构的标准就是针对现存和潜在的各种攻击与窃密手段。是否有可靠的应对策略。

XSS攻击

XSS攻击即跨站点脚本攻击,指黑客通过纂改网页,注入恶意的HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。

防护手段主要有

1、消毒:

XSS攻击者一般都是通过在请求中嵌入恶意脚本达到攻击的目的,这些脚本是一般用户输入中不使用的,如果进行过滤和消毒处理,即对某些HTML关键字符转义(“>“转义成“&gt”),就可以防止大部分攻击。

2、HttpOnly:

最早由微软提出,即浏览器禁止页面JavaScript访问带有HttpOnly属性的Cookie。对于敏感信息的Cookie(如用户认证信息),可通过对该Cookie添加HttpOnly属性,避免被攻击脚本窃取。

sql注入攻击

攻击者在http请求中注入恶意SQL命令,服务器用请求参数构造数据库SQL命令时,恶意SQL被一起构造,并在数据库中执行。

防护手段主要有

1、消毒:

和防XSS攻击一样,请求参数消毒是一种简单粗暴又有效的手段。

2、参数绑定:

使用预编译手段,绑定参数是最好芳SQL注入方法。目前许多数据访问层框架,如mybatis,Hibernate等,都实现SQL预编译和参数绑定,攻击者的恶意SQL会被当做SQL的参数,而不是SQL命令被执行。

CSRF攻击

CSRF(跨站点请求伪造),攻击者通过跨站点请求,以合法用户的身份进行非法操作,主要手段是利用跨站请求,在用户不知情的情况下,以用户的身份伪造请求。其核心是利用浏览器Cookie和Session策略,盗取用户身份。

防护手段主要有:

1、表单Token

CSRF是一个伪造用户请求的操作,所以需要构造用户请求的所有参数才可以。表单Token通过在请求参数中增加随机数的办法来阻止攻击者获得所有请求参数:在页面表单中增加一个随机数作为Token,每次响应页面的Token都不相同,从正常页面提交的请求会包含改Token值,而伪造的请求无法获得该值,服务器检查请求参数中Token的值是否存在并且正确以确定请求提交者是否合法。

2、验证码

相对来说,验证码更加简单有效,即请求提交时,需要用户输入验证码,以避免在用户不知情的情况下被攻击者伪造请求。但是验证码是一个糟糕的用户体验,所以请在必要时使用,如支付交易等关键页面。

3、Referer check

HTTP请求头的Referer域中记录着请求来源,可通过检查请求来源,验证是否合法。

 

 

总结

性能、可用性、伸缩性、扩展性和安全性是网站架构最核心的几个要素,这几个问题解决了,大型网站架构设计大部分挑战也就克服了。有一个误区需要注意,网站技术是为业务而存在的,不要为了技术而技术,选择适合自身的才是最好的。

 

补充:此文为学习《大型网站技术架构》这本书的总结。