今天在看nginx thread pool的时候,频繁的看到sendfile,其实以前也经常看到sendfile,只是我平时选择性的忽视而已。。。 先说下sendfile,明天在好好聊下nginx 线程池的一些突发点, 通过伪官方的博客介绍了如何利用nginx 线程池aio,实现9倍的性能…. 个人看了下,他核心的概念就是把你认为堵塞的模块或者说是逻辑扔到线程池里面,然后去接受新的任务,当有结果的时候,在从线程池里面取结果,然后返回。。。 但是如果用在nginx最强大的静态文件处理上,我个人觉得提升不大,毕竟你就算承接了更多的客户端的请求,但是你最后返回数据的逻辑,还是在抢占式的堵塞…  毕竟磁盘io的能力是有限的….    这只是个人的理解,如有不对的地方,请大家喷下…..

先不扯nginx线程池,回到sendfile…..

现在流行的web服务器里面都提供 sendfile 选项用来提高服务器性能

location /xiaorui.cc/ {
    sendfile       on;
    tcp_nopush     on;
    aio            on;
}

那么sendfile是什么东西,他是怎么影响性能的… …  sendfile实际上是 Linux2.0+以后的推出的一个系统调用,web服务器可以通过调整自身的配置来决定是否利用 sendfile这个系统调用。先来看一下不用 sendfile的传统网络传输过程:

read(file,tmp_buf, len);
write(socket,tmp_buf, len);

硬盘 >> kernel buffer >> user buffer>> kernel socket buffer >>协议栈

一个基于socket的服务,首先读硬盘数据,然后写数据到socket 来完成网络传输的。上面2行用代码解释了这一点,不过上面2行简单的代码掩盖了底层的很多操作。来看看底层是怎么执行上面2行代码的:

1、系统调用 read()产生一个上下文切换:从 user mode 切换到 kernel mode,然后 DMA 执行拷贝,把文件数据从硬盘读到一个 kernel buffer 里。
2、数据从 kernel buffer拷贝到 user buffer,然后系统调用 read() 返回,这时又产生一个上下文切换:从kernel mode 切换到 user mode。
3、 系统调用write()产生一个上下文切换:从 user mode切换到 kernel mode,然后把步骤2读到 user buffer的数据拷贝到 kernel buffer(数据第2次拷贝到 kernel buffer),不过这次是个不同的 kernel buffer,这个 buffer和 socket相关联。
4、系统调用 write()返回,产生一个上下文切换:从 kernel mode 切换到 user mode ,然后 DMA 从 kernel buffer拷贝数据到协议栈。
上面4个步骤有4次上下文切换,有4次拷贝,我们发现如果能减少切换次数和拷贝次数将会有效提升性能。在kernel2.0+ 版本中,系统调用 sendfile() 就是用来简化上面步骤提升性能的。sendfile() 不但能减少切换次数而且还能减少拷贝次数。
再来看一下用 sendfile()来进行网络传输的过程:
sendfile(socket,file, len);

硬盘 >> kernel buffer (快速拷贝到kernelsocket buffer) >>协议栈

1、 系统调用sendfile()通过 DMA把硬盘数据拷贝到 kernel buffer,然后数据被 kernel直接拷贝到另外一个与 socket相关的 kernel buffer。这里没有 user mode和 kernel mode之间的切换,在 kernel中直接完成了从一个 buffer到另一个 buffer的拷贝。
2、DMA 把数据从 kernelbuffer 直接拷贝给协议栈,没有切换,也不需要数据从 user mode 拷贝到 kernel mode,因为数据就在 kernel 里。

简单说,sendfile是个比 read 和 write 更高性能的系统接口, 不过需要注意的是,sendfile 是将 in_fd 的内容发送到 out_fd 。而 in_fd 不能是 socket , 也就是只能文件句柄。 所以当 Nginx 是一个静态文件服务器的时候,开启 SENDFILE 配置项能大大提高 Nginx 的性能。 但是当 Nginx 是作为一个反向代理来使用的时候,SENDFILE 则没什么用了,因为 Nginx 是反向代理的时候。 in_fd 就不是文件句柄而是 socket,此时就不符合 sendfile 函数的参数要求了。

