前言::

本篇博客是对《构建高性能web站点》一书中精要内容的总结,
正确理解这边列出的基础知识,将有助于网站工程师,架构师,在面对实际生产环境中的问题时,更好地分析本质原因与提出可行的解决方案


浏览器对于web站点服务器的请求内容包括一个典型页面中常见的组件:图片,层叠样式表(CSS),JavaScript脚本,内嵌页面(iframe)等

请求发出后,浏览器等待服务器的响应以及返回的数据,当获得所有返回数据后,经过本地的计算与渲染最终一幅完整的页面才呈现在用户眼前

以用户观点来看的“等待时间”,包括:

客户端(通常是web浏览器)发出的请求数据在网络上传输到达服务器前经历的时间(响应时间1)
服务器端(通常是web服务器软件)处理请求,发出的回应数据在网络上传输到达客户端前经历的时间(响应时间2)
浏览器本地计算与渲染所花费的时间

一个衡量站点处理请求的能力的指标是:每秒处理请求数。或称“吞吐量”
影响吞吐量的因素主要有:web服务器的类型与并发策略,I/O模型与性能,物理服务器的CPU核数等

影响浏览器计算与渲染生成最终页面的时间因素主要有:
浏览器采用的并发策略,脚本解释器的性能,页面大小与组件的数量,页面组件缓存状况,页面组件域名分布以及域名DNS解析等

改进与提升web站点的性能,可以从如下几个大方面着手:
A。增加带宽


B。减少页面中的HTTP请求:::必须指出的是,web站点中几乎任何一个网页都包含了多个组件,每个组件都需要下载,计算以及(或者)渲染,减少页面组件的数量就能减少HTTP请求的数量,但是这需要在优雅(或绚丽)的网页表现与性能之间进行取舍,一般而言,减少页面组件是以牺牲页面绚丽特效为代价换来性能上的提高


C。加快服务器脚本计算速度:::多数站点使用各种各样的“服务器端脚本语言”,例如PHP,Ruby,Python,ASP.NET,JSP等,用这些脚本语言编写的程序文件需要通过相应的脚本解释器进行解释,生成中间代码,然后依托在解释器的运行环境中运行,这里即是指加快中间代码生成这一环节的速度

D。使用动态内容缓存


E。使用数据缓存



F。将动态内容静态化:::将经常被访问的动态内容缓存静态化成HTML页面,直接让浏览器访问,避免了每次脚本解释器生成动态内容的时间开销



G。更换web服务器软件:::在有关web服务器软件的竞争环境下,大量的压力测试对比数据蛊惑着激进的开发者和运维工程师,人们只关注所谓的并发量冠军,却忽视更加本质性的东西,甚至不了解各种测试报告,数据的潜在前提
必须停止对于表面现象的盲目崇拜,同时学习一些稍显底层的知识来武装自己,并且适当利用这些知识分析各种web服务器的复杂参数配置后的本质


H。分离页面组件



I。合理部署(物理)服务器:::互联网运营商搭建的一系列网络节点,覆盖的地域有大有小,接入这些网络节点的局域网可以相互通信;位于不同运营商网络的局域网也可以通过国家骨干网络互联互通
如果通信的两端主机位于不同运营商的互联网中,那么数据必须流经两个运营商的顶级交换节点和骨干网络,在这个过程中数据会经历多次的存储转发,而且各运营商的顶级交换节点的出口带宽也不同,其时间开销是显而易见的
最理想的情况下,web站点与多数访问站点的用户位于同一个运营商的网络下,这也是选择服务器的物理地点时应该尽量把握的



J。使用负载均衡:::最大程度地发挥单台web服务器的处理能力,并且使其承受的压力达到上限后,需要将访问流量转移其他服务器上,称为负载均衡,常用的实现方法有:HTTP重定向,基于DNS的轮询解析,反向代理服务器实现的负载均衡调度,利用LVS组建服务器集群。。等等



K。优化数据库:::不论web服务器与数据库服务器是否位于同一台物理主机,其数据通信一般基于标准的TCP
每次建立或者释放通信连接时,一段内核缓冲区中的文件描述符相应的被创建或者销毁:这会有相当程度的时间开销
为了避免频繁的连接与释放数据库,应使用数据库持久连接:一种形式为某个进程内部的全局数据库连接,供进程内所有计算任务共享,在这个进程终止后便被释放



L。考虑可扩展性:::我们对于所谓的web站点架构的理解是通过引入一些别人开发的底层技术,并且在实践中不断使用这些技术,来逐步完善的
这里的”底层技术“涉及各种web服务器软件,后台数据库软件,各种类型的服务器端脚本语言及其扩展的开发框架。。。等等,以及任何涉及web站点架构中的必要技术



M。减少视觉等待



第二章  网络的数据传输

多数面向大型应用的站点内部,通过局域网中的服务器集群来组建分布式环境
许多“生活在应用层的前端以及后端开发者”,应该加深对于数据的网络传输原理这部分的理解,它是在优化自己的站点性能时不可或缺的底层知识

