nginx的sendfile指令的作用
linux为了解决对读文件产生的从应用空间到内核空间复制数据产生的效率影响引进了零拷贝。什么是零拷贝?这里就不多说了,请参考http://blog.csdn.net/crazyguang/article/details/2423708,我们主要是讲述nginx怎么是用sendfile的。
nginx通过使用sendfile指令来控制是不是用linux提供的零拷贝功能。具体配置如下:
sendfile on/off
注:这个指令只能用在HTTP框架下。
上面指令的作用就是给struct ngx_http_core_loc_conf_s 的sendfile赋值,逻辑也比较简单。
下面以nginx做源服务来讲述这个功能。nginx做源服务都会通过ngx_http_static_handler讲url转换成文件的目录(ngx_http_map_uri_to_path)。
static ngx_int_t
ngx_http_static_handler(ngx_http_request_t *r)
{
......
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
......
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
!= NGX_OK)
......
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
b->file_pos = 0;
b->file_last = of.size; b->in_file = b->file_last ? 1: 0;
b->last_buf = (r == r->main) ? 1: 0;
b->last_in_chain = 1; b->file->fd = of.fd;
b->file->name = path;
b->file->log = log;
b->file->directio = of.is_directio; out.buf = b;
out.next = NULL; return ngx_http_output_filter(r, &out);
......
}
通过 ngx_http_map_uri_to_path找到路径后就会调用ngx_open_cached_file打开文件,并获取到文件的相关信息。下面创建一个buf,注意这个buf的初始化在后面会用到。ngx_http_output_filter进入到filter链中。最后会调用到ngx_http_copy_filter。
static ngx_int_t
ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
......
ctx->sendfile = c->sendfile;
ctx->need_in_memory = r->main_filter_need_in_memory
|| r->filter_need_in_memory;
ctx->need_in_temp = r->filter_need_temporary;
for ( ;; ) {
rc = ngx_output_chain(ctx, in);
......
}
注意ctx->sendfile的值也是非要重要的。
ngx_int_t
ngx_output_chain(ngx_output_chain_ctx_t *ctx, ngx_chain_t *in)
{
......
if (in->next == NULL
#if (NGX_SENDFILE_LIMIT)
&& !(in->buf->in_file && in->buf->file_last > NGX_SENDFILE_LIMIT)
#endif
&& ngx_output_chain_as_is(ctx, in->buf))
{
return ctx->output_filter(ctx->filter_ctx, in);
}
......
} static ngx_inline ngx_int_t
ngx_output_chain_as_is(ngx_output_chain_ctx_t *ctx, ngx_buf_t *buf)
{
......
if (!sendfile) { if (!ngx_buf_in_memory(buf)) {
return 0;
} buf->in_file = 0;
}
......
}
这里面sendfile和buf中in_file就是判断数据是不是在文件中。如果上面的判断为真就会直接调用发送函数(ngx_linux_sendfile_chain),要不然就会调用ngx_output_chain_copy_buf把数据从文件中读取出来。
void
ngx_http_update_location_config(ngx_http_request_t *r)
{
......
if ((ngx_io.flags & NGX_IO_SENDFILE) && clcf->sendfile) {
r->connection->sendfile = 1; } else {
r->connection->sendfile = 0;
}
......
}
到这里就能理解了sendfile怎么影响nginx的sendfile处理了。下面来看最后一个函数, ngx_linux_sendfile_chain
ngx_chain_t *
ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
{
......
if (header.nelts == 0 && cl && cl->buf->in_file && send < limit) {
file = cl->buf;
......
if (file) {
......
rc = sendfile(c->fd, file->file->fd, &offset, file_size);
......
} else {
rc = writev(c->fd, header.elts, header.nelts);
......
}
可以看出如果file有值就会调用sendfile,但是在上面的if语句中cl->buf->in_file在前面判断是否读取文件内容的时候会进行修改,也就是如果要读取文件内容就会复位0,这样读取了文件内容后就直接调用writev发送数据,否则就调用sendfile发送文件到客户端。
nginx的sendfile指令的作用的更多相关文章
- linux中test与[ ]指令的作用
linux中test与[ ]指令的作用: 在Linux中,test和[ ]功能是一样的,类似于c语言中的( ).不过Linux的test和[ ]是指令.在和if或者while联用时要用空格分开.
- nginx:location指令中的正则表达式
nginx:location指令中的正则表达式 uri匹配步骤 官网说明https://docs.nginx.com/nginx/admin-guide/web-server/web-server/ ...
- (转)nginx日志配置指令详解
这篇文章主要介绍了nginx日志配置指令详解,nginx有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志,需要的朋友可以参考下日志对于统计排错来说非常有利的.本文总结了nginx日 ...
- nginx 配置优化指令
worker_processes worker_processes指令是用来设计Nginx进程数,官方默认设为1,赋值太多了,将会对系统IO影响效率,降低Nginx服务器性能.但是为了让多核CPU能够 ...
- nginx日志配置指令详解
这篇文章主要介绍了nginx日志配置指令详解,nginx有一个非常灵活的日志记录模式,每个级别的配置可以有各自独立的访问日志,需要的朋友可以参考下日志对于统计排错来说非常有利的.本文总结了nginx日 ...
- [Linux] nginx的try_files指令实现隐藏index.php的重写
1.nginx的try_files指令 ,核心功能是替代rewrite,并且比rewrite更强大的是可以按顺序查找文件是否存在,如果文件都找不到才会执行最后的重定向解决的问题是,如果一个网站的部署是 ...
- Python的global指令的作用
Python的global指令的作用 学过其他常用编程语言的同学一定清楚,Python是一个语法非常宽容的语言.它是个变量的定义可以省略.直接赋值.根据赋值结果自动确定变量类型的弱类型语言. 但是这样 ...
- vue第十三单元(指令的作用,指令的钩子函数)
第十三单元(指令的作用,指令的钩子函数) #课程目标 1.了解自定义指令的应用场景 2.掌握自定义全局和局部指令 3.掌握指令的钩子函数 #知识点 #一.认识自定义指令 除了核心功能默认内置的指令 ( ...
- Nginx的mirror指令能干啥?
mirror 流量复制 Nginx的 mirror 指令来自于 ngx_http_mirror_module 模块 Nginx Version > 1.13.4 mirror 指令提供的核心功能 ...
随机推荐
- 详解python2 和 python3的区别
看到这个题目大家可能猜到了我接下来要讲些什么,呵呵,对了,那就是列出这两个不同版本间的却别!搜索一下大家就会知道,python有两个主要的版本,python2 和 python3 ,但是python又 ...
- linux chmod权限
Linux chmod 命令 chmod用于改变文件或目录的访问权限.用户用它控制文件或目录的访问权限.该命令有两种用法.一种是包含 字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1 ...
- sequence1(暴力)
sequence1 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- Wakelock API详解
官方资料 http://developer.android.com/intl/zh-CN/reference/android/os/PowerManager.WakeLock.html http:/ ...
- 常见的transformation 和 Action
常见transformation map 将RDD中的每个元素传入自定义函数,获取一个新的元素,然后用新的元素组成新的RDD filter 对RDD中每个元素进行判断,如果返回true则保留,返回fa ...
- SD-关于定价日期的设置
最近看了一篇关于定价日期的文章,我觉得写得很不错,特将自己的理解摘抄如下: 关于SD的定价日期在SAP系统中有三个配置与其相关,以及手工输入定价日期,具体如下: 1.订单类型的“定价日期建议“ 这个字 ...
- java--多线程之Runnable
引读: 上一篇博文中讲了Thread的继承,存在一个问题就是,如果类本身已经继承了某个父类,又要继承Thread,导致多重继承. [但是我们知道接口是实现多重继承的重要方式].java提供了Runna ...
- 基于visual Studio2013解决算法导论之002归并排序
题目 归并排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- 基于visual Studio2013解决C语言竞赛题之0710排序函数
题目
- linux head命令
head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾. 1.命令格式: hea ...