摘要 一点一点拷贝
第一章 绪论
1.1 增加带宽
1.2 减少网页中的HTTP请求(Web网页前端优化)
1) 设计更加简单的网页,较少的图片和脚本
2) 将多个图片合并为一个文件使用CSS背景图片偏移计算呈现在网页中
3) 利用HTTP中浏览器的Cache策略
1.3 加快服务器脚本计算速度
1.4 使用动态内容缓存
1.5 使用数据缓存
1.6 将动态内容静态话
1.7 更换Web服务器软件
1.8 页面组件分离
1.9 合理部署服务器
1.10 使用负载均衡
1.11 优化数据库
1.12 考虑可扩展性
1.13 减少视觉等待
第二章 数据的网络传输
影响网络速度主要因素:
2.1带宽
2.2响应时间
2.3互联互通(服务器的部署问题)
第三章 服务器的并发处理能力
3.1吞吐率吞吐率压力测试
当前吞吐率查看:
Apache=>mod_status Apache启动时刻到目前时刻的平均计算值
Lighttpd=> mod_status最近5s的吞吐率目前时刻吞吐率单位时间流出数据量
压力测试工具
Apache=>ab Web服务器黑盒性能测试
3.2 CPU并发计算(只包含linux)
1)进程使用fork()调用注意:linux2.6以前 fork()的开销随当前进程数量递增而加大(进程间完全独立)
2)轻量级进程 linux2.0之后支持使用clone()创建允许共享部分资源如地址空间打开的文件等,减少了内存开销
3)线程实现1:pthread单一进程使用库函数模拟实现的多执行流,线程切换开销小,在SMP(多处理器)上表现较差(只有内核进程才能分配多个cpu时间)
实现2:LinuxThreads使用clone(创建线程)每个线程即是一个线程轻量级进程(linux 2.0以后)
4) 进程调度:进程优先级进程可以自己指定,进程调度器可以调整
Linux 2.6进程调度器倾向于I/O操作密集型的进程(I/O操作易阻塞释放时间片)
5) 进程切换 Apache的进程切换远大于Lighttpd(18166.5VS61.3)
6) IOWait CPU空闲且等待I/O操作完成的时间比例
7) 锁竞争尽量减少并发请求对共享资源的竞争(关闭Web服务器访问日志)
3.3系统调用系统调用将进程从用户态切换到内核态,会导致一定的内存空间交换(一定程度的上下文切换)所以系统调用的开销一般认为是比较昂贵的
(libc内的各种函数接口,times()等系统调用可以想办法减少)
3.4 内存分配 Apache使用内存池内存占用巨大并且性能不佳
Lighttpd内存使用量较小
Nginx 单一进程模式(多线程)内存使用量更小
3.5 持久连接 TCP连接的建立是昂贵的,使用长连接可以减少开销(HTTP请求数据头中包含 Connection:keep-Alive)
注:长连接会造成大量的空闲进程,会长时间大量无效占用资源
3.6 I/O模型同步阻塞、同步非阻塞、多路I/O就绪
Select:只支持1024个连接,调用时会扫描所有socket效率较低(水平触发)
Poll:同Select但是无连接数限制(水平触发)
SIGIO:边缘触发使用事件队列维护事件队列可能满事件可能过期
/dev/epoll
Epoll:同时支持水平触发和边缘触发只告知就绪的文件描述符,省略文件描述符复制开支,基于事件机制,回调方式通知
Kqueue:支持平台不足
3.7 直接I/O(O_DIRRCT/O_SYNC—只对写数据有效)不使用内核缓冲区在用户态实现缓冲区,直接I/O文件系统
3.8 sendfile 文件不载入内存直接将数据从文件系统载入网卡内核缓冲区 sendfile64 发送大文件
3.9异步I/O(AIO) 很多平台未实现
服务器并发策略
1. 一个进程处理一个连接,非阻塞I/O
方式1:主进程负责accept来自客户端的连接,然后fork子进程处理
方式2:1)建立进程池,主进程使用非阻塞accpt()建立连接后分配给子进程
2)子进程使用阻塞accpt()竞争请求,建立连接的子进程负责后续处理
Apache2.x使用方法2中第2中模式
结论:并发数要求不高(150以内)有其他功能要求的站点使用(单进程模式稳定性高,错误不会扩散)
2. 一个线程一个连接,非阻塞I/O
Apache work模型吞吐能力有少量上升很少使用
3. 一个进程处理多个连接,非阻塞I/O
Epoll适合处理大量非活跃链接
Poll对大量非活跃连接支持不好
Select 对于稍大的静态文件并发度支持严重不足
Work进程越多并发处理能力越大,但是受进程本身复杂度限制,work进程太多会导致进程切换开销
4. 一个线程处理多个连接,异步I/O(lighttpd 1.5使用linuxAIO,尚未实现)
第四章 动态内容缓存
4.1 缓存网页工作中最慢的部分例如数据库连接等
4.2 缓存与速度:缓存命中率
4.3 页面缓存直接缓存动态网页的html(动态图片动态xml数据等)
Smarty缓存框架 is_cached()判定通过后会直接读取缓存
缓存的持久化与查找:
1) smarty->use_sub_dirs(默认关闭)支持缓存文件的目录分级管理(根据URL自动生成目录与文件名)
2) smarty->cache_lifetime(s为单位的缓存过期时间)smarty->caching=1、2分别缓存过期的相对时间和绝对时间命中缓存的开销:is_cached、display涉及大量的字符串操作
3) 原则:在动态加载HTML缓存并终止程序前我们要让它尽可能只加载必要的其他文件这些文件越少越好(缓存文件的磁盘I/O开销程序库等)
4) 将缓存保存在内存 PHP的APC模块(以key-value方式保存APC数据),XCache模块(apc_fetch->apc_add、xcache_get->xcache_set)
5) 使用缓存服务器(memcached)(get->set)同样使用key/value方式保存(memcache_connect连接到缓存服务器注意TCP_IP开销)
6) APC/XCache的优势:使用本地内存,速度最快;缺点:使用本地内存,容量受限,在站点规模扩展后需要考虑引入memcached缓存服务器
7) 缓存的有效期和缓存强制清除策略
4.4 局部无缓存(特殊的动态网页也可能只有一部分区域需要及时更新)
1) Smarty 局部无缓存,使用smarty->register_block注册模板扩展标记,然后将不缓存部分用标签包围即可
2) Cakephp框架中使用<cake:nocache>标签包围无缓存区域即可
3) 需要将无缓存区域对应的动态数据计算提到缓存检查之前
4.5静态化内容前面描述的方法需要通过动态程序根据缓存有效期决定是否输出缓存,对缓存数据有较强的控制权,但是性能不足
1)直接访问HTML缓存(将cache目录下的php修改为html直接放在相应目录下)
优点:性能提高巨大
缺点:静态化网页仍然需要动态程序创建和更新,需要重新设计缓存更新、过期检查、缓存持久化等设计方案
使用CMS管理静态化内容
2)更新策略 a在数据更新时重新生成静态化内容 b 定时重新生成静态化内容
a=>频繁更新文件同步压力太大,一般引入更新延迟机制,更新任务加入队列,队列写满或者达到操死时间一次性写入磁盘(静态化缓冲区)
b=>定时更新(热门内容更新频繁其他内容更新时间延迟)
4) 局部静态化通过SSI(服务器端包含)技术实现各个局部页面的独立更新,减少网页计算时开销和磁盘I/O开销分发网络开销(Apche mod_include lighttpd mod_ssi)
注意:a一旦网页支持SSI,每次请求是服务器必须通读网页内容查找include标签,cpu开销大;b使用即使没有使用SSI,使用shtml网页后缀仍然会进行网页内容查找
解决方案 Apache使用Xbithack模式打开静态网页的SSI模式,通过修改网页权限来设置网页是否开启SSI