`
QING____
  • 浏览: 2250818 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

nginx线程池模式探讨

 
阅读更多

    nginx的IO模型其实大家应该有所了解,简单而言,就是一个master进程和多个worker进程(进程数由配置决定),master进程负责accept请求并队列化,最后转发给worker进程并由其进行处理请求和响应的整个过程。不过,这是进程层面,每个进程单线程处理。nginx在1.7.11版本提供了多线程特性(multi-threading),不过这个多线程仅用在aio模型(IO模型)中对本地文件的操作上,出发点就是以非阻塞模式来提高文件IO的效率和并发能力;所以这个多线程,并不是nginx通过多线程的方式处理proxy request(这部分是通过epoll模式),而是用来处理本地的一些静态文件。

 

    这里涉及到几个指令:sendfile、aio、directio,它们均与本地文件的操作有关,我们先看看它们的意义:

1、sendfile:

    跟系统“sendfile()”参数具有相同的语义,sendfile的目的就是提高本地文件通过socket发送的效率;磁盘、网络驱动器、内存是三种不同的传输介质,如果从本地读取一个文件并通过socket发送出去,通常情况下是进过如下几个步骤:

    1)磁盘驱动器从根据CPU的调度,从磁盘读取一定长度(chunk)的字节数据 2)字节数据copy到内核内存中 3)将内核内存中的数据copy到进程工作区内存 4)进程通过socket将数据copy到网络驱动器缓存, 并通过相应的传输协议发送出去。

    我们能够简单看出,数据的发送过程涉及到多次copy,这受限于计算机系统的设计问题;那么sendfile的主要出发点就是减少数据的copy以提高发送效率,sendfile是linux系统级的调用,socket可以通过DMA(直接内存访问)方式直接访问文件数据,并通过传输协议发送,减少了2次数据copy(磁盘到内核,内核到工作区)。

    sendfile_max_chunk参数用于限定每次sendfile()调用发送的最大数据尺寸,如果不限制大小的话,将会独占整个worker进程,默认为“无限制”。

    对于nginx而言,代理静态本地的静态文件资源(通常是小文件)将是非常高效的,建议对一些静态文件比如html、图片等,开启此参数。

location /video {
    sendfile on;
    sendfile_max_chunk 128k;
    aio on;
}

  

2、directio

    开启对O_DIRECT标记(BSD,linux)的使用,对应directio()这个系统调用,这个参数是针对大文件而设定的,sendfile针对的是小文件,通过directio可以指定限定的尺寸大小,对于超过此size的文件,将会使用directio(而不再使用sendfile)。根据directio的设计初衷,它具备sendfile的基本原理,只是不使用内核cache,而是直接使用DMA,而且使用之后内存cache(页对齐部分)也将被释放,因此directio通常适用于大文件读取,而且通常读取频率很低,对于高频的读取并不能提高效率(因为其不会重用cache,而是每次都DMA)。因为存在性能权衡问题,此参数默认为off。

location /video {
    sendfile on;
    directio 8m;
    aio on;
}

 

3、aio 

    我们会联想到aio模型,其实语义也基本相同,就是异步文件IO,nginx默认关闭此特性,它需要在高版本的linux平台上才支持(2.6.22+)。在linux平台上,directio只能读取基于512字节边界对齐的blocks,文件结束的那些未对齐的block将使用阻塞模式读取,同样那些文件在开头没有对齐时整个文件都将阻塞式读取,这里所谓的对齐,就是文件数据在内存页中的cache情况。

    当aio和sendfile都开启时,将会对那些size大于directio设定值的文件使用aio机制,即当小于directio设定值的文件将直接使用sendfile(aio不参与)。

    aio简单而言,就是使用多线程异步模式读取较大的文件,以提高IO效率,但是事实上可能并没有任何提高,因为大文件的读取即不能使用cache、而且本身也是耗时的,即使是多线程,对于request的等待时间也是无法预估的,特别是并发请求较高的时候,但是aio提高IO的并发能力是确定的。

 

    默认情况下,多线程模式是关闭的,我们需要通过“--with-threads”配置来开启,此特性尽在支持epoll、kqueue的平台上兼容。对于线程池的设置,我们可以通过“thread_pool”来声明,并在aio指令中指定。

thread_pool default_pool threads=16;##main上下文
...
location /video {
    sendfile on;
    sendfile_max_chunk 128k;
    directio 8M;
    aio threads=default_pool;
}

    当线程池中所有的线程都处于busy状态,那么新的task请求将会加入到等待队列,我们可以在thread_pool中使用“max_queue”参数来指定队列的大小,默认队列大小为65536,当队列已满后续的请求将会抛出error。

 

4、其他

    nginx官方宣称使用多线程模式,在aio读取文件场景下,性能有9倍的提升,参见文档;但是本人还是对这个测试具有一定怀疑态度,多线程 + aio在一定程度的确可以提高文件IO的读取性能,但是对于大文件而言,这似乎并没有想象的那么优秀,这受制于linux平台底层的本身特性,除非nginx自己对文件cache做了额外的操作。

    到目前为止,我们仍然建议大家:

    1)对于小文件的静态代理,我们应该开启sendfile,这对性能的提升是显著的。

    2)对于大文件读取(低频),我们可以尝试开启aio、directio,在提升并发能力的前提下,关注request的实际响应效率;既然官方推荐这么用,我们可以报以尝试的态度。

    3)对于高频单文件读取,aio、directio的性能或许提升并不显著,但应该不会降低性能。

分享到:
评论

相关推荐

    linux_nginx

    标题“Linux_Nginx”揭示了我们即将探讨的是关于Linux操作系统下的Nginx服务器的使用和配置。Nginx是一款高性能、轻量级的HTTP和反向代理服务器,以其高并发处理能力、低内存占用以及丰富的模块化设计而受到广泛青睐...

    java多线程_设计模式_各种技术(我的书架)

    此外,还有线程池模式,Java提供ExecutorService接口和ThreadPoolExecutor类来管理和控制线程,提高系统性能和资源利用率。 标签中的"源码"提示我们关注Java多线程和设计模式的具体实现。通过阅读开源项目的源码,...

    Redis Spring 并发限制动态代理

    本文将深入探讨“Redis Spring 并发限制动态代理”这一主题,解释如何通过动态代理技术实现对Redis连接的智能管理,以及线程池的并发限制策略。 首先,让我们理解什么是动态代理。动态代理是Java中的一种设计模式,...

    零声学院 第9代 Linux CC++后台架构开发 成长体系课程 - v1.21

    **源码分析专题**深入探讨了Nginx、Redis和skynet等开源项目的源码,分析了它们的基础架构、数据结构、通信机制以及并发编程模型。对于Nginx,课程涵盖了HTTP架构、进程通信、slab内存管理以及upstream机制;对于...

    商城笔记11111111

    【描述】:本文将深入探讨商城系统的开发技术栈,包括B2C和C2B2C模式的理解,以及Java项目中的关键技术和工具的运用。 【标签】:java项目 【正文】: 1. 商城模式理解 1.1 B2C与C2B2C模式 - **B2C**(Business...

    Java架构面试专题汇总(含答案)和学习笔记

    下面,我们将深入探讨其中可能涉及的一些核心知识点。 1. **Java基础** - **内存管理**:包括Java内存区域划分(堆、栈、方法区等)、垃圾回收机制(GC)、内存溢出异常(OOM)的分析与解决。 - **多线程**:线程...

    Tomcat性能优化及JVM内存工作原理

    5. **与Apache或Nginx整合**:作为Web服务器时,可以结合Apache或Nginx进行负载均衡和静态资源处理,减轻Tomcat的压力。 6. **选择合适的垃圾回收算法**:不同的垃圾回收器有不同的性能特点,如CMS、G1、ZGC等,...

    Jesse.Storimer.Working.with.TCP.Sockets.Oct.2012

    网络架构模式的探讨,包括进程每连接、线程每连接、预派生和线程池等模型,都被作者作为不同章节独立进行了详细讲解和示例演示。 作者还特别探讨了事件驱动模型(也称为反应器模式),并针对一些常用的网络架构软件...

    Java高并发高性能分布式框架从无到有微服务架构设计.docx

    本文将深入探讨如何从零开始构建这样的系统,旨在帮助开发者理解并掌握相关的技术和实践。 首先,我们要明白高并发意味着系统能够同时处理大量的用户请求,而高性能则要求系统在保证响应速度的同时,有效地利用资源...

    亿级流量网站架构核心技术 跟开涛学搭建高可用高并发系统

    架构是系统的骨架,决定了系统的设计模式和扩展性。在亿级流量的场景下,架构设计需要考虑负载均衡、分布式计算、数据库优化等多个方面。负载均衡通过将请求分散到多个服务器,避免单点过载;分布式计算则利用多台...

    Tomcat7优化

    3. 编译器设置:启用Server模式的HotSpot编译器,通过`-XX:+UseServerGC`命令,可以提升代码的运行效率。 二、线程池优化 1. `maxThreads`:设置合理的最大线程数,避免过多线程导致资源浪费,也防止线程数过多...

    tomcat7 优化 性能调优

    本文将围绕“Tomcat7优化与性能调优”的主题,深入探讨优化策略,包括但不限于配置调整、启动模式选择、线程池设置、JVM参数调整等方面。 #### 二、服务器资源考量 服务器所能提供的CPU、内存、硬盘等硬件资源对...

    基于Java的即时通讯工具设计与代码实现

    本文将深入探讨如何使用Java语言来设计并实现一个即时通讯工具,涵盖了从架构设计到具体代码实现的关键知识点。 1. **基础架构** - **TCP/IP协议**:即时通讯工具的核心是建立可靠的网络连接,Java通过Socket编程...

    Linux C_C++后端服务器架构开发1

    4. **中间件开发**:深入学习MySQL、Redis、Nginx和MongoDB等常用中间件,理解其工作原理和优化技巧,如MySQL的索引原理、事务处理、TiDB分布式数据库的存储引擎和集群方案。 5. **开源框架**:探讨如skynet、TARS...

    使用Java实现高并发推送服务.zip

    在这个主题中,我们将深入探讨如何利用Java来构建高效、稳定的高并发推送服务。 1. **线程池管理** - **Java ExecutorService**: 高并发环境下,通过Java的ExecutorService和ThreadPoolExecutor管理线程资源,避免...

    tomcat笔记_已.docx

    本笔记主要探讨 Tomcat 8.5 的整体架构、各个组件及其相互关系。 1. Tomcat 总体架构 Tomcat 的核心结构由多个组件构成,包括 Service、Connector、Engine、Host 和 Context。Service 是顶级容器,可以包含一个或多...

    java并发编程与高并发解决方案

    在探讨Java并发编程与高并发解决方案之前,我们首先需要理解几个关键概念:并发(Concurrency)、高并发(High Concurrency)以及多线程(Multithreading)。这些概念是现代软件开发中不可或缺的一部分,尤其是在...

    FTP(服务器)完整的

    在这个"FTP(服务器)完整"的项目中,我们重点探讨的是如何构建一个支持多线程的FTP服务器,以及客户端如何通过DOC(可能是文档)或网页形式与之交互。 首先,我们需要理解FTP服务器的工作原理。FTP服务器是基于TCP...

Global site tag (gtag.js) - Google Analytics