Nginx模块fastcgi_cache的几个注意点

本文探讨了Nginx FastCGI缓存机制,并通过实践测试揭示了影响缓存的因素,如Expires、Cache-Control等头部信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在web项目中,大家都已经非常熟悉其架构流程了。都说Cache是万金油,哪里不舒服抹哪里。这些流程中,几乎每个环节都会进行cache。从浏览器到webserver,到cgi程序,到DB数据库,会进行浏览器cache,数据cache,SQL查询的cache等等。对于fastcgi这里的cache,很少被使用。去年年底,我对nginx的fastcgi_cache进行摸索使用。在我的测试过程中,发现一些WIKI以及网络上没被提到的注意点,这里分享一下。


从浏览器到数据库的流程图

这里是我的NGinx配置信息

#增加调试信息
add_header X-Cache-CFC "$upstream_cache_status - $upstream_response_time";
fastcgi_temp_path /dev/shm/nginx_tmp;

#cache设置
fastcgi_cache_path   /dev/shm/nginx_cache  levels=1:2 keys_zone=cfcache:10m inactive=50m;
fastcgi_cache_key "$request_method://$host$request_uri";
fastcgi_cache_methods GET HEAD;
fastcgi_cache   cfcache;
fastcgi_cache_valid   any 1d;
fastcgi_cache_min_uses  1;
fastcgi_cache_use_stale error  timeout invalid_header http_500;
fastcgi_ignore_client_abort on;

配置这些参数时,注意每个参数的作用域,像fastcgi_cache_path参数,只能在http配置项里配置,而fastcgi_cache_min_uses这个参数,可以在http、server、location三个配置项里配置。这样更灵活的会每个域名、每个匹配的location进行选择性cache了。具体的参数作用域,参考FASTCGI模块的官方WIKI。我为了调试方便,添加了一个『X-Cache-CFC』的http响应头,$upstream_cache_status 变量表示此请求响应来自cache的状态,分别为:

  • MISS 未命中
  • EXPIRED – expired, request was passed to backend Cache已过期
  • UPDATING – expired, stale response was used due to proxy/fastcgi_cache_use_stale updating Cache已过期,(被其他nginx子进程)更新中
  • STALE – expired, stale response was used due to proxy/fastcgi_cache_use_stale Cache已过期,响应数据不合法,被污染
  • HIT 命中cache


FASTCGI_CACHE $upstream_cache_status 结果为miss,一次也没命中

程序代码是Discuz!论坛, 随便开启测试了几下,发现/dev/shm/nginx_cache/下没有任何目录建立,也没有文件创建。调试的http header响应头里的X-Cache-CFC 结果一直是MISS。从服务器进程上来看,Nginx cache manager process 跟Nginx cache loader process 进程也正常运行:

root      3100     1  0 14:52 ?        00:00:00 nginx: master process /usr/sbin/nginx
www-data  3101  3100  0 14:52 ?        00:00:00 nginx: worker process
www-data  3102  3100  0 14:52 ?        00:00:00 nginx: cache manager process
www-data  3103  3100  0 14:52 ?        00:00:00 nginx: cache loader process

不知道为何会这样,为何没有cache成功,我以为我配置参数有问题,只好阅读WIKI。发现fastcgi_ignore_headers 参数下解释有这么一段

fastcgi_ignore_headers
Syntax: fastcgi_ignore_headers field …
Default:
Context: http
server
location
Reference: fastcgi_ignore_headers

This directive forbids processing of the named headers from the FastCGI-server reply. It is possible to specify headers like “X-Accel-Redirect”, “X-Accel-Expires”, “Expires” or “Cache-Control”.

也就是说这个参数的值,将会被忽略掉,同样被忽略掉的响应头比如”X-Accel-Redirect”, “X-Accel-Expires”, “Expires” or “Cache-Control”,而nginx配置中并没有fastcgi_ignore_headers参数的设定,那么问题会不会出现在FASTCGI响应结果里包含了类似”X-Accel-Redirect”, “X-Accel-Expires”, “Expires” or “Cache-Control”这几个响应头呢?用strace抓包,看了下nginx与fpm进程通讯的数据

####为了确保准确抓到处理该http请求的进程,我把nginx 、fpm都只开启了一个进程处理。
//strace -ff -tt -s 1000 -o xxx.log -p PHPFPM-PID
14:52:07.837334 write(3, "\1\6\0\1\0\343\5\0X-Powered-By: PHP/5.3.10-1ubuntu3.5\r\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\r\nCache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\nPragma: no-cache\r\nContent-type: text/html\r\n\r\nHello cfc4n1362034327\0\0\0\0\0\1\3\0\1\0\10\0\0\0\0\0\0\0\0\0\0", 256) = 256

