构建高性能web站点笔记
第三章 服务器并发处理能力
3.1吞吐率
描述服务器在实际运行期间单位时间内处理的请求数。也就是一定并发用户的情况下,服务器处理请求能力的量化体现。
吞吐率的前提包括:
- 并发用户数
- 总请求数
- 请求资源描述
第五章 动态脚本加速
微动态内容的计算结果生成缓存,我们达到一定目的。
3.1 opcode缓存
目的减少CPU和内存开销。如果动态内容的性能瓶颈不在CPU和内存,而在于I/O操作,比如数据库查询带来的磁盘I/O开销,那么opcode cache的性能提升也有限。
如php,ruby,python这些解释型语言,当解释器完成对脚本代码的分析后,便将他们生成可以直接运行的中间代码,也就是操作码Operate Code,opcode。
对解释型语言,从程序代码到中间代码的过程,我们称为解释(parse),由解释器完成。
对编译型语言,从程序代码到中间代码的过程,称为编译(如C语言的gcc编译器)。
编译器和解释器一个根本的不同是:解释器在生成中间代码以后,便直接执行,所以运行时的控制权在解释器;而编译器则将中间代码进一步优化,生成可以直接运行的目标程序,但不执行。用户可以在随后的任意时间执行它,这时控制权在目标程序,和编译器没有任何关系。
php的核心引擎 Zend Engine
查看print 1+1;
的opcode,通过分析,一共有5个操作:
三地址码,是一种中间代码的理想表现形式。每个运算由不超过三个地址组成:op1,op2,result。
生成opcode
实际上,脚本代码可以看做一系列单词的集合,这些单词包括关键字,标识符,运算符等。
step1: 词法分析,给所有的单词分类,并打上记号(token),print对应的记号是T_PRINT词法规则文件zend_language_scanner.1
setp2: 语法分析,将T_PRINT标记以及上下文替换成了zend_do_print()函数,该函数实现了到opcode的转换,设置了opcode的指令以及op1的数据。
避免重复编译
通过opcode缓存,避免重复的opcode编译。
一些优秀的opcode缓存器扩展,比如php可以选择APC,XCache等。他们都可以将opcode缓存在共享内存中,而我们几乎不需要修改任何代码。
5.2解释器扩展模块
比如在php中加载java扩展模块,则吞吐率就会下降,带来巨大开销。
5.3脚本跟踪与分析
为了让脚本执行更快,women那必须了解事件主要消耗在哪些代码上。
Xdebug是一个PHP的PECL扩展,提供了一组用于代码跟踪和调试的API。
代码执行事件、上下文信息收集等。
(没有详细看)
第六章 浏览器缓存
6.1浏览器
一般来说,浏览器的缓存都是在本地,内存中或者文件中。
6.2缓存协商
服务器端的动态内容缓存包括缓存内容的创建、存储以及过期检查等一系列过程。
浏览器缓存在浏览器本地,而内存由web服务器生成,任何一方都不能单独完成这一系列过程。所以它们之间必须有一种沟通机制,这就是HTTP中的“缓存协商”。
HTTP协议定义的缓存机制有:
- Expires策略:Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
- Cache-control策略:Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
-
Last-Modified/If-Modified-Since:Last-Modified/If-Modified-Since要配合Cache-Control使用。
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
-
Etag/If-None-Match: Etag/If-None-Match也要配合Cache-Control使用。
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器觉得)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。
HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
-
用户行为与缓存
用户操作 Expires/Cache-Control Last-Modified/Etag 地址栏回车 有效 有效 页面链接跳转 有效 有效 新开窗口 有效 有效 前进/后退 有效 有效 F5刷新 无效 有效 ctrl+F5刷新 无效 无效
第七章 Web服务器缓存
7.1 URL映射
解析URL,完成从URL到实际内容或资源的映射。
7.2 缓存响应内容
存储对应关系,在URL映射开始时检查缓存,如果存在并处于有效期内,那么直接取出并作为响应内容返回给浏览器。
准备好缓存区
一般来说,缓存存储在本机内存、磁盘或者分布式存储到其他服务器的内存或者磁盘。
缓存内容
引入磁盘缓存后,原本指向动态内容的请求可以迅速获得缓存
缓存文件描述符
对于静态内容,特别是拥有大量小文件的站点, Web服务器相当大一部分开销花在打开文件上,即Open()系统调用,所以我们还可以考虑将打开后的文件描述符直接缓存到Web服务器的内存中,当然,文件描述符是反应系统资源的数据结构,它也只能存在本机内存中。
Apache提供相应的扩展 mod_file_cache,他需要我们提供希望缓存的文件列表,比如我们配置:
CacheFile /data/www/htdocs/test.html
这样一来,Apache在启动的时候便会打开这些文件,并持续到Apache关闭为止,在这期间,如果有对这些文件的请求,Apache将通过文件描述符直接把文件传送出去。
显然,这种缓存文件描述符的缓存方式只适用于静态内容,并对于大文件不使用,因为处理他们的主要时间花在传送数据上,而不是打开文件。
第八章 反向代理缓存
8.1定义
web服务器隐藏在代理服务器之后。实现这种机制的服务器,就称为反向代理服务器。
目的:基于缓存的加速。