前言
上节我们讲了架构设计的五大核心要素,今天我们就讲第一个核心要素:性能,性能是一个网站给用户最直接的感受,是一个网站的灵魂。下面我们将从以下几个方面谈谈如何构建一个高性能架构:网站性能测试、web前端优化、应用服务器优化、存储性能优化。
网站性能测试
性能测试是性能优化的前提和基础,也是性能优化结果的检验和度量标准,不同视角下的网站有不同的标准,也对应不同的优化。下面我们将依次展开:
不同视角下的网站性能
-
用户视角:对于用户而言,发出一个请求,到响应结束所用的时间就是最直观的性能表现,如下图就是一个用户对性能最直观的体现方式
主要包括计算机和网站服务器通信的时间,网站服务器处理请求的时间,
计算机浏览器构造请求解析和响应的时间,主要优化手段是使用一些前端
架构优化方案,例如优化HTML样式,利用浏览器的缓存和异步特性调整
浏览器缓存策略,使用cdn服务和反向代理手段等;
-
开发人员:开发人员主要关注的是应用程序本身及其相关子系统的性能,主要包括响应延迟、系统吞吐量、并发处理能力、系统稳定性等技术指标;主要的优化手段有使用缓存加速数据读取,使用集群提高吞吐量,使用异步消息加快请求响应及实现削峰,使用代码优化程序自身;
-
运维人员:运维人员主要关注基础设施性能和资源的利用率,主要包括网络运营商的带宽,服务器硬件的配置,数据中心网络架构,服务器和网络带宽的利用率等;主要的优化手段有建设优化骨干网络,使用高性价比定制服务器配置,利用虚拟化技术优化资源利用;
性能测试指标
-
响应时间:指应用执行一个操作需要的时间,包括从请求开始到请求最后响应数据所需的所有时间。响应时间是系统最重要的性能指标,直观的反映了系统的“快慢”;
-
并发数:指系统能够同时处理请求的数目,这个数量也反映了系统负载的特性,对于网站而言,并发数就是网站并发用户数,即同时提交请求的用户数量。与网站并发数对应的还有网站系统用户数(可以访问系统的总用户数,一般为系统的注册用户数)和网站在线用户数(当前登录系统的用户总数),这三者的关系:网站系统用户数>>网站在线用户数>>网站并发用户数;
-
吞吐量:指单位时间内处理的请求数量,体现系统的整体处理能力。主要通过TPS(每秒事务数)、HPS(每秒HTTP请求数)和QPS(每秒查询数)来体现
-
性能计数器:指描述服务器或者操作系统性能的一些数据指标,主要包括系统负载(System Load)、对象与线程数、内存使用、CPU使用、磁盘与网络I/O等;
-
系统负载:指当前正在被CPU执行和等待被CPU执行的进程数总和,是反映系统忙闲程度的重要指标。多核CPU情况下,最理想的是所有CPU都在使用,没有进程在等待被处理,此时load的理想值就是CPU的数目;当load<cpu数时,表示CPU有空闲,存在资源浪费;当load>cpu数时,表示有进程在排队等待CPU调度,系统资源不足,影响应用程序的执行性能,Linux中使用top查看系统负载。
-
性能测试方法
-
性能测试:系统设计初期规划的性能指标为预期目标,在对系统不断施加压力,验证系统在资源可接受范围内是否能达到性能预期目标;
-
负载测试:对系统不断增加并发请求以增加系统压力,直到系统的某项性能达到安全临界值,如果某个资源已经饱和状态时,继续对系统施加压力的话,系统的处理能力不但不能提升,反而会下降;
-
压力测试:当系统超过安全负载的时候,对系统继续施加压力,直到系统崩溃或者不能再处理任何请求,以此来获取系统最大压力承受能力;
-
稳定性测试:被测试的系统在特定的硬件、软件、网络环境下,给系统加载一定业务压力,使系统运行一段较长时间,以此来检测系统是否稳定;
性能优化策略
如果性能测试的结果不能满足业务需求,或者说不是很令人满意,那么就要进行性能分析和优化了
-
性能分析:排查网站性能和程序性能瓶颈的基本方法是,检查请求处理的各个环节的日志,分析哪个环节响应时间不合理,超过了预期;然后检查监控数据,分析影响性能的主要因素是内存、磁盘、网络还是CPU,是代码问题还是架构不合理,或者系统资源确实不足;
-
性能优化:根据网站分层架构,可以把性能优化也分为web前端性能优化、应用服务器性能优化、存储服务器性能优化;
web前端性能优化
一般来说web前端指的是网站业务逻辑之前的部分,包括浏览器加载、网站视图模型、图片服务、cdn服务等,优化手段主要体现在浏览器访问、反向代理和CDN等几个方面:
-
浏览器访问优化
-
减少http请求:HTTP协议都是无状态的应用层协议,意味着每次http请求都需要建立通信链路,进行数据传输,而在服务端,每个http请求都需要开启一个独立的线程去处理,增加了服务器的开销,所以减少HTTP请求的数目可以有效的提高访问性能;减少http请求的主要手段包括合并css、合并js、合并图片。将浏览器一次访问需要的这些静态资源合并成一个文件,这样浏览器只需要一次请求即可。多张图片也可以合并成一张大图,如果每张图都有不同的超链接,可以通过css偏移响应鼠标点击操作,构造不同的URL;
-
使用浏览器缓存:对于一个网站而言,css,js和一些图片这些静态资源更新的频率都比较低,而这些又是每次请求都需要加载的,如果把这些文件缓存在浏览器中,可以极好的改善性能,通过设置HTTP头中的Cache-Control和Expires的属性,可以设定浏览器缓存;
-
启动压缩:在服务器端对文件进行压缩,浏览器端进行解压缩,可以有效的减少通信传输的数据量,但是压缩对服务器和浏览器产生一定的压力,在通信带宽良好而服务器资源不足的情况下要权衡考虑是否压缩;
-
css放在页面最上面,js放在页面最下面:浏览器会在下载完全部的css之后就对整个页面进行渲染,因此最好的做法是将css文件置于页面最上面,让其尽快加载。js则相反,浏览器加载js后立即执行,有可能会阻塞整个页面,所以最好将js置于页面最下面。但是要注意一点如果页面在解析时就需要用到的js,这时候放最下面就不合适了;
-
减少cookie传输:cookie包含在每次请求和响应中,太大的cookie会严重影响数据传输,因此哪些数据需要写入cookie时需要慎重考虑,尽量减少cookie的数据量;此外对于一些静态资源的访问(css,js等),发送cookie并没有意义,可以考虑使用独立的域名访问,尽量避免请求静态资源时发送cookie,减少cookie的传输次数;
-
-
反向代理
-
反向代理服务器位于机房一侧,代理网站web服务器接收http请求;
-
反向代理可以起到保护网站安全的作用,所有来自互联网的请求都必须经过代理服务器,相当于在web服务器和可能的网络攻击之间建立了一个屏障;
-
反向代理还可以通过配置缓存功能加速web请求,当用户第一次访问静态资源时,静态内容会被缓存到代理服务器上,这样当其他用户再次访问该静态资源时,就可以直接从反向代理服务器中获取,加快了web响应速度,减轻了web服务器的负载压力;当缓存的内容发生变化时,通过内部通知机制通知代理缓存失效,反向代理服务器会重新加载最新的内容再次缓存;
-
反向代理也可以实现负载均衡的功能,通过负载均衡构建的应用集群可以提高系统的总体处理能力,进而改善网站高并发下的性能;
-
-
CDN加速
-
CDN又叫内容分发,本质上也是缓存,而且是将数据缓存在离用户最近的地方,当CDN中存在浏览器请求的资源时,直接从CDN返回给浏览器,最短路径返回响应,加快用户访问速度减少数据中心负载压力;
-
CDN能够缓存的一般是一些静态资源,如css,js,图片,静态网页等;
-
应用服务器性能优化
应用服务器就是处理网站业务的服务器,部署业务代码,是网站开发最复杂,变化最频繁的地方,优化手段主要体现在缓存、集群、异步和代码优化:
-
分布式缓存:回顾我们之前讲过的网站架构演变,当遇到性能瓶颈时,第一个想到的解决方案就是缓存,我们就好好讲下缓存;
-
缓存的基本原理:缓存是指将数据存储在相对较高访问速度的存储介质中,以供调用。一方面缓存访问速度快,另一方面如果缓存的数据是经过计算处理得到的,那么被缓存的数据就无需在计算直接可以使用。
-
缓存的本质:内存Hash表,数据缓存以一对kv的形式存储在内存hash表中,首先计算kv对中key的hashcode对应的hash表索引,可以快速访问hash表中的数据。然后通过hashcode计算hash表的索引下标,最简单的是余数法,使用hash表数组长度对hashcode求余,余数即为hash表索引,使用该索引可直接访问到hash表中存储的kv对,具体过程见下图:
缓存主要用来存储一些读写比例较高,很少变化的数据,应用程序读取数据时,先到缓存中读取,如果读取不到或者数据已经失效,再访问数据库,并将数据写回缓存:
-
合理使用缓存:
-
频繁修改数据:如果缓存中保存的是频繁修改的数据,就会出现数据写入缓存后,应用来不及读取缓存,数据就已经失效的情形,反而增加了系统负担,一般来说数据读写比在2:1以上缓存才有意义;
-
没有热点的访问:如果应用访问的数据没有热点,即缓存的数据很少被访问,那么缓存就没有意义,还没来得及被访问就已经被挤出缓存,这是无用的缓存;
-
-