在NGINX中,缓存静态文件,通常只是缓存了打开文件的描述符fd,在客户端访问静态资源的时候,NGINX通过sendfile机制,由DMA将数据读到输出流,响应到客户端,因此ngx_open_cached_file()中,并没有缓存文件内容。 在解读ngx_open_cached_file前,先来写个debug的demo:
void testOpenFileCache(){
ngx_time_init();
ngx_open_file_info_t of;
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
of.read_ahead = 128;
of.valid = 30;
of.errors = 0;
ngx_pool_t * pool = ngx_create_pool(POOL_SIZE,NULL);
ngx_open_file_cache_t *open_file_cache = ngx_open_file_cache_init(pool, 32, 60);
ngx_str_t name = ngx_string("/root/a.txt");
ngx_open_cached_file(open_file_cache,&name,&of,pool);
ngx_open_cached_file(open_file_cache,&name,&of,pool);
}
void main(){
testOpenFileCache();
}
先来看看打开open_file_cache 的配置
http{
open_file_cache max=1000 inactive=20s;
#表示最大打开文件缓存1000个,inative表示失效时间,到达失效时间未再次访问的将从缓存移除并关闭,默认关闭该配置
open_file_cache_valid 30s;
#指多长时间检查一次缓存的有效信息
open_file_cache_min_uses 1;
#指在失效时间范围内,最少访问多少次,文件描述符才是一直打开状态
}
一、不使用文件缓存的情形: ngx_pool_cleanup_add() ngx_open_and_stat_file()
direct io 使用DMA直接将硬盘上的数据读到用户空间buffer, 或者将用户空间buffer中的数据通过DMA直接写到硬盘上。避免多次系统调用及CPU拷贝(用户态内核态之间的拷贝)动作; 使用directIO时,用户态buffer需与系统page大小对齐,即,当系统page大小为4096,那么用户态buff需是4096的正整数倍。
location /video/ {
sendfile on;
aio on;
directio 1024m;
}
使用AIO时,应该同时使directIO生效,AIO从内核版本2.6.22后开始支持; 当文件大小大于 directio 值后,使用「异步 I/O + 直接 I/O」这两者不需使用pagecache,文件大小小于directio 或者关闭directIO时,使用「零拷贝技术:sendfile或mmap」 官网AIO配置 或 配置Nginx I/O 或 零拷贝
二、使用文件缓存情形 使用文件缓存时,需要先初始化缓存:当配置了open_file_cache ,那么在解析配置时,会执行ngx_open_file_cache_init() 这里使用的就是cleanup handler就是ngx_open_file_cache_cleanup这个是清理cache的,而ngx_pool_cleanup_file是清理单个缓存文件的 此时cache就不为空了,那么ngx_open_cached_file()中就跳过cache为空的部分:
现在来看看对于create代码块中对超时file缓存的处理:ngx_expire_old_cached_files()
其中ngx_close_cached_file方法接下来一起解读。 最后,来看看两个cleanup方法: ngx_open_file_cleanup(): 这个是在pool销毁时触发执行: ngx_open_file_cache_cleanup,也是在销毁对应的pool时,执行
|