1. 首页 > 快讯

Nginx 高性能解析:深入理解线程池模式

与Apache的同步IO模型相比,Nginx由于使用了NIO,因此在性能上碾压前者。 Nginx 轻量级,占用系统资源少,天然支持高并发。

[[329666]]

今天我们简单讨论一下nginx的线程模型。请注意,它不是流程模型。

nginx以多进程模式运行。 nginx 在1.7.11 版本中提供了多线程,但这种多线程仅用于aio 模型中的本地文件操作。出发点是使用非阻塞模式来提高文件IO的效率和并发性。

所以这个多线程并不是nginx通过多线程来处理代理请求(这部分是通过epoll方式),而是用来处理一些本地的静态文件。

这里涉及到几个基本指令:sendfile、aio和directio,它们都与本地文件的操作有关。接下来我们分别看看它们的含义。

sendfile该指令与系统函数sendfile()语义相同。 sendfile的目的是提高通过socket发送本地文件的效率。官方博客介绍了如何使用nginx线程池aio实现9倍性能提升。

它还有一个更容易记住的名字,叫做零拷贝。读取传统文件和将其发送到网络有什么区别?

磁盘、网络驱动器和内存是三种不同的传输介质。如果在本地读取文件并通过套接字发送,通常会经历以下步骤:

1)磁盘驱动程序根据CPU调度从磁盘读取一定长度(chunk)的字节数据2)将字节数据复制到内核内存3)将内核内存中的数据复制到进程工作空间内存4)进程复制将数据通过socket发送到网络驱动程序缓存并通过相应的传输协议发送出去。可见,数据发送过程涉及多份,受到计算机系统设计问题的限制。

sendfile的主要出发点是减少数据复制,提高发送效率。 sendfile 是Linux 系统级调用。套接字可以通过DMA(直接内存访问)直接访问文件数据并通过传输协议发送,减少2倍的数据数量。复制(磁盘到内核,内核到工作区)。

sendfile_max_chunk 参数用于限制每个sendfile() 调用发送的最大数据大小。如果不限制大小,则整个工作进程将是独占的。默认为“无限制”。这也太霸道了吧。

对于nginx来说,代理静态本地静态文件资源(通常是小文件)是非常高效的。对于一些静态文件如html、图片等建议启用该参数。

location/video{sendfileon;sendfile_max_chunk128k;aioon;}directio此命令用于启用O_DIRECT 标志(BSD、Linux),对应于directio() 系统调用。

该参数针对大文件设置,sendfile针对小文件设置。可以通过directio 指定有限的大小。对于超过此大小的文件,将使用directio (而不是sendfile)。

按照directio的设计初衷,它有sendfile的基本原理,只不过不使用内核缓存,而是直接使用DMA,并且内存缓存(页对齐部分)在使用后也会被释放。

因此directio通常适合读取大文件,并且读取频率通常很低。因为对于高频读取来说,并不能提高效率(因为它不是复用cache,而是每次都复用DMA)。由于性能权衡,该参数默认关闭。

location/video{sendfileon;directio8m;aioon;}aio说到aio模型,语义基本一致,都是异步文件IO。 nginx默认关闭该功能,需要在更高版本的linux平台(2.6.22+)上支持。

在Linux上,directio只能读取基于512字节边界对齐的块,并且文件末尾的那些未对齐的块将使用阻塞模式读取。

同样,如果文件在开始时未对齐,则整个文件将被阻塞读取。这里所谓的对齐是指文件数据在内存页中的缓存状态。

当aio和sendfile都开启时,对于大小大于directio设置值的文件,将使用aio机制:即当文件大小小于directio设置值时,将直接使用sendfile(aio没有不参加)。

AIO,简单来说就是采用多线程异步方式读取较大的文件来提高IO效率,但实际上可能并没有什么提升。由于读取大文件无法使用缓存,且耗时,即使使用多线程,请求的等待时间也是不可预测的,尤其是并发请求较高时。但是aio可以提高IO的并发量,这是肯定的。

我们的配置文件得到了进一步的丰富。