//strace -ff -tt -s 1000 -o xxx.log -p Nginx-PID
15:05:13.265663 recvfrom(12, "\1\6\0\1\0\343\5\0X-Powered-By: PHP/5.3.10-1ubuntu3.5\r\nExpires: Thu, 19 Nov 1981 08:52:00 GMT\r\nCache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0\r\nPragma: no-cache\r\nContent-type: text/html\r\n\r\nHello cfc4n1362035113\0\0\0\0\0\1\3\0\1\0\10\0\0\0\0\0\0\0\0\0\0", 4023, 0, NULL, NULL) = 256

从抓取的数据包里可以看到,fpm确实返回了包含“Expires”、“Cache-Control”头的http 响应头信息。那么疑问来了:
  • nginx的fastcgi_cache没缓存这条http响应,是因为响应头里包含“Expires”、“Cache-Control”的原因吗?
  • 程序里并没有输出“Expires”、“Cache-Control” http header的代码,这是谁输出的呢?
  • 既然是fpm响应的时候,就已经有了,那么是php的core模块,还是其他拓展模块输出的?
  • “Expires:”时间为何是“Thu, 19 Nov 1981 08:52:00 GMT”?

疑问比较多,一个一个查起,先从Nginx的fastcgi_cache没缓存这条http响应查起。我根据测试环境nginx版本1.1.9(ubuntu 12.04默认的),到nginx官方下了对应版本的源码,搜索了fastcgi参数使用的地方,在http\ngx_http_upstream.c找到了。虽然不能很流程的读懂nginx的代码,但粗略的了解,根据了解的情况加以猜测,再动手测试实验,也得出了结论,确定了nginx的fastcgi_cache的规则。

//ngx_http_upstream.c
//line 3136  当fastcgi响应包含set-cookie时,不缓存
static ngx_int_t
ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h,
    ngx_uint_t offset)
{
#if (NGX_HTTP_CACHE)
    ngx_http_upstream_t  *u;

    u = r->upstream;

    if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) {
        u->cacheable = 0;
    }
#endif

    return NGX_OK;
}

//line 3242 当响应头包含Expires时,如果过期时间大于当前服务器时间,则nginx_cache会缓存该响应,否则,则不缓存
static ngx_int_t
ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h,
    ngx_uint_t offset)
{
    ngx_http_upstream_t  *u;

    u = r->upstream;
    u->headers_in.expires = h;

#if (NGX_HTTP_CACHE)
    {
    time_t  expires;

    if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_EXPIRES) {
        return NGX_OK;
    }

    if (r->cache == NULL) {
        return NGX_OK;
    }

    if (r->cache->valid_sec != 0) {
        return NGX_OK;
    }

    expires = ngx_http_parse_time(h->value.data, h->value.len);

    if (expires == NGX_ERROR || expires < ngx_time()) {         u->cacheable = 0;
        return NGX_OK;
    }

    r->cache->valid_sec = expires;
    }
#endif

    return NGX_OK;
}

//line 3199  当响应头包含Cache-Control时,#####如果####这里有如果啊。。。
//【注意】如果Cache-Control参数值为no-cache、no-store、private中任意一个时,则不缓存...不缓存...
//【注意】如果Cache-Control参数值为max-age时,会被缓存,且nginx设置的cache的过期时间,就是系统当前时间 + mag-age的值
    if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL
        || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL
        || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL)
    {
        u->cacheable = 0;
        return NGX_OK;
    }

    p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1);

    if (p == NULL) {
        return NGX_OK;
    }
    ...
    r->cache->valid_sec = ngx_time() + n;

也就是说,fastcgi响应http请求的结果中,响应头包括Expires、Cache-Control、Set-Cookie三个,都会可能不被cache,但不只有这些,别忘了nginx配置中fastcgi_ignore_headers参数设定的部分。以及ngxin的 X-ACCEL X-Accel-Redirect、X-Accel-Expires、X-Accel-Charset、X-Accel-Buffering等nginx自定义的响应头。由于这几个不常用,我也没深入研究。通过对nginx的ngx_http_upstream模块代码模糊理解,加猜测,以及写了脚本测试验证,可以得到结论是正确的。即Nginx fastcgi_cache在缓存后端fastcgi响应时,当响应里包含“set-cookie”时,不缓存;当响应头包含Expires时,如果过期时间大于当前服务器时间,则nginx_cache会缓存该响应,否则,则不缓存;当响应头包含Cache-Control时,如果Cache-Control参数值为no-cache、no-store、private中任意一个时,则不缓存,如果Cache-Control参数值为max-age时,会被缓存,且nginx设置的cache的过期时间,就是系统当前时间 + mag-age的值。