常用的分层网络模型有:OSI七层网络模型与TCP四层网络模型,也是多数计算机网络教材中采用的讲解模型


二个衡量线路的参数:

   带宽:特定线路每秒可发送的最大比特数。

   延迟:单个比特往返特定线路所花费的时间,以秒为单位。


带宽 * 延迟 = 带宽延迟乘积。

   客观量化某特定线路在数据从发送方到接收方,再返回发送方(收到确认)这段往返时间内,理

   论上能发送的数据上限。


例如,某线路带宽为每秒最多可以承载一百万比特(即 1Mbps),1比特往返发送端需0.02秒(20毫秒),则理论上在这20毫秒的往返时间内,最多可发送 1000000 bits * 0.02 = 20000 bits 的后续数据。如果发送端在这20毫秒内,总共仅发送了1000 bits 的数据(即相当于 1000 bits /8 = 125字节)我们可以认为,这段时间内的线路利用率为 1000 bits / 20000 bits = 5% ,效率非常低下。

显而易见,在前面的例子中,20毫秒/125字节 的数据发送量,还不及一个IP分组在因特网主干线路上的大小(通常是500多字节)。

所以,在高带宽(每秒传输大量比特)以及大延迟(传输距离长)的线路中,如因特网主干,需要一种高效的传输层协议,如TCP,这样才能充分利用线路的带宽资源。









网络线路测速使用的带宽,或者互联网运营商提供的接入带宽,单位为Bit / per second,表示单位时间的比特数;
例如100M带宽,全称为100Mbit/s ,或者100Mbps

web浏览器的下载进程,其他多线程或断点续传下载软件,以及P2P协议下载软件等的实时下载速度状态显示,
其单位为Bytes / per second ,表示单位时间的字节数,其中, 1 byte = 8bits(即1字节等于8比特)

严格意义上的带宽,不仅指数据在网络(线路)上的传输速度,还包括了数据在两端通信主机内部(即发送前与接收后)的传输速度,下面将概要介绍数据在网络传输前的发送环节,即数据从主机进入网络的过程

1。要发送数据的应用程序将数据写入该程序(运行时称为进程)的内存地址空间
2。应用程序通过系统函数库接口(例如send函数)向内核发出调用,由系统内核接手后续的操作,
    系统内核将这些数据从用户态内存区(即每个进程独占的虚拟内存地址空间)复制到由内核维护的一段称为“内核缓冲   区”的物理内存地址空间中;因为这块地址空间的大小有限(取决于物理内存模块容量的大小以及不同操作系统的实现机制),所有来自其他应用程序的发送数据将以队列的形式进入这里。如果发送的数据量比较大,需要进行多次系统调用,例如编程时的send()调用,每次调用时发送的数据大小固定,但取决于内核缓冲区的承载能力
3。发送数据写入内核缓冲区后,由内核通知网卡控制器(适配器)前来读取数据,此时对CPU的控制权转移到其他进程。
    网卡控制器接到通知,根据网卡驱动程序中关于内核缓冲区的地址信息,将发送数据复制到网卡缓冲区中
必须指出,带宽在数据复制的这个阶段中,主要是指连接两端硬件设备的系统总线所支持的传输宽度
    例如连接内存与网卡的系统总线宽度为32位,且与网卡接口位宽相同(例如PCI-E)那么每个复制数据的大小为4字节,此时的带宽为单位时间传输的数据总量 * 每个数据的大小(4字节)

4。网卡缓冲区的数据在发送至网络传输前,需要对以字节为单位的数据转换成以比特为单位,因为只有比特(二进制的数字信号)才能在线路中传输;在发送完数据后还要删除以释放该数据占用的缓冲区以便后续的数据发送
5。根据数据进入线路的传输介质不同,将生成不同信号:铜线,双绞线路将生成数字信号(电信号);光纤线路将生成光信号并传输。一般而言,铜线中电信号传播速度为2.3 X 10^8 m/s  ,光纤中光信号传播速度为2.0 X 10^8 m/s  ,

由于光信号在光纤中传输时用到光的全反射原理,所以光在光纤中的实际(总的)传输距离往往大于光纤线路的物理长度,这里的传播速度即相对光纤的物理长度而言,所以速度会比在铜线中略低
光纤相对于传统双绞线等传输介质的真正优势在于:
光信号在光纤中的最大有效传输距离为数千米;而电信号在双绞线中的最大有效传输距离仅为100m,这导致需要使用中继器来避免信号在更远距离传输时的衰减(带来的副作用是中继器在转发信号时增加的时间开销)
相较而言,由于光信号的传输衰减程度相当低,于是总体传输效率和距离就比双绞线高得多,且又可以免去使用中继器增强信号带来的时间开销

网卡设备中的参数,例如100M(百兆)网卡,则是指该设备单位时间(秒)内理论上的最大发送数据量为100Mbit,
或者为12.5Mbytes