nginx中http模块中的sendfile指令及其原理。

1、sendfile()介绍

nginx的http模块中有一个sendfile指令,默认是开启状态,官网的文档对其解释是:

Enables or disables the use of sendfile().

Starting from nginx 0.8.12 and FreeBSD 5.2.1, aio can be used to pre-load data for sendfile():

location /video/ {sendfile       on;tcp_nopush     on;aio            on;
}

In this configuration, sendfile() is called with the SF_NODISKIO flag which causes it not to block on disk I/O, but, instead, report back that the data are not in memory. nginx then initiates an asynchronous data load by reading one byte. On the first read, the FreeBSD kernel loads the first 128K bytes of a file into memory, although next reads will only load data in 16K chunks. This can be changed using the read_ahead directive.

简单来说就是启用sendfile()系统调用来替换read()和write()调用,减少系统上下文切换从而提高性能,当 nginx 是静态文件服务器时,能极大提高nginx的性能表现,而当 nginx 是反向代理服务器时,则没什么用了。下面我们来分析一下这个sendfile的工作原理:

2、原理分析

首先我们需要知道sendfile()和read()、write()之间最大的区别就是前者是属于系统调用,而后者是属于函数调用,我们来看下面这幅图

我们不难看出,nginx是属于Applicaiton的,而read()、write()属于函数调用,也就是在Lib Func这一层,sendfile()系统调用,位于System Call这一层,而想要对硬盘进行操作,是kernel才有的权限,上面的那些层都需要往下调用。

作为对比我们先来看一下正常情况下如果nginx调用read()和write()函数的操作过程:

我们都知道数据是存储在硬盘上面的,当数据被调用的时候会被加载进内存再被层层递进最后被CPU使用,这里个这个过程我们进行简化。

  • 步骤一:首先nginx调用read函数,这时data从harddisk从被加载进Kernel Buffer(Hard Disk)中,此时是从一开始的用户态(user mode)陷入内核态(kernel mode)才能完成操作
  • 步骤二:接着由于data需要被write()函数进行操作,所以data从Kernel Buffer(Hard Disk)传输到User Buffer中,此时从内核态(kernel mode)切换回用户态(user mode)
  • 步骤三:再接着data被write()函数从user buffer写入到Kernel Buffer(Socket Engine),此时从用户态(user mode)陷入内核态(kernel mode)
  • 步骤四:data从Kernel Buffer(Socket Engine)传输到Socket Engine,此时从内核态(kernel mode)切换回用户态(user mode)

这里需要说明两点,一是用户态和内核态之间的切换是需要执行上下文切换操作的,这是十分耗费系统资源和时间的操作,二是因为read()、write()属于函数调用,它们是没有权限在kernel中操作,无法将data直接从Kernel Buffer(Hard Disk)传输到Kernel Buffer(Socket Engine)。

那么使用sendfile()呢?,由于是系统调用,所以在步骤二和步骤三的时候就可以不需要再将数据传输到User Buffer,直接在kernel中进行操作,省去了两次状态切换,也就是省去了两次的上下文切换,从而大幅度提升了性能。

我们来看一下下面的这幅图(灵魂画手上线→_→)

最后我们再来解释一下,为什么当 nginx 是反向代理服务器时,sendfile()就没什么用了呢。

顾名思义,sendfile()的作用是发送文件,也就是接收数据的一段是文件句柄,发送数据的那一端是socket。而在做反向代理服务器的时候,两端都是socket,此时无法使用sendfile(),也就不存在性能提升这一说了。