nginx fastcgi_cache 响应expired


nginx fastcgi_cache hit命中


FASTCGI_CACHE $upstream_cache_status 结果为miss,一次也没命中。

//逐个测试,测试时,注释其他的
header("Expires: ".gmdate("D, d M Y H:i:s", time()+10000).' GMT');
header("Expires: ".gmdate("D, d M Y H:i:s", time()-99999).' GMT');
header("X-Accel-Expires:30");
header("Cache-Control: no-cache");
header("Cache-Control: no-store");
header("Cache-Control: private");
header("Cache-Control: max-age=10");
setcookie('cfc4n',"testaaaa");
echo 'Hello cfc4n',time();

到了这里,疑问1解决了。那么疑问2、3呢?程序里并没有输出“Expires”、“Cache-Control” http header的代码,这是谁输出的呢?既然是fpm响应的时候,就已经有了,那么是php的core模块,还是其他拓展模块输出的?我精简了代码,只输出一个“hello world”,发现也确实被缓存了。显然,php脚本程序中并没输出http header 的“Expires”、“Cache-Control”,多次测试,最终定位到session_start函数,翻阅源码找到了这些代码:
//ext/session/session.c  line:1190 左右
// ...
CACHE_LIMITER_FUNC(private) /* {{{ */
{
	ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
	CACHE_LIMITER(private_no_expire)(TSRMLS_C);
}
/* }}} */
//再到这里3 或者上面几个 ##默认是nocache
CACHE_LIMITER_FUNC(nocache) /* {{{ */
{
	ADD_HEADER("Expires: Thu, 19 Nov 1981 08:52:00 GMT");

	/* For HTTP/1.1 conforming clients and the rest (MSIE 5) */
	ADD_HEADER("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");

	/* For HTTP/1.0 conforming clients */
	ADD_HEADER("Pragma: no-cache");
}
/* }}} */
//这里2
static php_session_cache_limiter_t php_session_cache_limiters[] = {
	CACHE_LIMITER_ENTRY(public)
	CACHE_LIMITER_ENTRY(private)
	CACHE_LIMITER_ENTRY(private_no_expire)
	CACHE_LIMITER_ENTRY(nocache)
	{0}
};

static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
{
	php_session_cache_limiter_t *lim;

	if (PS(cache_limiter)[0] == '\0') return 0;

	if (SG(headers_sent)) {
		const char *output_start_filename = php_output_get_start_filename(TSRMLS_C);
		int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);

		if (output_start_filename) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent (output started at %s:%d)", output_start_filename, output_start_lineno);
		} else {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot send session cache limiter - headers already sent");
		}
		return -2;
	}

	for (lim = php_session_cache_limiters; lim->name; lim++) {
		if (!strcasecmp(lim->name, PS(cache_limiter))) {
			lim->func(TSRMLS_C);   //这里1
			return 0;
		}
	}

	return -1;
}
// ...

到了这里,知道原因了,是程序调用session_start时,php的session拓展自己输出的。session.cache_limit参数来决定输出包含哪种Expires的header,默认是nocache,修改php.ini的session.cache_limit参数为“none”即可让session模块不再输出这些http 响应头。或在调用session_start之前,使用session_cache_limiter函数来指定下该参数值。那为什么要在使用session时,发Expires、Cache-Control的http response header呢?我猜测了下,需要session时,基本上是用户跟服务器有交互,那么,既然有交互,就意味着用户的每次交互结果也可能不一样,就不能cache这个请求的结果,给返回给这个用户。同时,每个用户的交互结果都是不一样的,nginx也就不能把包含特殊Cache-Control的个人响应cache给其他人提供了。

还有一个无聊的问题“Expires:时间为何是Thu, 19 Nov 1981 08:52:00 GMT”?我翻阅了session.c这段代码的添加时间,版本,作者信息,在php官方版本库中找到了这次提交的信息

Revision 17092 – (view) (download) (as text) (annotate) – [select for diffs]
Modified Sun Dec 12 14:16:55 1999 UTC (13 years, 2 months ago) by sas
File length: 28327 byte(s)
Diff to previous 16964
Add cache_limiter and cache_expire options. Rename extern_referer_check
to referer_check.

