yuhaiyang 2016-03-20
大型网站技术架构
核心原理与案例分析
应用、数据分离
===》
缓存(80/20定律)80%的业务访问集中在20%的数据上
===》
应用服务器集群改善网站并发处理能力
===》
DB读写分离(DB库主从热备)改善DB负载压力
===》
反向代理、CDN加速网站响应(网站访问延迟与用户流失率正相关)
CDN、反向代理原理是使用缓存
反向代理:部署在网站中心机房
CDN:部署在网络运营商的机房
目的:尽早返回用户数据,加快用户访问,减轻后端server的压力
===》
使用分布式文件系统、分布式数据库系统
业务分库分表
===》
使用NoSQL、搜索引擎
===》
业务拆分(分而治之)不同的产品线
通过超链接、消息队列(数据分发)、数据存储系统建立关系
===》
分布式服务
网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的(不要过度设计 KISS原则)
在网站还很小的时候追求网站的架构是舍本逐末
最需要做的是为用户提供好的服务来创造价值,得到用户的认可、活下去、野蛮生长。
每一个模式描述了在我们周围不断重复发生的问题及该问题的解决方案的核心,这样,就能一次又一次的使用该方案而不必做重复的工作
模式的核心在于可重复性
网站的架构模式:分层(横向)、分割(纵向)、分布式(分布式应用和服务、分布式静态服务—动静分离、分布式数据存储、分布式计算)、集群、缓存(CDN、反向代理、本地缓存、分布式缓存)、异步、冗余(sever,data)、自动化、安全(验证码、加密等)
缓存的使用前提是数据访问热点不平衡,部分数据频繁访问;某个时间段有效。
从浏览器到数据库,影响用户请求的所有环节都可以进行性能优化:
在浏览器端:
浏览器缓存、页面压缩、合理布局页面,减少Cookie传输;
CDN,将网站静态内容分发到离用户最近的网络服务机房;
在机房部署反向代理服务器,缓存热点文件,加快请求相应速度,减轻应用服务器负载压力。
在应用服务器端:
本地缓存、分布式缓存,通过缓存在内存中的热点数据处理用户请求,加快请求处理过程,减轻数据库负载压力;
通过异步操作将用户请求发送至消息队列等待后续任务处理,而当前请求直接返回响应给用户;
将多台应用服务器组成集群共同对外提供服务,提高整体处理能力,改善性能;
在数据库端:
索引、缓存、SQL优化;
NOSQL数据库通过优化数据模型、存储结构、伸缩特性
高可用设计目标就是当服务器宕机时,服务或应用依然可用。
高可用的主要手段是冗余,应用部署在多台服务器上同时提供服务,数据存储也在多台服务器互相备份,任何一台服务器宕机都不会影响应用的整体可用,也不会导致数据丢失。
不断向集群加入服务器的手段来缓解不断上升的用户并发访问压力和不断增长的数据存储需求。
衡量架构可伸缩性的主要标准是是否可以用多台服务器构建集群,是否容易向集群添加新的服务器,加入的新服务器后是否可以提供和原来服务器无差别的服务,集群中可容纳的总的服务器数量是否有限制。
关注网站的功能需求
设计网站的架构使其能够迅速响应需求变化是可拓展性的目标。
衡量网站可拓展性的主要标准是在网站增加新的业务时,是否可以实现对现有产品的透明无影响,不需要改动或很少改动现有业务就可以上线新产品。不同产品之间耦合是否很少,一个产品的改动对其他产品无影响,其他产品和功能不需要受牵连进行改动。
网站可拓展架构主要手段是事件驱动架构和分布式服务。
事件驱动架构常用消息队列实现,将用户请求和其他业务事件构成消息发布到消息队列,消息的处理者作为消费者从消息队列中获取消息进行处理。通过这种方式将消息产生和处理分离,可以透明的增加新的消息生产者任务或新的消费者消费消息。
分布式服务是将业务和可复用服务分离开,通过分布式服务框架调用,新增产品可以调用可复用的服务实现自身业务逻辑,对现有产品无影响。可复用服务升级时,也可以通过提供多种版本服务队应用实现透明升级,不需要强制应用同步变更。
网站的安全架构是保护网站不受恶意访问和攻击,保护网站的重要数据不被窃取。
衡量网站的安全架构标准是针对现存和潜在的各种共计和窃密手段,是否有可靠的应对策略。
改善用户视角下的网站性能:
优化页面HTML样式、利用浏览器的并发和异步特性、调整浏览器的缓存策略、CDN服务、反向代理。使浏览器尽快显示用户需要的内容,近可能近的获取页面内容。
开发人员视角下的网站性能:
关注程序及子系统的性能:响应延迟、系统吞吐量、并发处理能力、系统稳定性等;主要手段:使用缓存加速数据读取、使用集群提高吞吐能力、使用异步消息加快请求响应和实现消峰,使用代码优化改善程序性能。
运维人员视角下的网站性能:
关注基础设施性能和资源利用率。
主要优化手段:建设优化骨干网、使用高性价比服务器、利用虚拟化技术优化资源利用。
从开发和测试人员的角度,网站性能测试的主要指标有响应时间、并发数量、吞吐量和性能计数器。
响应时间常用重复请求的总时间/请求数量计算平均值
并发数量:同时能处理的请求数量,反应系统的负载情况。测试该指标时可以多线程并发模拟用户的办法来测试系统的并发处理能力,为了真实模拟用户行为,测试程序并不是启动多线程后不停的发送请求,而是在两次请求之间随机加入一个等待时间(思考时间)。
吞吐量:单位时间内处理请求的数量。体现系统的整体处理能力。TPS每秒事务量、HPS每秒HTTP请求数量、QPS每秒查询数
性能计数器是服务器或OS性能的数据指标。如系统负载(TOP命令,最后三个浮点数表示最近1、5、10分钟的情况)、对象鱼线程数、内存使用、CPU使用、磁盘与网络IO等。
分性能测试、负载测试、压力测试、稳定性测试。
根据测试情况,进行对应的优化:
Web端性能优化、应用服务器性能优化、存储服务器性能优化。
Web端性能优化
1)减少HTTP请求(HTTP是无状态的应用层协议,每次HTTP请求都需要建立通讯链路、进行数据传输,在服务器端,每个HTTP请求都需要启动独立的线程去处理。这些通讯和服务的开销都很昂贵,减少HTTP请求可有效的提高访问性能。);
常用手段:合并CSS、JS、图片。
2)使用浏览器缓存
静态资源的更新频率低,但每次HTTP请求都需要的,但将文件缓存在浏览器中则可以改善性能。
手段:设置HTTP头中的Cache-control和Expires属性对浏览器缓存进行设置。
使用浏览器缓存的网站在更新资源时,应采用批量更新法:一个个文件逐步更细,并有一定的时间间隔,避免用户浏览器突然大量缓存失效,集中更新,造成服务器负载骤增,网络堵塞。
3)启用压缩
服务器对文件压缩、浏览器解压文件,以减少通讯传输的数据量。JS、CSS、HTML。
4)CSS放在最上边、JS放在最下边
浏览器会在下载完CSS后加载页面;将CSS放在最上边,让浏览器尽快加载页面。浏览器加载JS会立即执行,会阻塞页面加载,造成页面显示缓慢。因此JS放在最下边。
5)减少Cookie传输
Cookie包含在每次的请求和响应中,太大的Cookie会影响数据传输。对于静态资源的服务,发送Cookie无意义,可考虑静态资源用独立的域名访问,避免请求静态资源时发送Cookie。
CDN加速
本质是缓存,将数据缓存在离用户最近的地方,使用户以最快速度获取数据。(网络服务第一跳)
CDN部署在网络运营商机房,这些运营商又是终端用户的网络服务提供商,因此用户请求路由的第一跳就到达了CDN服务器,当CDN服务器存在请求的资源时,从CDN直接返回浏览器,最短路径返回响应,加快用户访问,减少数据中心负载压力。
CDN能缓存的是静态资源:JS、CSS、图片、文件、静态网页。
反向代理
代理服务器可以配置缓存功能加速Web请求。当用户第一次访问静态内容时,静态内容就被缓存在反向代理服务器上,这样其他用户访问该资源时,可以从反向代理服务器直接返回,从而加速Web请求。
应用服务器性能优化
主要手段是集群、异步、缓存等。
网站性能优化的第一定律:优先使用缓存优化性能。
1)分布式缓存
缓存的基本原理
缓存指的是将数据存储在相对较高访问速度的介质中,以供系统使用。一方面缓存访问速度快,可以减少数据访问的时间,另一方面如果缓存的数据是经过计算得到的,那么缓存的数据无需重复计算即可使用,因此缓存还能减少计算时间。
缓存的本职是一个内存Hash表,网站应用之后,数据以Key-Value形式存储在内存Hash表。读写的时间复杂度O(1)。
缓存主要用来存放读写比很高、很少变化的数据。网站数据的访问通常遵循28定律,即80%的访问落在20%的数据上。因此利用Hash表和内存的高速访问特性,将这20%的数据缓存起来,可以很好的改善系统性能。提高数据读取速度,降低存储访问压力。
通过分布式缓存服务器集群,将数据缓存分布到集群多台服务器上可改善缓存的可用性。
常用的分布式缓存架构有:JBoss Cache为代表的需要同步更新的分布式集群;Memcached为代表的不互相通信的分布式缓存集群。
JBoss Cache:在集群之后所有服务器中保存相同的缓存数据,当某台服务器缓存数据更新时,会通知集群中其他机器更新缓存数据或清除数据。应用与缓存通常部署在同一台机器。常见于企业级应用,但在大型网站很少用。
Memcached:缓存和应用分离部署,应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据,缓存服务器之间不进行通讯,集群规模很容易扩容,具有良好的可伸缩性。
远程通讯设计需要考虑两方面的要素:通信协议(TCP/UDP/HTTP)、通信序列化协议(数据传输的两端,必须使用彼此可识别的数据序列化方式才能完成通信,如XML、JSON)。Memcached使用TCP、基于文本的自定义协议。服务器通信模块基于Libevent,一个支持事件触发的网络通信程序库,提供稳定的长连接。
异步操作
使用消息队列将调用异步化,可改善网站的扩展性,还能改善网站的系统性能。(消息队列的处理速度高于数据库)消息队列有很好的消峰作用,通过异步处理,将短时间高并发产生的事务消息存储在消息队列,从而削平高峰期的并发。
使用集群
避免一台服务器因负载过大而响应缓慢,使用户请求具有更好的延迟响应性。
代码优化
多线程
使用多线程的主要原因:IO阻塞与多CPU。利用线程阻塞与执行,可以最大程度提高CPU的利用。要想最大程度利用多CPU服务器,也要使用多线程。
资源复用
系统运行时,要尽量减少开销很大的系统资源的创建与销毁。如数据库连接、网络通信连接、线程、复杂对象等。资源复用的主要方式是单例和对象池。
数据结构
垃圾回收
2)
存储服务性能优化
关系数据库常用B+树。NOSQL数据库采用LSM树。
文件压缩
Session复制:早期方案使用,应用服务器开启Web容器的Session复制功能,在集群的几台服务器之间同步Session对象,使得每台服务器都保存所用的Session信息,这样任何一台服务器宕机都不会导致Session数据丢失。
缺点:集群规模大时,集群服务器间进行大量Session复制,占用服务器和网络的大量资源,系统负担重。
Session绑定
可以通过负载均衡的源地址Hash算法实现,负载均衡器总是将来源相同的IP请求分发到同一台服务器。但服务器宕机时,其他服务器木有Session则无法完成服务。很少使用的方案。
利用Cookie记录Session
利用浏览器的Cookie记录Session。但缺点是Cookie大小受限制,能记录的信息有限;每次请求都要传输Cookie,影响性能;如果用户关闭Cookie,访问就会不正常。实际使用较多。
Session服务器
可用性高、伸缩性好,性能好,对信息大小无限制。
独立部署Session集群管理Session。==将应用服务器的状态分离:无状态的应用服务器+有状态的Session服务器。
有状态的Session服务器一般采用分布式缓存、数据库等。
高可用的策略:
1分级管理
核心应用用最好的服务器;服务器部署进行必要的隔离,避免故障的连锁反应。
2超时设置
超时抛异常,应用程序迅速进行相应的反应。
3异步调用
通过消息队列实现。避免一个服务失败导致整个应用请求失败。
4服务降级
高并发,服务器压力负载大时使用的手段:拒绝服务和关闭服务。
拒绝服务:拒绝低优先级应用的调用,减少服务调用次数。
关闭服务:关闭不必要的功能。
5服务等幂性
服务重复调用和一次调用效果一致。
手段是数据备份和失效转移机制。
数据备份:数据有多个副本,任意副本的失效都不会导致数据的永久丢失。
失效转移机制:当一个副本不可用时,迅速切换到其他副本。
数据备份:
冷备:定期备份。缺点:不能保证最终一致性。
热备:异步热备、同步热备。
异步热备:多分数据的写入异步完成。先成功写一份,其他异步实现。主从存储服务器。
同步热备:多分数据的写入同步完成,多线程保证性能。服务器对等,不分主从。
失效转移
若数据服务器集群中任何一台服务器宕机,那么应用程序针对这台服务器的所有写操作都需要重新路由到其他服务器,保证数据访问不会失败。
失效转移组成:失效确认+访问转移+数据恢复
失效确认手段:心跳检测、应用程序访问失败报告(心跳检测确认)
仅仅通过改变部署服务器的数量就可以扩大或缩小网站的服务处理能力。
网站伸缩设计分为两类:根据功能进行物理分离实现(一个功能一台服务器)、单一功能通过集群实现。
常用的负载均衡算法:
轮询、加权轮询、随机、最少连接、源地址散列Hash
在对现有系统影响最下的情况下,系统功能可持续的扩展或提升的能力。
低耦合性的系统更易扩展
软件架构师的最大价值不在于掌握多少先进的技术,而在于具有将一个大系统切分成N个低耦合的子模块的能力。设计可扩展性网站的核心在于模块化。降低模块的耦合,提高复用。在大型网站中,这些模块分布式部署,独立的模块部署在独立的服务器,从物理上分离模块之间的耦合,进一步降低耦合提高复用。
模块分布式部署后聚合的方式是分布式服务和分布式消息队列。
事件驱动架构:低耦合的模块之间传输事件消息,以保持模块的松耦合,并借助事件消息的通讯完成模块间的合作。典型的是生产者消费者模式。常用的是分布式消息队列实现。
通过接口分解系统耦合,不同子系统通过相同的接口进行服务调用。
大型分布式网站的需求与特点:
负载均衡、失效转移、高效远程通信、整合异构系统、对应用最少侵入、版本管理、实时监控
分布式架构设计:Thrift、Dubbo
利用开放平台建设网站生态圈:
API接口、协议转换、安全、审计(监控第三方访问情况,统计、收费)、路由、流程
XSS攻击和SQL注入是网站攻击主要手段。
XSS攻击:跨站点脚本攻击。通过篡改网页,注入恶意HTML代码,在用户浏览网页时,控制用户浏览器进行恶意操控的一种攻击方式。
预防手段:消毒(对输入进行转义)、HTTPOnly(防止XSS获取Cookie)
开源应用防火墙:ModSecurity
常用手段:
文本匹配(双数组Trie树、多级Hash算法比较高效)
分类算法(朴素贝叶斯)
黑名单(Hash表实现)
常用的其他反向代理服务器(nginx,Tegin):Squid
比Apache更轻量级的应用服务器/图片服务器:Lighttpd
关注人不是产品:发掘每个人的优势
发掘人的优秀
共享美好蓝图
共同参与架构:架构师对架构负则,但不是说必须自己完成架构设计
学会妥协
成就他人