阅读 83

nginx静态资源优化配置方法

Nginx对静态资源如何进行优化配置。这里从三个属性配置进行优化:

sendfile on;  tcp_nopush on;  tcp_nodeplay on;  复制代码

sendfile

sendfile,用来开启高效的文件传输模式。sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称之为零拷贝。

语法sendfile on | off
默认值sendfile off;
位置http,server,location

请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务器端应用程序,服务器端应用程序会处理这些请求,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器(网卡)传递回去。

原理解释:

read/write:

在传统的文件传输方式(read、write/send方式),具体流程细节如下:

  1. 调用read函数,文件数据拷贝到内核缓冲区

  2. read函数返回,数据从内核缓冲区拷贝到用户缓冲区

  3. 调用write/send函数,将数据从用户缓冲区拷贝到内核socket缓冲区

  4. 数据从内核socket缓冲区拷贝到协议引擎中

在这个过程当中,文件数据实际上是经过了四次拷贝操作: 硬盘—>内核缓冲区—>用户缓冲区—>内核socket缓冲区—>协议引擎

sendfile:

sendfile系统调用则提供了一种减少拷贝次数,提升文件传输性能的方法。

  1. sendfile系统调用利用DMA引擎将文件数据拷贝到内核缓冲区,之后数据被拷贝到内核socket缓冲区中

  2. DMA引擎将数据从内核socket缓冲区拷贝到协议引擎中

这里没有用户态和内核态之间的切换,也没有内核缓冲区和用户缓冲区之间的拷贝,大大提升了传输性能。 这个过程数据经历的拷贝操作如下: 硬盘—>内核缓冲区—>内核socket缓冲区—>协议引擎

带有DMA收集拷贝功能的sendfile

对于带有DMA收集拷贝功能的sendfile系统调用,还可以再减少一次内核缓冲区之间的拷贝。具体流程如下:

  1. sendfile系统调用利用DMA引擎将文件数据拷贝到内核缓冲区,之后,将带有文件位置和长度信息的缓冲区描述符添加到内核socket缓冲区中

  2. DMA引擎会将数据直接从内核缓冲区拷贝到协议引擎中

这个过程数据经历的拷贝操作如下: 硬盘—>内核缓冲区—>协议引擎

tcp_nopush

tcp_nopush:该指令必须在sendfifile打开的状态下才会生效,主要是用来提升网络包的传输'效率'

语法tcp_nopush on | off;
默认值tcp_nopush off;
位置http,server,location

语法tcp_nppush的含义,当有数据时,先别着急发送,确保数据包已经装满数据,避免了网络拥塞。他可以配置一次发送数据的包大小。也就是说,它不是按时间累计0.2秒后发送包,而是当包累计到一定大小后就发送。

当使用sendfile函数时,tcp_nopush才起作用,它和指令tco_nodelay是互斥的。tcp_cork是linux下tcp/ip传输的一个标准了,这个标准的大概的意思是,一般情况下,在tcp交互的过程中,当应用程序接收到数据包后马上传送出去,不等待,而tcp_cork选项是数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞,已经是默认了。

也就是说tcp_nopush = on 会设置调用tcp_cork方法,这个也是默认的,结果就是数据包不会马上传送出去,等到数据包最大时,一次性的传输出去,这样有助于解决网络堵塞。

对于nginx配置文件中的tcp_nopush,默认就是tcp_nopush,不需要特别指定,这个选项对于www,ftp等大文件很有帮助

tcp_nodelay

tcp_nodelay:该指令必须在keep-alive连接开启的情况下才生效,来提高网络包传输的'实时性'.

你怎么可以强制 socket 在它的缓冲区里发送数据? 一个解决方案是 TCP 堆栈的 TCP_NODELAY选项。这样就可以使缓冲区中的数据立即发送出去。

Nginx的 TCP_NODELAY 选项使得在打开一个新的 socket 时增加了TCP_NODELAY选项。但这时会造成一种情况: 终端应用程序每产生一次操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据以及40个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞。为了避免这种情况,TCP堆栈实现了等待数据 0.2秒钟,因此操作后它不会发送一个数据包,而是将这段时间内的数据打成一个大的包。这一机制是由Nagle算法保证。

语法tcp_nodelay on | off;
默认值tcp_nodelay on;
位置http,server,location

在平时使用的时候可以将两个值都打开。"tcp_nopush"和”tcp_nodelay“是"互斥的",那么为什么要将这两个值都打开,这个大家需要知道的是在linux2.5.9以后的版本中两者是可以兼容的,三个指令都开启的好处是,sendfifile可以开启高效的文件传输模式,tcp_nopush开启可以确保在发送到客户端之前数据包已经充分“填满”, 这大大减少了网络开销,并加快了文件发送的速度。 然后,当它到达最后一个可能因为没有“填满”而暂停的数据包时,Nginx会忽略tcp_nopush参数, 然后,tcp_nodelay强制套接字发送数据。由此可知,TCP_NOPUSH可以与TCP_NODELAY一起设置,它比单独配置TCP_NODELAY具有更强的性能。所以我们可以使用如下配置来优化Nginx静态资源的处理

sendfile on;  tcp_nopush on;  tcp_nodelay on; 复制代码

参数sendfile on 用于开启文件高效传输模式,同时将tcp_nopush on 和tcp_nodelay on 两个指令设置为on,可防止网络及磁盘I/O阻塞,提升Nginx工作效率。


作者:张哲溪
链接:https://juejin.cn/post/7026154981220679688

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