对比session.c两个版本的变更,果然是这块代码。作者是sas,也就是Sascha Schumann http://php.net/credits.php里可以看到他的大名。关于这个expires过期时间的问题,有人在stackoverflow也提问过,Why is “Expires” 1981?,别人说那天是他生日。这是真的么?如果那天是他生日的话,而他增加session.cache_limiter时是1999年,他才17岁,17岁呀。我17岁时在干嘛?还不知道电脑长啥样,正在玩『超级玛丽』呢。

好奇的不是我一个人,还有个帖子是epoch date — Expires: Thu, 19 Nov 1981 08:52:00也问了。另外两个地址虽然没问,也有人提到那天是他生日了。http://boinc.berkeley.edu/dev/forum_thread.php?id=2514https://github.com/codeguy/Slim/issues/157,这些帖子都提到说原帖是http://www.phpbuilder.com/lists/php3-list/199911/3159.php ,我无法访问,被跳转到首页了。用http://web.archive.org找到了历史快照,发现上下文关系不大,也不能证明是他生日。 我更是好奇的发了两封邮件到他的不同邮箱里问他,不过,目前他还没回复。或许他没收到、没看到,或许懒得回了。N年后,“Expires:时间为何是Thu, 19 Nov 1981 08:52:00 GMT”这个日期,会不会又成了一段奇闻佳话了呢?