Nginx篇06-Sendfile指令及其原理相关推荐

  1. HwBinder驱动篇-Android10.0 HwBinder通信原理(十)

    摘要:本节主要来讲解Android10.0 HwBinder驱动的流程 阅读本文大约需要花费24分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平台设 ...

  2. 深入浅出学习透析Nginx服务器的架构分析及原理分析「底层技术原理+运作架构机制」

    Nginx再次回顾 也许你已经忘记了Nginx是做什么的?我来再次给你夯实一下概念. 多协议反向代理 Nginx是个高性能的Web和反向代理服务器及HTTP服务器,它能反向代理HTTP,HTTPS和邮 ...

  3. HwServiceManager篇-Android10.0 HwBinder通信原理(五)

    摘要:本节主要来讲解Android10.0 HwServiceManager的通信原理 阅读本文大约需要花费34分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,And ...

  4. HwBinder入门篇-Android10.0 HwBinder通信原理(一)

    摘要:本节主要来讲解Android10.0 HwBinder的通信原理概要 阅读本文大约需要花费18分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Android的平 ...

  5. 一篇不一样的docker原理解析

    0 引言 在学习docker的过程中,我发现目前docker学习最大的障碍,不是网上的资源太少,而是网上的资源太多,资源太多带来的噪声让学习效率降低不少.而在讲解docker原理上,所有的讲解都是关于 ...

  6. 【Nginx那些事】nginx 安装及常用指令

    [Nginx那些事]系列 [Nginx那些事]nginx 安装及常用指令 [Nginx那些事]Nginx 配置文件说明 [Nginx那些事]nginx原理解析 [Nginx那些事]nginx配置实例( ...

  7. nacis服务注册原理_HwServiceManager篇Android10.0 HwBinder通信原理(五)

    阅读本文大约需要花费34分钟. 原创不易,如果您觉得有点用,希望可以随手转发或者点击右下角的 "在看".""分享"",拜谢! <And ...

  8. Nginx篇--解读nginx配置

    一.前述 之前讲解了Nginx的源码安装与加载到系统服务中去,http://www.cnblogs.com/LHWorldBlog/p/8298226.html 今天详细讲解Nginx中的具体配置. ...

  9. 【直通华为HCNA/HCNP系列R篇7】可靠性功能原理及配置与管理-王达-专题视频课程...

    [直通华为HCNA/HCNP系列R篇7]可靠性功能原理及配置与管理-8892人已学习 课程介绍         本课程以华为指定的ICT认证教材<华为路由器学习指南>为主线,全面.系统.深 ...

最新文章

  1. LVS集群---做前端调度器搭建使用
  2. 洛谷 - P2045 - 方格取数加强版 - 费用流
  3. Oracle 数据库利用sql语句判断某个表是否是临时表实例演示,达梦数据库查询出所有临时表
  4. 抽象类实例化 使用原功能 c++_java 学习笔记 day08 final/static关键字、抽象类和接口...
  5. UCSD本科数学计算机专业前景如何,2020年UCSD计算机工程排名真该小心来考查
  6. 如何删除“无法读源文件或磁盘”的空头文件
  7. Google 搜索命令
  8. Java Spring boot 企业微信点餐系统
  9. 老生常谈!数据库如何存储时间?你真的知道吗?
  10. 关于Flash闪存的扇区、块、页
  11. Joomla 一个实例建站过程
  12. calendar java起始于结束时间,java获取一天的开始时间和一天的结束时间
  13. uniapp App端 实现pdf文件预览
  14. Fast Abstractive Summarization with Reinforce-Selected Sentence Rewriting
  15. 从十亿光年到0.1飞米:从宇宙到细胞,从宏观到微观
  16. 台式计算机系统重新安装软件,教你台式机如何重装系统
  17. python模块名功能明和别名_Python周末练习
  18. 最佳编程笔记本_2020年如何选择最佳笔记本电脑进行编程?
  19. css改火狐滚动条样式_css布局系列1——盒模型布局
  20. 科普 | 什么是贴片电阻?

热门文章

  1. Activiti7工作流流程详解
  2. Python_sobel边缘检测
  3. yum 安装daemonize 错误:依赖检测失败: daemonize 被 jenkins-2.303.1-1.1.noarch 需要
  4. PAT 乙级 1015 德才论 (25 分)
  5. 浙大哈佛剑桥学者联手破解数学界几十年的谜题,成果登上数学顶刊
  6. java丰桥顺丰路由接口调用
  7. 今天面试了几家高级测试工程师,面试题整理(含答案)
  8. 详细记录拉链表的实现过程
  9. Java实现键盘输入
  10. java字符串换行符替换成段落标记_导出EXCEL换行符br为什么没有起到作用/poi导出excel内存溢出...