thread_pooldefault_poolthreads=16;##main context.location/video{sendfileon;sendfile_max_chunk128k;directio8M;aiothreads=default_pool;}当线程池中的所有线程都处于繁忙状态时,新的任务请求将被添加到等待队列中。我们可以使用thread_pool中的max_queue参数来指定队列的大小。默认队列大小为65536。当队列已满时,后续请求将抛出错误。

nginx官方宣称使用多线程模式。在aio读文件的场景下,性能提升了9倍,但我对这个测试还是有一些疑问。

多线程+aio确实可以在一定程度上提高文件IO的读取性能,但是对于大文件来说,这似乎并没有想象中的那么好。这受Linux平台底层特性的影响,除非nginx本身对文件缓存进行额外的操作。

到目前为止,xjjdog仍有以下建议(供参考):

1)对于小文件的静态代理,我们应该启用sendfile,这将显着提高性能。 2)对于大文件读取(频率较低),我们可以尝试启用aio和directio,在提高并发能力的前提下,关注请求的实际响应效率;既然这是官方推荐的,我们可以尝试一下。 3)对于高频大文件读取,aio和directio的性能提升可能并不显着,但应该不会降低性能。

关于Nginx 高性能解析:深入理解线程池模式,的介绍到此结束,希望对大家有所帮助。

用户评论

米兰

哇,9倍的性能提升?!真是厉害啊,一定要看一下这个 Nginx 线程池模型的代码。

    有11位网友表示赞同!

经典的对白

我一直在想怎么提高 Nginx 的性能,这个 "线程池模式" 听起来很不错。

    有15位网友表示赞同!

坏小子不坏

GitHub 上有开源项目吗?方便下载学习一下。

    有9位网友表示赞同!

有阳光还感觉冷

之前用过 Nginx ,它有时候处理并发请求会比较慢,这个新模型会不会解决这个问题?

    有7位网友表示赞同!

花菲

9倍的提升也太夸张了吧?是不是在特定场景下才能达到这样的效果?

    有12位网友表示赞同!

莫失莫忘

我对异步编程不太了解,这个 "线程池模式" 是怎么运作的呢?

    有7位网友表示赞同!

哥帅但不是蟋蟀

感觉这个 GitHub 项目肯定会引起很多开发者关注。

    有13位网友表示赞同!

西瓜贩子

学习 Nginx 线程池模式的代码肯定可以让我的技能提升不少。

    有6位网友表示赞同!

挽手余生ら

如果能具体介绍一下这个新模型是怎么改进 Nginx 的性能,那就更好了。

    有20位网友表示赞同!

暮光薄凉

这种新的工作方式是不是会对传统的 web 服务器架构产生影响呢?

    有13位网友表示赞同!

Edinburgh°南空

看起来这是一个很有用的工具,可以用来优化 web 应用的性能。

    有18位网友表示赞同!

熏染

对于我来说,如果能简单使用这个模型,那就能解决很多问题了。

    有14位网友表示赞同!

最迷人的危险

希望能看到更多关于 "线程池模式" 的应用案例和分析。

    有9位网友表示赞同!

封锁感觉

学习新的技术总是让人激动不已,这种新模型一定很酷!

    有13位网友表示赞同!

你与清晨阳光

期待看到这个项目的发展,或许能找到一些灵感。

    有16位网友表示赞同!

娇眉恨

我尝试过很多 Nginx 优化方案,但效果都不理想。这个新模型能带来惊喜吗?

    有20位网友表示赞同!

蔚蓝的天空〃没有我的翅膀

这个项目会不会有官方的支持和维护呢?

    有11位网友表示赞同!

南宫沐风

对于普通开发者来说,这个 "线程池模式" 是否比较复杂?

    有13位网友表示赞同!

┲﹊怅惘。

我需要更深入地了解一下 "线程池模式" 的工作原理才能更好地理解它。

    有5位网友表示赞同!

拥抱

分享一下 "线程池模式" 的优缺点吧!

    有10位网友表示赞同!

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/7130.html

联系我们

在线咨询:点击这里给我发消息

微信号:666666