<think>我们正在讨论FastCGI的配置选项及其作用。根据用户的要求,我需要解释FastCGI配置中的各个选项及其含义。根据提供的引用,我们可以整理出以下配置选项: 1. **fastcgi_connect_timeout**:指定连接到后端FastCGI服务器的超时时间。 2. **fastcgi_send_timeout**:指定向FastCGI服务器传送请求的超时时间(已经完成两次握手后)。 3. **fastcgi_read_timeout**:指定接收FastCGI服务器应答的超时时间(已经完成两次握手后)。 4. **fastcgi_buffer_size**:用于指定读取FastCGI应答第一部分(应答头)的缓冲区大小。 5. **fastcgi_buffers**:指定本地用于缓冲FastCGI应答的缓冲区数量和大小。 6. **fastcgi_busy_buffers_size**:当缓冲区处于繁忙状态时(例如,正在向客户端发送响应),可以使用的额外缓冲区大小。默认是fastcgi_buffers的两倍。 7. **fastcgi_temp_file_write_size**:写入缓存文件时使用的数据块大小。默认是fastcgi_buffers的两倍。 8. **fastcgi_cache**:开启FastCGI缓存并指定一个名称。 9. **fastcgi_cache_valid**:指定不同应答代码的缓存时间。 10. **fastcgi_cache_key**:定义缓存的键(key),通常由请求方法、主机名、URI、参数等组合而成。 11. **fastcgi_cache_use_stale**:当出现某些错误(如error、timeout、http_500等)时,是否使用过期的缓存。 12. **fastcgi_hide_header**:隐藏FastCGI服务器返回的某些响应头(如X-Powered-By)。 此外,在引用[4]中,还提到了在server模块中配置FastCGI缓存的相关指令,例如: - **fastcgi_cache**:指定缓存区名称(与http模块中定义的keys_zone名称对应)。 - **fastcgi_cache_valid**:针对不同状态码设置缓存时间。 - **fastcgi_cache_key**:设置缓存的键。 - **fastcgi_cache_use_stale**:定义在何种情况下使用过期的缓存。 - **add_header**:添加自定义响应头,例如显示缓存命中状态。 现在,我将根据这些信息,详细解释每个配置选项的作用。 ### FastCGI配置选项详解 1. **fastcgi_connect_timeout** 该指令设置与FastCGI服务器建立连接的超时时间。如果在这个时间内没有建立连接,则返回超时错误。单位可以是秒(s)或毫秒(ms),例如:`fastcgi_connect_timeout 30s;`。 2. **fastcgi_send_timeout** 该指令设置向FastCGI服务器发送请求的超时时间。注意,这个时间是从连接建立后开始计算的。如果在指定时间内没有发送完请求数据,则超时。例如:`fastcgi_send_timeout 30s;`。 3. **fastcgi_read_timeout** 该指令设置从FastCGI服务器读取响应的超时时间。同样,这个时间是从连接建立后开始计算的。如果在指定时间内没有接收到响应,则超时。例如:`fastcgi_read_timeout 40s;`。 4. **fastcgi_buffer_size** 该指令设置用于读取FastCGI响应第一部分的缓冲区大小。响应第一部分通常包括响应头。这个值一般设置为一个缓冲区的大小,通常与`fastcgi_buffers`指令中单个缓冲区的大小相同。例如:`fastcgi_buffer_size 64k;`。 5. **fastcgi_buffers** 该指令设置用于缓冲FastCGI响应的缓冲区的数量和大小。格式为:`fastcgi_buffers number size;`。例如:`fastcgi_buffers 4 64k;`表示分配4个64KB的缓冲区。如果响应大于缓冲区总大小,则超出部分会被写入临时文件(由`fastcgi_temp_path`指定),但这会影响性能,因此应尽量设置合适的缓冲区大小以避免使用临时文件。 6. **fastcgi_busy_buffers_size** 该指令限制在响应未完全读取时,可以发送给客户端的缓冲区大小。通常设置为`fastcgi_buffers`中单个缓冲区大小的两倍。例如,如果`fastcgi_buffers`设置为`4 64k`,则默认的`fastcgi_busy_buffers_size`为128k。 7. **fastcgi_temp_file_write_size** 该指令设置写入临时文件时每次写入的数据块大小。默认值通常为`fastcgi_buffers`中单个缓冲区大小的两倍。例如:`fastcgi_temp_file_write_size 128k;`。 8. **fastcgi_cache** 该指令启用FastCGI缓存,并指定一个缓存区域名称。缓存区域必须在`http`块中通过`fastcgi_cache_path`指令预先定义。例如:`fastcgi_cache my_cache;`。 9. **fastcgi_cache_valid** 该指令根据响应状态码设置缓存时间。例如:`fastcgi_cache_valid 200 302 10m;`表示状态码为200和302的响应缓存10分钟。可以设置多个状态码和对应的缓存时间。 10. **fastcgi_cache_key** 该指令定义生成缓存键的字符串。通常包括请求方法、主机名、URI和参数等。例如:`fastcgi_cache_key "$request_method$host$uri$is_args$args";`。 11. **fastcgi_cache_use_stale** 该指令指定在哪些情况下可以使用过期的缓存。例如,当与FastCGI服务器通信出现错误、超时或服务器返回500错误时,可以使用过期的缓存:`fastcgi_cache_use_stale error timeout http_500;`。 12. **fastcgi_hide_header** 该指令用于隐藏FastCGI服务器返回的某些响应头。例如,隐藏`X-Powered-By`头:`fastcgi_hide_header X-Powered-By;`。 ### 缓存配置示例 在`http`块中定义缓存路径和参数: ```nginx http { fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=100m; ... } ``` - `levels`:设置缓存目录的层级结构。 - `keys_zone`:定义共享内存区域(名称和大小,10MB)。 - `inactive`:缓存如果在指定时间内未被访问则被删除(60分钟)。 - `max_size`:设置缓存的最大大小(100MB)。 在`server`或`location`块中配置缓存: ```nginx location ~ \.php$ { ... fastcgi_cache my_cache; fastcgi_cache_valid 200 301 302 30m; fastcgi_cache_valid 404 1m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout updating http_500 http_503; add_header X-Cache-Status $upstream_cache_status; } ``` - `add_header`:添加一个响应头`X-Cache-Status`,显示缓存命中状态(如HIT、MISS、BYPASS等)。 ### 注意事项 - 缓存可以显著降低服务器负载,但需要根据应用场景合理配置,避免缓存敏感数据或动态内容。 - 缓冲区大小设置应基于实际响应大小调整,过小会导致频繁使用临时文件,过大则浪费内存。 通过以上配置选项的详细解释,我们可以更好地优化FastCGI服务的性能和稳定性[^2][^4]。 §§相关问题§§ 1. 如何优化FastCGI缓存以提高性能? 2. FastCGI配置中缓冲区大小设置不当会导致什么问题? 3. 如何监控和调试FastCGI缓存的命中率?</think>### FastCGI 配置选项详解 以下是 FastCGI 的核心配置选项及其作用解释,基于 Nginx 的典型配置: #### 1. **连接与超时控制** - **`fastcgi_connect_timeout`** 指定连接到后端 FastCGI 进程的超时时间(如 PHP-FPM)。若超时,返回 504 错误。 *示例*:`fastcgi_connect_timeout 30s;` *作用*:防止因后端无响应导致前端阻塞。 - **`fastcgi_send_timeout`** 定义向 FastCGI 发送请求数据的超时时间(从连接建立后开始计算)。 *示例*:`fastcgi_send_timeout 30s;` *作用*:避免大文件上传时连接长时间挂起。 - **`fastcgi_read_timeout`** 设置接收 FastCGI 响应的超时时间(从连接建立后开始计算)。 *示例*:`fastcgi_read_timeout 40s;` *作用*:防止后端脚本执行过久阻塞前端[^2]。 #### 2. **缓冲区管理** - **`fastcgi_buffer_size`** 定义读取 FastCGI 响应头(第一部分)的缓冲区大小。 *示例*:`fastcgi_buffer_size 64k;` *作用*:存储响应头信息(如状态码、Cookie),通常与 `fastcgi_buffers` 的单缓冲区大小一致。 - **`fastcgi_buffers`** 设置用于缓存 FastCGI 响应正文的缓冲区数量和大小。 *示例*:`fastcgi_buffers 4 64k;` *作用*: - 若响应 ≤ 256KB(4×64KB),全部缓存在内存; - 若响应 > 256KB,超出部分写入磁盘临时文件(影响性能)[^2][^4]。 - **`fastcgi_busy_buffers_size`** 限制在响应未完全接收时,可先发送给客户端的缓冲区大小。 *默认*:`fastcgi_buffers` 总大小的两倍(如 4×64KB → 512KB)。 *作用*:平衡内存使用与响应速度。 - **`fastcgi_temp_file_write_size`** 定义写入磁盘临时文件时单次写入的数据块大小。 *默认*:`fastcgi_buffers` 单缓冲区大小的两倍(如 128KB)[^2]。 #### 3. **缓存优化** - **`fastcgi_cache`** 启用 FastCGI 响应缓存并命名缓存区域。 *示例*:`fastcgi_cache my_cache;` *作用*:减少重复请求对后端的负载,提升响应速度[^4]。 - **`fastcgi_cache_path`** 配置缓存存储路径及参数(需在 `http` 块中定义)。 *示例*: ```nginx fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m inactive=60m max_size=1g; ``` - `levels`:缓存目录层级结构 - `keys_zone`:共享内存名称及大小(存储缓存键) - `inactive`:缓存未访问的失效时间 - `max_size`:磁盘缓存最大容量[^4]。 - **`fastcgi_cache_valid`** 按响应状态码设置缓存时间。 *示例*:`fastcgi_cache_valid 200 301 1h;` *作用*:精细化控制不同内容的缓存策略[^4]。 - **`fastcgi_cache_key`** 定义生成缓存键的规则。 *示例*:`fastcgi_cache_key "$request_method$host$uri$args";` *作用*:区分不同请求(如 GET/POST、不同参数)[^4]。 - **`fastcgi_cache_use_stale`** 指定在何种错误下使用过期缓存。 *示例*:`fastcgi_cache_use_stale error timeout http_500;` *作用*:确保后端故障时仍能提供降级响应[^4]。 #### 4. **安全与调试** - **`fastcgi_hide_header`** 隐藏后端返回的敏感响应头。 *示例*:`fastcgi_hide_header X-Powered-By;` *作用*:减少服务器信息泄露风险。 - **`add_header`** 添加自定义响应头(用于调试)。 *示例*:`add_header X-Cache-Status $upstream_cache_status;` *作用*:显示缓存命中状态(`HIT`/`MISS`/`BYPASS`)[^4]。 --- ### 关键配置示例 ```nginx location ~ \.php$ { fastcgi_pass unix:/tmp/php-fpm.sock; fastcgi_cache my_cache; # 启用缓存 fastcgi_cache_valid 200 1h; # 200响应缓存1小时 fastcgi_cache_key "$scheme$request_method$host$request_uri"; # 缓存键规则 fastcgi_buffer_size 128k; # 响应头缓冲区 fastcgi_buffers 4 256k; # 响应内容缓冲区 fastcgi_connect_timeout 15s; # 连接超时 add_header X-Cache $upstream_cache_status; # 调试头 } ``` ### 注意事项 1. **缓冲区大小**:需根据平均响应体积调整。过小导致频繁磁盘写入,过大浪费内存[^2]。 2. **缓存失效**:动态内容需谨慎设置 `fastcgi_cache_valid`,避免返回旧数据。 3. **超时时间**:根据后端处理能力设置,过长影响并发,过短导致504错误[^2][^4]。 通过合理配置这些选项,可显著提升 FastCGI 应用的性能和稳定性[^2][^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值