|
基于squid面向apache作反向代理的php程序设计技巧
squid 已经不再仅仅是一个 proxy server了,越来越多的站点采用 squid 作 前端服务,后方运行着若干台真正的 web server(apache)在服务... (注: 就算只 有一台服务器, 也可以同时安装squid +apache一起服务),squid 本身强劲的缓存 设计大大提升 web 效率。
squid, apache 的配置安装均不是本文的重点,在此也不详述。一般情况下这 些缓存设计都擅长于静态网页或小图片或小文件等,而对于较为复杂的动态页面, 作这样的缓存均可能带来用户浏览效果的不实时,往往导致后端页面更新了前端却 还没有及时刷新,非常不爽。
其实在 php 脚本中, 结合 HTTP 标准头中有2个重要的标签可以很好的解决 这个困扰。即服务端发送的 Last-Modifed 和 客户端发送的 If-Modified-From 。
带 cache 的 squid 反向代理的工作关系流程图大致如下:
返回给用户 +--------------------------------------------+ | (有效)| \| 发出请求 |\ [User(Browser)] -------------> [Squid]------->[缓存仓库] /| \| / |(无效/不存在) (执行完成)/ |/ [WebServer(apache/php)] 假设 webServer 采用 php 脚本服务,每次的的请求产生的负载比较高(+db...) 当 php 能够在 squid 提交请求时通过 If-Modified-From 得知在 squid 缓存池中 的数据 Last-Modified 时间的话,通过比较时间戳记就可以知道缓存是否有效,若 有效那么 php 脚本就不需要从头执行完成,只要简单的输入 Last-Modified 的时间 即可退出程序 exit(0),节省不必要的程序开销。实现步骤如下:
1. # squid.conf (squid 的配置文件中确保相关的 URL 刷新写法如下) # 重点在于 0, 0% 和 reload-into-ims # 0, 0% 确保每次请求进来的时候 squid 都会向后台 server 提交请求 # reload-into-ims 选项保证了提交 If-Modified-From: 且会强制缓存数据直到 # LM 修改才清理... # # 特别注意: 不同的URL组成可以写好几条 refresh_pattern, # 仅针对动态+高负荷的 url 作如下处理即可. # refresh_pattern ^http: 0 0% 1440 reload-into-ims
2.
// 基于squid面向apache作反向代理的php程序设计技巧 // 作者: hightman 首次发布于 chinaunix.net PHP 版 // // 首先在 php 程序中,确保不要输出 Expires: HTTP 头 // // 当前 URL结构的最后更新时间,如 BBS 列表的话可以判断最新发贴时间, // 博客文章可以求出最后发表评论的时间,只要没有新发表或没有新评论不 // 必重新运行 php 脚本... $chrono = filemtime(__FILE__);
// 使用 apache 提供的函数,获取 If-Modified-Since $headers = apache_request_headers(); $client_time = (isset($headers['If-Modified-Since']) ? strtotime($headers['If-Modified-Since']) : 0);
// 比较 client_time 与 当前页面刷新时间 if ($client_time && $client_time >= $chrono) { // 表明 squid 的缓存是新的不必从头运行脚本,简单通过 HTTP 状态通知即可 // 发送 '304 Not Modified'. 然后退出脚本 header('Last-Modified: '.gmdate('D, d M Y H:i:s', $client_time).' GMT', true, 304); exit(0); } else { // 表明该页面比客户端提供的更新, 故需要重新运行脚本, 发送 200 状态 // 并提供 最近的 Last-Modified 时间 header('Last-Modified: '.gmdate('D, d M Y H:i:s', $chrono).' GMT', true, 200); }
// 对于一些特殊的 client 发起的 HEAD 请求,也不必生成实体内容,直接退出 :-P if (strtoupper($_SERVER['REQUEST_METHOD']) == 'HEAD') exit(0);
//
|