高性能Web站点
概述一般而言,我们评估一个Web站点速度如何,通常先置身于用户的角度,访问该站点的一系列页面,体验等待时间。对于每个页面来说,等待时间从用户输入页面地址或点击跳转链接开始,一直持续到新的网页完整的展现出来。如何构建高性能Web站点,可以就一下几个方面进行着手。
1优化招数
服务器并发策略
1.这里的吞吐率特指Web服务器单位时间内处理的请求。
2.压力测试的前提:1>并发用户数 2>总请求数 3>请求资源描述
3.用户平均请求等待时间主要用户衡量服务器在一定 并发用户数的情况下,对于单个用户的服务器质量;而服务器平均请求处理时间与前者相比,则用于衡量服务器的整体服务质量,它其实就是吞吐率的倒数。
4.对http header中标记为Connection: Keep-Alive的请求,开启web服务器的 长连接支持。减少系统调用accept的次数,即减少建立连接的开销。
5.老调重弹,进程, 内核级线程和用户级线程在不同情况下的优劣。IO模型,mmap(内村映射),直接IO,例如sendfile syscall以及异步IO等。多路IO复用(select, poll,epoll and kqueue etc)
6.服务器并发策略
1> 一个进程处理一个连接,非阻塞IO。稳定性强,但context switch的开销随http request递增而快速增长。
2> 一个内核级线程处理一个连接,非阻塞IO, 多进程 多线程混合方式。Context switch的问题依然存在。理论上可以支持更多的 并发连接。
3>一个进程处理多个连接,非阻塞IO。(epoll, kqueue)lighttpd, nginx。支持并发性能强劲。 上述情况的适用范围不能一刀切,而且这里都是指单机并发,需根据实际情况(实际 并发数)来选择。通常,在 并发用户数较大的情况下,Web服务器使用什么样的并发策略,是影响最大 并发数的关键。
动态内存缓存
在实际应用中,动态内容缓存可能是使用得最多的技术,但是并不见得所有的动态内容都适合使用网页缓存,缓存带来的性能提升恰恰与有些 动态数据实时交互的需求形成矛盾,这就是一个权衡。
1. 缓存动态生成的html代码。
2. 把动态内容 静态化,直接缓存整个html文件。这样就可以直接访问缓存。这时的更新策略:
1>在数据更新时重新生成 静态化内容 2>定时重新生成静态化内容
3. 使用SSI(server side include)进行局部 静态化。但web server的SSI功能会对 静态文件的吞吐率有负面影响。
动态脚本加速
加快 脚本语言的执行速度;缓存 中间代码(opcode)以供复用。
浏览器缓存
减少http请求,充分利用浏览器的缓存。而webapp通过http协议(更具体位置就是http header)来与浏览器协商,那些东东浏览器可以使用其缓存即可。
1. Last-Modified/If-Modified-Since
2. ETag/If-None-Match
3.Expires + Cache-Control: max-age=<seconds>
1和2需要 浏览器和webserver交互后,有服务器端通知浏览器是否使用 浏览器缓存,而3则是在过期前直接使用浏览器缓存,这样就直接kill掉了http request。同时还需注意,在使用SSI的内容中,由于整个页面是服务器动态生成的,所以Last-Modified标记在不同的Web服务器中有不同的生成方法。
Web服务器缓存
这个第二点动态内存缓存有区别,前者更指缓存是否命中与否完全由应用程序决定,且缓存方式也有应用来决定;而后者更指有web服务器通过URL决定是否缓存命中,比如 静态内容或者更新不太频繁的动态内容就比较时候由其缓存。
反向代理缓存
Web服务器隐藏在 代理服务器之后。这种代理机制称为反向代理(Reverse proxy),同时,实现这种机制的服务器便成为反向代理服务器。隐藏在反向代理服务器之后的Web服务器,我们习惯称它为后端服务器(Back-end server),当然,反向代理服务器就被称为前端服务器(Front-end server)。
引入反向代理服务器的目的之一就是基于 缓存的加速。我们可以将内容缓存在反向代理服务器上,所有缓存机制的实现仍然采用HTTP/1.1协议。
缓存命中率和后端吞吐率的理想技术模型
缓存丢失率=(活跃内容数/(实际吞吐率×平均缓存有效期))×100%
缓存命中率= 1-缓存丢失率 后端吞吐率= 活跃内容数/平均缓存有效期
缓存命中率= (1-(后端吞吐率/实际吞吐率))×100%
后端吞吐率 = (1 – 缓存命中率)×实际吞吐率
结论: 1. 活跃内容数和平均缓存有效期一定的情况下, 缓存命中率与实际吞吐率成正比。
2. 实际吞吐率和平均缓存有效期一定的情况下, 缓存命中率与活跃内容数成反比。
3. 活跃内容数和实际吞吐率一定的情况下, 缓存命中率与平均缓存有效期成正比。
4. 活跃内容数一定的情况下,后端吞吐率与平均缓存有效期成反比。
5. 平均缓存有效期一定的情况下,后端吞吐率与活跃内容数成正比。
6. 缓存命中率的变化不一定会影响后端吞吐率。
7. 后端吞吐率的变化不一定会影响 缓存命中率。
ESI – Edge Side Include类似与SSI,但不在webserver端组装内容,而是在http 代理服务器上组装内容,包括 反向代理。在处理只有局部更新动态内容时AJAX是更好的原则,它不依赖与底层webserver的实现,但ESI的优势在于再有多个后端服务器的情况下,变可以避免多个后端的重复组装,减少总工作量。
Web组件分离
从以下几个方面来看Web组件的差异:
1. 文件大小
2. 文件数量
3. 内容更新频率
4. 预计 并发用户数
5. 是否需要 脚本 解释器
6. 是否涉及大量CPU计算
7. 是否访问数据库
8. 访问数据库的主要操作是读还是写
9. 是否包含RPC
对每种类型的Web组件采取不同的优化方式(一种或多种):
1. 是否使用epoll模型
2. 是否使用sendfile() syscall
3. 是否使用异步IO
4. 是否支持HTTP 持久连接(http keep-alive)
5. 是否需要opcode 缓存
6. 是否使用动态内容 缓存以及有效期为多长
7. 是否使用Web服务器 缓存以及有效期为多长
8. 是否使用 浏览器缓存以及有效期为多长
9. 是否使用 反向代理缓存以及有效期为多长
10. 是否使用 负载均衡策略
按照Web组件的不同类型将其放在不同的二级域名/机器/不同类型的WebServer
同时,还需考虑到不同的浏览器对同一个域名下的访问有多大 并发数限制,而使用多个域名。
IE6,7 2(http/1.1)
IE8 6(http/1.1)
Firefox2 2(http/1.1)
Firefox3 6(http/1.1)
发挥各自的潜力
对于动态内容:开启opcode缓存,使用足够快的CPU,足够大的内存, 多进程以及与数据库保持高速连接
对于静态内容:支持epoll,非阻塞IO,异步IO,使用sendfile,单进程(对于IO密集型任务, 多进程无法发挥优势),使用高速 磁盘,使用RAID
对于image, css and script分配合理设置其过期时间(expires)
分布式缓存
使用分布式缓存避免 应用服务器的内存缓存瓶颈,使其更易于扩展。当使用多台 应用服务器时,分布式缓存易于内容共享。
数据库性能优化(泛泛而谈)
1.合理的执行计划,包括合理使用索引
2.使用 慢查询分析工具,找出执行很慢的sql并优化之。
3.合理的数据库缓存,索引缓存, 数据缓存等
4.更具实际需求选择合理的数据库引擎或数据库
5.反范式化设计,对查询带来优化,但增加写和更新的工作量。
6.放弃 关系型数据库,针对实际情况,读写要求极高时 数据库扩展: 读写分离,按业务实施合理的 垂直分区,对热点表进行 水平分区。
Web负载均衡
DNS负载均衡
需要DNS服务商提供该功能,且DNS记录存在缓存,无法及时修改,带来更新延迟。
反向代理负载均衡
HTTP重定向和DNS解析在请求的调度上体现在“转发”上,而其则体现在“转移”。
任何对于实际服务器的http请求都必须经过调度器;调度器必须等待实际服务器的http响应,并将它反馈给用户。
由于调度策略在自己手中,就可以使用诸如按照权重进行调度等策略。也可以对个 应用服务器进行健康监控,对无效服务器不在把请求转移给它;还可以实现sticky sessions。
作为 负载均衡调度器的反向代理服务器在扩展上的制约,反向代理服务器的处理能力制约了整个集群的处理能力,其次,容易出现 单点故障
IP负载均衡
Netfilter+ IPVS
用iptables修改Netfilter规则,进行基于IP的tcp包转发,也即调度。 IPVS(IP Virtual Server)也成为LVS(Linux Virtual Server)。
两者结合的具体策略有 1. LVS + NAT
2. LVS + DR
2其他编辑
内容分发和同步 WebDAV rsync etc
分布式文件系统
分布式计算
十二 性能监控
工具列表:
1. MRTG 网卡流量报告,可以获取实际带宽(Max Speed),它便是从 交换机接收端口获得的最大接收速度,同时也是该主机的最大数据发送速度。
2. apache ab 通过http进行压力测试
3. *nix中的strace, 追踪系统调用
4. 优秀的web server: apache, lighttpd, nginx
5. 反向代理:varnish
6. msyql工具: mysqlreport 数据库状态信息报表 mysql-proxy 数据库 反向代理 spock-proxy 分区反向代理
7. Nmon OS实时监控
8. Cacti 系统监控
9. 监控宝 响应时间监控
10. 分布式缓存 memcached</seconds>