Nginx教程:nginx对静态文件cache的处理(2)

  这里ngx_cached_open_file_s有3个域需要注意,分别是uniq,count以及close。其中uniq也就是文件属性中的st_ino(同一个设备中的每个文件,这个值都是不同的),这个值主要用于判断文件是否被修改(不过这个修改是覆盖这类的,如果你用open打开,然后写入的话,这个值还是一样的).count是文件的引用计数,表示现在文件被几个请求使用中。close表示文件是否需要被关闭(比如。

  ok,接下来就是nginx的超时处理测略了。首先来看ngx_close_cached_file,这个函数主要是尝试关闭当前的文件,对这代码我们来看流程。

//判断是否需要关闭
if (!file->close) {
//如果不需要,则更新存取时间
file->accessed = ngx_time();
//然后将文件插入到队列头(先remove然后insert)
ngx_queue_remove(&file->queue);
ngx_queue_insert_head(&cache->expire_queue, &file->queue);
//看文件的使用次数是否大于设置的最小次数,或者文件的引用技术是否大于0,如果有一个满足,则直接返回,因为此时不需要close文件.
if (file->uses >= min_uses || file->count) {
return;
}
}
ngx_open_file_del_event(file);
if (file->count) {
return;
}
//到达这里说明文件需要被关闭。
if (file->fd != NGX_INVALID_FILE) {
//关闭文件
if (ngx_close_file(file->fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_close_file_n " \"%s\" failed", file->name);
}

file->fd = NGX_INVALID_FILE;
}

if (!file->close) {
return;

  接下来是ngx_expire_old_cached_files,这个函数比较关键,主要是用来执行超时,或者强制超时cache中的元素(根据参数不同).主要的判断就是now – file->accessed <= cache->inactive,这段,这段主要是看这个文件多久没有被使用,是否超过了我们设置的inactive时间.

while (n < 3) {
//如果队列为空,则直接返回
if (ngx_queue_empty(&cache->expire_queue)) {
return;
}
//取出最后一个文件,也就是可能需要被超时的文件(因为尾部是最长时间没有操作的文件)
q = ngx_queue_last(&cache->expire_queue);

file = ngx_queue_data(q, ngx_cached_open_file_t, queue);
//n是控制是强制超时,还是按inactive超时,后一个判断是判断是否超时
if (n++ != 0 && now - file->accessed <= cache->inactive) {
return;
}
//如果有超时的,或者需要强制超时,则开始从队列和红黑树中移除
ngx_queue_remove(q);

ngx_rbtree_delete(&cache->rbtree, &file->node);

cache->current--;

ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
"expire cached open file: %s", file->name);

if (!file->err && !file->is_dir) {
//关闭文件
file->close = 1;
ngx_close_cached_file(cache, file, 0, log);

} else {
ngx_free(file->name);
ngx_free(file);
}
}

  最后来看,nginx里面如何判断文件被改变的。当需要打开一个文件,然后在cache中发现了文件,此时就需要判断文件是否被改变,这里nginx只能判断删除,然后覆盖的这类,而你如果只是简单的附加,则nginx无法知晓,来看代码,在ngx_open_and_stat_file里面的。判断很简单,就是看uniq是否相等,如果不等则说明文件被改变,此时需要重新打开文件,然后重新加入cache,否则直接返回。

if (of->fd != NGX_INVALID_FILE) {

if (ngx_file_info(name, &fi) == NGX_FILE_ERROR) {
of->failed = ngx_file_info_n;
goto failed;
}
//判断文件是否被改变
if (of->uniq == ngx_file_uniq(&fi)) {
goto done;
}

}
//否则重新打开
if (!of->log) {

/*
* Use non-blocking open() not to hang on FIFO files, etc.
* This flag has no effect on a regular files.
*/

fd = ngx_open_file(name, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
NGX_FILE_OPEN, 0);

} else {
fd = ngx_open_file(name, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN,
NGX_FILE_DEFAULT_ACCESS);
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/10934.html