NGINX日志中错误代码499得含义
最近发现Nginx服务日志文件中有很多499的错误,到Http status code中检查没有发现这个问题,于是查看Nginx的源码,发现是 客户端主动断开连接会报这个错误。还有一些其他的自定义错误代码:
495 https certificate error
496 https no certificate
497 http to https
498 canceled
499 client has closed connection
Popularity: 9% [?]
Random Posts
使用fastcgi++编写fastcgi应用初探(一)
fastcgi++作为一个完全C++编写的fastcgi应用开发包,封装了很多功能,比如参数提取,session,mysql数据库连接管理等最大限度的简化cgi编程。
编写一个简单的helloworld的fastcgi应用。
-
#include <fstream>
-
#include <boost/date_time/posix_time/posix_time.hpp>
-
-
#include <fastcgi++/request.hpp>
-
#include <fastcgi++/manager.hpp>
-
-
void error_log(const char* msg)
-
{
-
using namespace std;
-
using namespace boost;
-
static ofstream error;
-
if(!error.is_open())
-
{
-
error.open("/tmp/errlog", ios_base::out | ios_base::app);
-
error.imbue(locale(error.getloc(), new posix_time::time_facet()));
-
}
-
-
error << '[' << posix_time::second_clock::local_time() << "] " << msg << endl;
-
}
-
-
class Helloworld: public Fastcgipp::Request<char> {
-
public:
-
bool response()
-
{
-
out << "<html><body>";
-
out << "Hello world!";
-
out << "</body></html>";
-
return true;
-
}
-
}
-
main(){
-
try
-
{
-
Fastcgipp::Manager<Helloworld> fcgi;
-
fcgi.handler();
-
}
-
catch(std::exception& e)
-
{
-
error_log(e.what());
-
}
-
}
可以看到基本的只要从 Fastcgipp::Request
Popularity: 7% [?]
Related
Linux每进程线程数问题处理
公司的一台服务器升级,原先运行正常的一个服务经常会跳出,于是予以分析解决。
该服务是一个tcp的服务端程序,被动接收客户端连接处理数据,升级后当客户端连接到一定量后程序会自动跳出。
使用netstat查看各个状态的数量
netstat -na |awk ‘{print $6}’|sort |uniq -c |sort -nr
发现很多的CLOSE_WAIT,并且还在不断增加中。
觉得可能是CLOSE_WAIT得不到释放,占用很多资源,
于是修改sysctl.conf中关于tcp连接的连接时间等设置,结果问题依旧。
怀疑收到攻击,使用
netstat -na |grep CLOSE_WAIT|awk ‘{print $5}’|awk -F”:” ‘{print $1}’|sort |uniq -c |sort -nr |wc -l 查看连接过来的地址,发现都是地址来源都是正常的
首先检查
使用 ps -fe |grep programname 查看获得进程的pid
再使用 ps -Lf pid 查看对应进程下的线程数,发现数值为303,远小于实际应该的数量。于是初步判断是由于线程数不够造成的原因。查找资料发现可以通过设置 ulimit -s 来增加每进程线程数。
每进程可用线程数 = VIRT上限/stack size
其中 VIRT 上限: 32位x86 = 3G 64位x64=64G
statck size 默认是 10240 因此在默认情况下
32位系统上单进程最多可以创建300个线程,
64系统在内存充足的情况下最多可以创建 6400 个线程。
在机器硬件固定的情况下,可以通过 ulimit -s 降低stack size 的设置值来获得更多的每进程线程数。
Popularity: 7% [?]
Related
编译gdlib库碰到undefined reference to `png_check_sig’问题解决
采用源码方式编译php,需要gd库,同样采用源码编译,在编译过程中碰到 undefined reference to `png_check_sig’ 错误。
google了一下,发现由于使用的新的 libpng 1.4版本,去掉了png_check_sig函数,替换为了png_sig_check函数
,于是编辑gd库的 gd_png.c文件,将
-
if (!png_check_sig (sig, 8)) { /* bad signature */
-
return NULL;
-
}
修改为
-
if (png_sig_cmp (sig, 0, 8)) { /* bad signature */
-
return NULL;
-
}
再次编译通过
Popularity: 7% [?]
Related
编译安装fastcgi++库
从fastcgipp官方网站下载最新的fastcgi++-2.0alpha-81f89e4e.tar.bz2,
-
tar -xjvf fastcgi++-2.0alpha-81f89e4e.tar.bz2
-
cd fastcgi++-2.0alpha-81f89e4e
-
./configure
-
./make
-
./make install
该fastcgi++库完全使用c++编写,依赖boost库(要求>1.35),所以安装时需要先安装boost库。
编译过程中碰到问题 mysql_set_character_set 找不到问题,修改 src/mysql.cpp 文件,将如下两行注释掉
-
//if(mysql_set_character_set(&connection, charset))
-
// throw Error(&connection);
再次编译通过。
安装后include头文件被拷贝到 /usr/local/include/fastcgi++/,库文件被拷贝到 /usr/local/lib/fastcgipp.a
编译examples目录下测试用的fastcgi应用,验证编译安装的正常性。
使用默认的 make examples 没有编译通过。打开Makefile文件,发现缺少对 boost库的引用,将其添加上,再次编译,通过。
-
FASTCGIPP_INCLUDE=/usr/local/include/fastcgi++
-
BOOST_INCLUDE=/usr/local/include/boost-1_39
-
BOOST_CPPFLAG=-I$(BOOST_INCLUDE) -pthread
-
BOOST_THREADLIB=-lboost_thread-gcc34-mt-1_39 -pthread
-
-
pkgConfigLibs=-lfastcgipp -lboost_thread -lmysqlclient
-
CXX=g++
-
CXXFLAG= -g -O2
-
-
database.fcgi: database.cpp
-
$(CXX) -o database.fcgi database.cpp -I$(FASTCGIPP_INCLUDE) $(pkgConfigLibs) $(BOOST_CPPFLAGS) $
-
(CXXFLAGS) $(BOOST_THREAD_LIBS)
-
-
clean:
-
rm -f *.fcgi
—————-
默认Makefile编译不通过的原因
1. 缺少对boost库的目录include引用
2. 缺少boost线程库的应用,默认使用的是-lboost_thread 需要为-lboost_thread-gcc34-mt-1_39 -pthread
Popularity: 6% [?]
Random Posts
nginx中的多条件rewrite解决方案
前两天在搞 nginx 的rewrite, 其中有个地址需要用到多条件判断,结果试了好久,没有办法在nginx中写出复合方式的条件判断,比如
if ($request_method !~ ^post$ && $request_filename !~ ^/file/a.* ) {
rewrite …
}
网上参照了一篇,可以通过nginx的set命令,来设置变量进行前置判断,从而达到多条件的rewrite实现。
# 先定义两变量备用
set $my_file ”;
set $my_uri $request_uri;if ($request_method = POST) {
set $my_uri ”;
}# 使用友好的地址方式
if ($query_string) {
set $my_uri ”;
}…
# 判断$my_uri是否为空,不为空,则设置要rewrite到的文件,再在下面用rewrite转
if ($my_uri ~ ^(.+)$) {
set $my_file /cache/myfile/$http_host/$1index.html;
}if (-f $document_root$my_file) {
rewrite ^(.*)$ $my_file break;
}
将名为$my_uri的变量作为标志位,如果不满足一些前置条件时,将标志位置空;
在最后只要判断标志位是否为空,如果不为空,再进行rewrite
Popularity: 6% [?]
Related
Nginx常见应用技术指南(Nginx Tips) – 转
Nginx 常见应用技术指南(Nginx Tips)[定期更新]
作者:NetSeek http://www.linuxtone.org(IT运维专家网|集群架构|性能调优)
欢迎转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明.
更新时间:[2008-12-4] 第一版:[2008-11-25]
目录:
一. Nginx基础知识
二. Nginx安装配置
三. Nginx Rewrite
四. Nginx Redirect
五. Nginx 目录自动加斜线
六. Nginx 防盗链
七. Nginx expires
八. Nginx 访问控制
九. Nginx Location
十. Nginx 日志处理
十一. Nginx Cache服务配置
十二. Nginx 负载均衡
十三. Nginx 优化
十四. Nginx 相关参考文档
Read more
Popularity: 6% [?]
Related
Web中一些不利于做缓存的因素
Web中不利于做缓存的一些因素,以及怎样尽可能的减小这些不利因素对缓存处理的影响。
- 使用SSL做通信的页面
- 使用Http验证的保护页面
- 使用Cookie的页面
- 限制使用Cookie的目录
- 对静态资源比如图片尽量不要让cookie沾上
- 使用动态内容的页面
作为安全通信,不做缓存处理,这个时候我们要考虑是否所有的页面内容都是否必须做安全通讯保护的,根据需要可以努力将一部分(如图片等)静态资源内容通过http协议走,而不是全部通过SSL协议走,这样就可以使部分没有必要通过SSL协议走的内容可以做缓存处理,减少服务器的负载和降低网络流量的使用。
这个和SSL处理有点类似,同时也可以通过 Cache-Control中的public命令来做一些控制。
一般使用Cookie是为了保存一部分个人设置信息。
在Cookie的设置中,注意domain和path值的设置,path值不设置就是默认都整个domain下的了
可以设立独立的域名做文件服务器,这样原有域上的Cookie信息就不会跟着走
可以使用头信息来设置动态内容的一些过期失效时间,但一般来说,动态内容只是一个页面中的一部分,其他大部分还是相同,可以采取模板化处理,在页面中使用嵌入脚本嵌入动态内容,这样可以方便达到部分缓存处理的目的,同时减低一些网络流量。
Popularity: 6% [?]
Related
Web Cache Tutorial for Web Authors and Webmasters(译)Part-2
原文标题: Caching Tutorial for Web Authors and Webmasters
原文地址: http://www.mnot.net/cache_docs/;
译文地址: http://www.sunnyu.com/?p=164
前段地址: Caching Tutorial for Web Authors and Webmasters(译)Part-1
本文由 sunny译于 2009.01.16 由于英文水平有限,译文难免有很多不足之处,欢迎指正。
Tips for Building a Cache-Aware Site
在使用 新鲜度信息 和 校验器 之前,你还可以做很多事情来使你的网站对缓存处理是友好的。
- Use URLs consistently — 这是做缓存处理的黄金准则. 如果你为不同页面,不同用户或不同网站提供相同的内容,他们应该使用相同的URL. 这很简单并且是一个很有效的方法使你的网站是cache-friendly. 比如,如果你使用“/index.html” 在你的HTML做为你网站的参考,那就总是这么使用.
- Use a common library of images 其他在不同地方的元素来引用他们.
- Make caches store images and pages that don’t change often 通过使用
Cache-Control: max-age
头信息设置一个很大的值. - Make caches recognize regularly updated pages 通过设置一个适当的 max-age 或 expiration 时间.
- If a resource (especially a downloadable file) changes, change its name. 这种办法,你可以设置他在未来很长时间后才失效并保障正确的文件版本被提供; 引用的页面文件则需要一个小的失效时间。
- Don’t change files unnecessarily. 如果你这么做了,新的Last-Modified日期将会使所有相关信息的验证失败. 比如, 在更新网站的时候,不要覆盖整网站,只对变化的文件做处理.
- Use cookies only where necessary — cookies很难被缓存,并且在多数时候并不是必须的.如果你必须使用Cookie,在动态页面中要有节制的使用。
- Minimize use of SSL — 因为加密的页面不会在共享缓存中保存, 只有在你必须用的时候采用, 在SSL页面中谨慎使用图片。
- use the Cacheability Engine — 可以帮助你应用本教程所阐述的很多观念。
Writing Cache-Aware Scripts
默认情况下, 很多脚本不会返回校验器 ( Last-Modified
或 ETag
回应头) 或新鲜度信息 (Expires
或 Cache-Control 头信息
).有一些脚本确实是动态的 (意味着每一次请求都返回不同的内容), 但更多 (像搜索引擎和基于数据库的网站) 的是可以从缓存中获得好处的。
一般说来,如果一个请求的内容在一段时间后(一些分钟后或一些天后)可以使用同样的请求重现, 它应该是可缓存化的。如果返回内容只和请求的URL地址有关,那么它是可缓存的;如果输出内容和Cookie,验证信息或其他外部标准有关,那么它们一般是不可缓存的。
- 将脚本缓存化的最好的办法是将将变化后的内容导出保存到一个文件中, 然后Web服务器可以将他们和其他Web页面一样看待,生成和使用校验器, 这样可以使你的工作容易些。记住:只要写那些发生了变化的文件, 这样
Last-Modified
的时间就是实际期望的。 - 另外一种方法就是给内容设置一个时间相关的头信息(适合使用的足够长时间)。 可以通过
Expires
头信息设置,不过更简单的是通过Cache-Control: max-age
头信息来做,他使内容在请求发生后的一个足够长时间内保持鲜活的。 - 如果你不能那么做,那么你需要通过脚本生成一个校验器, 然后回应
If-Modified-Since
和/或If-None-Match
请求. 这个可以通过分析HTTP头信息, 然后在适合的时候回应一个304 Not Modified
。 不幸的是,这是个不简单的任务。
其他一些技巧;
- Don’t use POST 除非是适合的. 大多数缓存器对POST方法的回应是不做缓存的; 如果你使用GET方法获取信息,缓存器可以保存信息为将来使用.
- Don’t embed user-specific information in the URL 除非生成的内容完全和那个用户相关。
- Don’t count on all requests from a user coming from the same host, 因为缓存器通常是一起工作的。
- Generate
Content-Length
response headers. 这个很容易做, 它将使你脚本的回应使用一个 持久连接(persistent connection)。 他允许客户端通过一个 TCP/IP 连接请求很多内容, 而不是对每个请求都建立一次连接. 他使你的网站看上去比较快.
查看 Implementation Notes 获取更多信息。
Frequently Asked Questions
What are the most important things to make cacheable?
一个很好的策略就是先鉴别出最热门,使用量最大的内容(特别是图片),拿它们先开刀.
How can I make my pages as fast as possible with caches?
最适合缓存化的内容要给他设置一个长的用来保持新鲜度的时间。校验器会来计算减少这个鲜活时间,但是缓存器仍然会和原始服务器做交互来检查看它是否是新鲜的。如果缓存器知道它是新鲜的,就直接从缓存器中提供给客户端显示用。
I understand that caching is good, but I need to keep statistics on how many people visit my page!
如果你必须知道每一次页面被访问的情况, 在页面上选中一个小元素 (或页面信息), 通过设置一个适当的头信息使它是不可缓存的. 比如, 你可以在每一个页面上引用一个 1×1 的不可缓存透明图片. Referer
头信息将会包含调用它的页面信息.
请注意,即使这样也不能给出关于你用户的精确统计, 并且对通过互联网访问的用户也不是很友好,他产生不必要的流量, 并强迫用户等待未被缓存的内容从网络上下载回来, see On Interpreting Access Statistics in the references.
How can I see a representation’s HTTP headers?
很多浏览器使你能够在”page info”或类似的界面中看到 Expires
和 Last-Modified
头信息。如果有的化,会给你一个关于页面和其上相关内容的细节内容菜单.
为了看到内容的完整头信息,你可以使用Telnet客户端手工连接到Web服务器.
要注意的是,你必须指定连接的端口(一般是80),比如你可以连接到 www.example.com:80
或 www.example.com 80
(注意空格). 具体查看你telnet客户端的文档.
当你连接到一个网站后,输入请求内容。比如, 如果你想看到 http://www.example.com/foo.html 的头信息
, 首先连接到 www.example.com
, 80
端口,并输入:
GET /foo.html HTTP/1.1 [return] Host: www.example.com [return][return]
[return]等同
敲回车键; 确认最后输入两次.这样将输出头信息,然后跟着实际内容. 如果只想看到头信息, 使用HEAD 来替换 GET.
My pages are password-protected; how do proxy caches deal with them?
默认情况下, 被HTTP验证保护的页面被当作是私有的; 他们不会在共享缓存中保留. 然而你可以使用Cache-Control: public 头信息将被验证保护地页面标志为公共的; 这样HTTP 1.1-compliant 的缓存器将允许他们被缓存。
如果你期望这些文件被缓存, 但仍然要多每一个用户做验证, 将 Cache-Control: public
和 no-cache
头信息组合起来。这告诉缓存器它在从缓存中送出内容前必须递交客户端的验证给原始的服务器。这个头信息如下所示:
Cache-Control: public, no-cache
不用管它是怎么做的, 它最小化了验证过程; 比如:如果你的图片是不敏感的, 将他们放到一个单独的目录并配置你的服务对他们不做强制验证。这样,那些图片就会很自然的被缓存了。
Should I worry about security if people access my site through a cache?
SSL 页面不会被代理缓存, 因此你不需要担心会通过缓存获取敏感信息。 However, because caches store non-SSL requests and URLs fetched through them, 你必须对不安全的网站有所认识; 一个不道德的管理员可能会通过缓存搜集用户的信息(特别是在URL信息中)。
实际上,任何在网络上介于你服务器和客户机之间的管理员都可以收集这类信息. 个别情况如在CGI脚本在URL地址中传递用户名和密码信息时;这很容易让其他人发现用户的登陆信息。
不过如果你关注关于网站安全的一般性问题, 你就不会对代理缓存的这个情况感到惊奇。
I’m looking for an integrated Web publishing solution. Which ones are cache-aware?
这个是不确定的. 一般来说,越复杂的系统越难缓存. 最差的情况就是所有的内容都是动态生成,并且不提供校验器; 他们根本不可能被缓存. 和你的供应商的技术人员沟通获取更多信息, 然后看下面的 Implementation notes.
My images expire a month from now, but I need to change them in the caches now!
Expires头信息设置的时间不会被中断破坏; 除非缓存器 (浏览器或代理) 主动删除内容, 否则缓存的内容会被保留使用直到设定的时间。
最有小的解决方法就是修改任何指向他们的连接; 这样, 就会从原始服务器中完整的获得新内容。记住被页面引用的内容用也会被缓存. 因为这个原因,最好使HTML页面指向的那些静态图片或类似内容也是很好缓存的。
如果你想让指定的缓存器重新加载一个内容, 你可以在浏览器中强制重新加载一个被缓存的内容(在Firefox中, 在点 重新加载 按钮的时候按住 shift 键,将处理一个 Pragma: no-cache
请求头)。 或, 你可以让缓存管理员通过他们可以使用的接口界面删除缓存内容。
I run a Web Hosting service. How can I let my users publish cache-friendly pages?
如果你使用的是Apache, 考虑允许他们使用.htaccess 文件并提供适合的文档。
否则你需要在每一个虚拟主机上为各种缓存属性建立预定的区域。比如:你可以指定一个叫 /cache-1m 的目录用来放读取后要缓存一个月的内容,然后再建一个/no-cache的目录在头信息中指定这么目录中的内容不要被缓存。
不管你能够怎么做,最好先给最大量的用户内容做缓存处理。在大型网站上这会给网络流量和机器负载上节约很多。
I’ve marked my pages as cacheable, but my browser keeps requesting them on every request. How do I force the cache to keep representations of them?
通常缓存器会对一个标志缓存的内容做本地备份并重用它,但是在某些条件下一些内容不会被缓存重新使用。 缓存器基本上是基于内容的大小,类型(图片或html文件)或如果保留它们需要占用多少本地空间等来决定一个内容是否被缓存重用。
一些缓存器允许管理员设置对不同类别内容的保留优先级,另外一些则允许一些内容驻留(“pinned”)在缓存中,这样他们总是可用的。
Popularity: 6% [?]
Related
Web Cache Tutorial for Web Authors and Webmasters(译)Part-1
原文标题: Caching Tutorial for Web Authors and Webmasters
原文地址: http://www.mnot.net/cache_docs/;
译文地址: http://www.sunnyu.com/?p=163
本文由 sunny译于 2009.01.15 由于英文水平有限,译文难免有很多不足之处,欢迎指正。
What’s a Web Cache? Why do people use them?
Web cache 存在于客户端和服务器(原始服务器)之间,它监测过来的请求并将对请求的回应做拷贝保存 — 使其就像通常的HTML页面, 图片和文件一样 (collectively known as representations). 然后当有另外一个同样的请求(相同的url地址参数)过来的时候,他就使用前面复制保存的内容做回应而不是再次从原始服务器获取回应内容.
使用 Web caches 主要有以下两个主要原因:
- 降低延时 — 因为用户请求不是从原始服务器返回而是从Cache返回(离客户更近), 所以客户端可以花更少的时间获取并显示它. 这样使网站看起来更快响应.
- 降低网络流 — 因为表现内容被重用, 它大大降低了用户使用的网络带宽,这样也变相节约了金钱(如果客户要为流量付费), 他将低了对网络带宽的要求并且便于管理.
Kinds of Web Caches
Browser Caches
如果你检查网页浏览器的偏好设置对话框,你应该会看到”Cache”设置的项目。这个设置项通过使用你本地机器上的一些硬盘空间来存储你用浏览器看到的内容。浏览器端的Cache使用很简单的机制工作。他通常会在一次浏览期间检查确认要显示的内容是新的。
这种Cache在用户按”back”按钮或这点击一个刚刚看过的链接地址时显得特别有用。同样,如果你在整个网站中使用同样的导航图片,也会从浏览器的Cache中获得巨大好处。
Proxy Caches
Web proxy caches 基于和浏览器Cache类似的规则,但是更具有可伸缩性. Proxies 使用相同的方法为成千上万的用户提供服务;大企业和ISP通常会在他们的防火墙上设置它(或在一些独立的设备上设置)。
因为proxy caches不是客户机或服务器的一部分,但是他们存在于网络上,通常客户的请求会通过一些方式路由到Proxy Cache这儿.一种方式就是在你的浏览器的代理设置中手工告诉你要使用的代理服务器。另外一种方式便是拦截. Interception proxies 将用户的请求通过下层网络进行重定向, 因此客户不需要进行设置,甚至于不知道有它存在。
Proxy caches 是一种共享缓存(shared cache); 和只有一个用户使用的浏览器缓存不同的是,他通常有大量的用户在使用,因此他能大量减少响应延时和网络通讯,因为热门的内容可以被重用n多次。
Gateway Caches
Also known as “反向代理(reverse proxy caches)” or “surrogate caches,” gateway caches 也是一个中介物, 但它不是由网管设置用来节约浏览,通常是由 网站管理员自己设置来时他们的网站具有更好可伸缩性,可用性和更好的性能.
请求可以有多种方法路由到 gateway caches , 但是典型的负载均衡方式会将他们中的一个或多个原始服务器当作客户端看待.
Content delivery networks (CDNs) distribute gateway caches throughout the Internet (or a part of it) and sell caching to interested Web sites. Speedera and Akamai are examples of CDNs.
本篇教程关注点主要在浏览器缓冲和代理缓存,然而一些信息同样适合于gateway cache。
Aren’t Web Caches bad for me? Why should I help them?
Web Caching 是在互联网方面最易被误解的一项技术。网站管理员有点害怕对他们的网站失去控制,因为proxy Cache会对他们”隐藏”他们的用户,使他们很难得到是哪些人访问了他们的网站。
然而对这些人有些不幸的是, 即使 Web caches 不存在, 在互联网上仍然会有很多变化用来保障他们能够精确的获取用户是怎样看他们网站的。如果这是是你关注的大方面,本教程将会教会你在保留缓存的情况下怎样获取这些你需要的这些统计信息。
另一方面,缓存会提供过时(陈旧)的内容,本教程将教会你怎样配置你的服务器来控制被缓存的内容。
CDNs are an interesting development, because unlike many proxy caches, their gateway caches are aligned with the interests of the Web site being cached, so that these problems aren’t seen. However, even when you use a CDN, you still have to consider that there will be proxy and browser caches downstream.
另一方面,如果你很好的对您的网站进行了规划,缓存将能够帮助你提高网站的压力负载响应更多的用户连接。差异是显著的; 一个没有很好缓存处理的网站或许会化好一会时间加载页面, 然而和一个从缓存中获得好处的网站做比较就会显得不怎么样。用户喜欢快速的网站,将会引起更多次的访问.
想象一下,很多大型的互联网公司花费大量的金钱在世界各地建立了很多服务器用来复制他们的内容,目的就是想为他们的用户提供尽可能快的存取速度。缓存可以为你做同样的事情,并且他们更接近于客户。最重要的是,你不必为此额外付费.
其实不管你喜不喜欢,代理缓存和浏览器缓存都被被应用. 如果你不能正确配置你网站的cache,他就会按照采用默认的方式(或缓存管理员决定的的方式)做缓存.
How Web Caches Work
所有的缓存器都有一些规则用来决定什么时候从缓存中提供内容. 其中一些规则由 (HTTP 1.0 and 1.1)协议指定, 还有一些由缓存的管理员设定 (浏览器缓存的使用者或代理的管理员).
一般说来,有如下一些通用规则 (如果你不明白细节,不要担心,后面会有详细说明):
- 如果回应的头信息告诉缓存不要保留他,缓存就不保留它
- 如果被请求的内容是需要验证(安全保护的),他不应该被缓存
- 如果没有校验器 (
ETag
或Last-Modified
头信息) 在回应中设置, 并且没有任何显式的关于新鲜度的信息, 将被当作不可缓存的. - 如果满足下列情况,一个被缓存的内容可以被认为是新鲜的(fresh )(意味这可以直接发送给客户端而不用检查原始服务器) :
- 如果有失效时间(expiry time)或其他关于时间控制的 头信息 被设置,并且仍然在新鲜(fresh)的时间里面.
- 如果浏览器缓存已经看到内容,并且被设置为一次浏览期间只检查一次.
- 如果代理缓存最近看到内容并被修改成相对之前很长的一段时间.
新鲜的内容不用检查原始的服务器,直接从重缓存中提供.
- 如果内容是过时的,原始服务器将被用来验证检查(validate)或告诉缓存该内容的拷贝是否还是好的.
新鲜度(freshness) 和校验器(validation) 对缓存内容很重要.一个新鲜的内容将被立即从缓存中返回,校验过的内容避免失效内容被发送.
How (and how not) to Control Caches
有一些工具可供网站设计人员和网站管理员来对网站的缓存使用情况进行调优。也许在配置服务器的过程中是手脏一点,但显然做这些是值得。 在您服务器上使用这些工具的具体细节可以参照下面的 Implementation 段落.
HTML Meta Tags and HTTP Headers
HTML 作者可以在 <HEAD> 段插入一些Tag. These meta tags are often used in the belief that they can mark a document as uncacheable, or expire it at a certain time.
Meta tags 很容易使用,但不是很有效. 那是因为他们只被一些浏览器缓存使用(他们实际读入 HTML 页面), 不是代理缓存(他们根本不读入HTML信息). 然而可以通过放一个 Pragma: no-cache 的meta标签到Web页面上, it won’t necessarily cause it to be kept fresh.
如果你的网站托管在 ISP 或者主机托管商那里,并且他们没有赋予您任意设置HTTP头信息的能力,(比如 Expires
和 Cache-Control
), 要大声抱怨,因为在你的工作中这些是必须的。
另一方面, 真实的 HTTP headers 将给你很多关于浏览器缓存和代理缓存对于你页面内容缓存行为的控制。他们在HTML页面中不可见,通常是由Web服务器自动生成的。然后,你可以在某种程 度上对他们进行控制(具体要看你所使用的服务器)。下面的章节,你经看到哪些HTTP头信息应该被关注,并且怎么在你的网站中应用他们。
服务器在HTML信息前发送HTTP头信息, 他们被浏览器和任意中间缓存看到. 典型的 HTTP 1.1 回应头信息可能如下面这样:
HTTP/1.1 200 OK Date: Fri, 30 Oct 1998 13:19:41 GMT Server: Apache/1.3.3 (Unix) Cache-Control: max-age=3600, must-revalidate Expires: Fri, 30 Oct 1998 14:19:41 GMT Last-Modified: Mon, 29 Jun 1998 02:28:12 GMT ETag: "3e86-410-3596fbbc" Content-Length: 1040 Content-Type: text/html
HTML 信息将有一个空行分隔跟随在这些头信息后面,查看 Implementation 章节看怎么设置 HTTP 头信息.
Pragma HTTP Headers (and why they don’t work)
很多人相信,设置一个Pragma: no-cache
的HTTP 头信息中将使内容不会被缓存。但这个不是总成立; HTTP 规范未对Pragma回应头信息做任何设置指导。 但是有关于 Pragma 的请求头信息 (由浏览器发送给服务器的头信息) 的讨论。虽然有些缓存对此做实现,但是主流的并未实现,使用这个并没有任何效果。要使用下面说明的一些头信息来控制。
Controlling Freshness with the Expires HTTP Header
Expires
是用来控制缓存的基本HTTP 头信息; 它告诉所有的缓存相关的内容将会保持新鲜多长时间. 在那时间后, 缓存将和原始服务器做比较检查看内容是否发生改变. Expires
头信息几乎被所有的缓存支持。
多数服务器允许你通过多种方式设置 Expires
回应头信息. 通常,他们允许设置一个失效的绝对时间, a time based on the last time that the client saw the representation (last access time), or a time based on the last time the document changed on your server (last modification time).
Expires
头信息特别适合于使静态图片缓存化(比如导航条和按钮图片). 因为他们通常不会发生变化,你可以给他们设定一个相对长的失效时间,是你的网站更快的回应用户的请求. 他们也适合控制定期改变的页面缓存. 比如, 如果你在每天早晨6点半更新一个新页面,你可以设置为在那个时间失效, 这样缓存器就知道什么时候应该获取一个新的拷贝,不需要用户按 “刷新” 按钮。
在 Expires
头信息中只能使用 HTTP date; 任何其他的内容基本上会被解释为 ‘in the past’, 这样内容将不会被缓存,同样要记住,HTTP date 是格林威治时间(GMT),不是本地时间.
一个例子:
Expires: Fri, 30 Oct 1998 14:19:41 GMT
有一点很重要,如果你使用 Expires 头信息,您应该确保Web服务器的时间是精确的.你可以通过使用 Network Time Protocol (NTP) 协议来做到;和你本地机器的管理员沟通一下。
虽然 Expires
头很有用, 它还是有有些限制. 首先, 由于和时间有关, 服务器的和缓存机器的时间必须同步;如果时间不一致, 可能不会达到期望的效果,缓存机可能错误的将过时的内容当作新鲜的.
另外一个问题是,它很容易忘记一些信息被设置为在某一个具体时间后失效. 如果你不在他失效前更新失效时间,之后的每一次请求都会回到你真实的Web服务器上,增加了负载和延时.
Cache-Control HTTP Headers
HTTP 1.1 阐述了一个新类别的头信息: Cache-Control
回应头信息, 给Web发布者们更多关于他们内容的缓存的控制,由此避免 Expires 的缺点。
有用的 Cache-Control
回应头信息包括:
max-age=
[seconds] — 设定最长多长时间内认为该内容是新鲜的,和Expires 有点类似
, 该指令是相对于请求的时间。 [seconds] 是相对于请求时间你期望保持新鲜度的时间.s-maxage=
[seconds] — 类似max-age
, 除了他只对共享的缓存器作用 (比如 proxy).public
— 标志验证过的回应是可缓存的;通常,如果需要 HTTP 验证, 回应会自动不可缓存化 (针对共享缓存).no-cache
— 每一次在释放一个缓存内容前都强制缓存器将请求提交给原始的服务器来校验. 这个在期望做鉴定保证的时候很有用(通常和 public 做组合), 或用来维护一个严格的新鲜内容,牺牲缓存带来的好处。no-store
— 指示缓存器在任何情况下都不要在本地保留拷贝.must-revalidate
— tells caches that they must obey any freshness information you give them about a representation. HTTP allows caches to serve stale representations under special conditions; by specifying this header, you’re telling the cache that you want it to strictly follow your rules.proxy-revalidate
— 类似must-revalidate
, 除了它只对 proxy缓存器作用。
一个例子:
Cache-Control: max-age=3600, must-revalidate
如果你计划使用 Cache-Control
头信息, 你应该好好看一下 HTTP 1.1 文档; see References and Further Information.
Validators and Validation
在 How Web Caches Work, 我们说校验被服务器和缓存器使用来交流什么时候一个内容发生了变化. 通过使用它, 缓存器避免下载本地已经有的但是不确定是否仍然是新鲜的内容.
校验器很重要; 如果对一个内容缓存器中现在没有拷贝,并且这个内容没有关于新鲜度的信息 (Expires
或 Cache-Control
) , 缓存器将根本不对其做拷贝保存.
通常 校验器 是文档最后修改的时间, 由Last-Modified
头信息交互. 当缓存器有一个包含 Last-Modified
信息的内容被保存, 他可以使用这个信息去询问服务器这个内容是否发生了改变( 通过一个If-Modified-Since
请求).
HTTP 1.1 引入一个新的叫 ETag 的校验器. ETags 是一个有服务器端生成的唯一标识,并且每一次内容发生变化ETag也会发生变化. 因为服务端控制 ETag 怎样生成, 缓存器可以通过判断 ETag 是否匹配来看本地拷贝的内容是否和服务器端的一样(通过一个If-None-Match 请求)
.
几乎所有的缓存都使用 Last-Modified 时间来判断一个内容是否是新的; ETag 校验也变得很流行。
目前多数Web服务器会自动为静态内容(比如图片文件)生成 ETag
和 Last-Modified
头信息来当作校验器; 你不需要做任何事情。然而, 对于动态的内容,他们没有足够信息去自动生成这个信息 (比如 CGI, ASP 或 数据库的网站); see Writing Cache-Aware Scripts.
Popularity: 6% [?]