Linux-Nginx之sendfile与上下文切换的更多相关文章

  1. Linux kernel 的 sendfile 是如何提高性能的

    Linux kernel 的 sendfile 是如何提高性能的 现在流行的 web 服务器里面都提供 sendfile 选项用来提高服务器性能,那到底 sendfile 是什么,怎么影响性能的呢? ...

  2. linux+nginx+tomcat负载均衡,实现session同步

    linux+nginx+tomcat负载均衡,实现session同步 花了一个上午的时间研究nginx+tomcat的负载均衡测试,集群环境搭建比较顺利,但是session同步的问题折腾了几个小时才搞 ...

  3. nginx的sendfile指令的作用

    linux为了解决对读文件产生的从应用空间到内核空间复制数据产生的效率影响引进了零拷贝.什么是零拷贝?这里就不多说了,请参考http://blog.csdn.net/crazyguang/articl ...

  4. linux+nginx+mysql+php

    LNMP(linux+nginx+mysql+php)服务器环境配置   一.简介 Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为 “engine X”, 是一个高性能的 ...

  5. linux独有的sendfile系统调用--“零拷贝,高效”

    参考:http://blog.csdn.net/caianye/article/details/7576198 如今几乎每个人都听说过Linux中所谓的"零拷贝"特性,然而我经常碰 ...

  6. linux nginx配置新项目加域名(设置绑定域名)

    转自:linux nginx配置新项目加域名 找到nginx的配置文件 nginx/nginx.conf 第一种方,法直接在nginx.com里面配置 user www www; worker_pro ...

  7. LNMP(linux+nginx+mysql+php)服务器环境配置【转载】

    本文转载自 园友David_Tang的博客,如有侵权请联系本人及时删除,原文地址: http://www.cnblogs.com/mchina/archive/2012/05/17/2507102.h ...

  8. linux nginx 启动脚本

    linux nginx 启动脚本 [root@webtest76 ~]# vi /etc/init.d/nginx #!/bin/bash # nginx Startup script for the ...

  9. Linux nginx日志按天分割实例

    Linux nginx日志按天分割实例   nginx的日志有个小缺点,日志文件一直就是一个,不会自动地进行切割,如果访问量很大的话,将导致日志文件非常大,不便于管理这就需要我们自己来实现了,按日期每 ...

  10. MacOS + Linux + Nginx

    Asp.Net Core 发布和部署( MacOS + Linux + Nginx ) 前言 在上篇文章中,主要介绍了 Dotnet Core Run 命令,这篇文章主要是讲解如何在Linux中,对 ...

随机推荐

  1. 《Java中方法的参数传递方式只有一种:值传递》

    //方法的参数传递机制(1):基本类型做形参的传递. class PrimitiveTransferTest { public static void swap(int a,int b) { //下面 ...

  2. openstack中运行定时任务的两种方法及源代码分析

    启动一个进程,如要想要这个进程的某个方法定时得进行执行的话,在openstack有两种方式: 一种是通过继承 periodic_task.PeriodicTasks,另一种是使用loopingcall ...

  3. Osmocom-BB多信道修改代码相关

    修改bb\src\target\firmware\layer1\prim_rx_nb.c 文件 这个nb表示normalburst,指的是ccch的数据,用专业的术语,应该是,一个ccch的burst ...

  4. ios中摄像头/相册获取图片,压缩图片,上传服务器方法总结

    相册 iphone的相册包含摄像头胶卷+用户计算机同步的部分照片.用户可以通过UIImagePickerController类提供的交互对话框来从相册中选择图像.但是,注意:相册中的图片机器路径无法直 ...

  5. KochSnow曲线

    在这里实现了Koch曲线,而且提到我们只需要对一个等边三角形的各条边按照Koch曲线的算法进行绘图就能得到KochSnow曲线,将其实现到之前提到的绘图框架中,考虑到KochSnow的实现主要依赖Ko ...

  6. vijos 1776 关押罪犯

    带权并查集+贪心. #include<iostream> #include<cstdio> #include<cstring> #include<algori ...

  7. PHP数据类型和常量

    数据类型的转换    一种是强制转换            语法:setType(变量,类型).这个函数将原变量的类型转变                在赋值前使用(类型)的形式,不会改变原变量的类 ...

  8. vs中附加IIS进程的调试方法

    项目运行以管理员的身份进行运行否则附加不进去:

  9. URAL 2040 (回文自动机)

    Problem Palindromes and Super Abilities 2 (URAL2040) 题目大意 给一个字符串,从左到右依次添加,询问每添加一个字符,新增加的回文串数量. 解题分析 ...

  10. HDU 5045

    http://acm.hdu.edu.cn/showproblem.php?pid=5045 题意:n个学生m道题,一个n*m的矩阵代表第n个学生解第m题AC的概率,任意两学生做题数差距不能大于1,问 ...