精华内容
下载资源
问答
  • nginx高并发原理

    2015-06-07 18:34:43
    如何设计高并发网站?nginx高并发原理以及nginx vs Apache.
  • Nginx高并发原理

    2017-01-24 20:18:52
    转载自:初步探索Nginx高并发原理首先要明白,Nginx 采用的是多进程(单线程) & 多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。多进程的工作模式1、Nginx 在启动后,...

    转载自:初步探索Nginx高并发原理

    首先要明白,Nginx 采用的是多进程(单线程) & 多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。

    这里写图片描述

    多进程的工作模式

    1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。
    2、接收来自外界的信号,向各worker进程发送信号,每个进程都有可能来处理这个连接。
    3、 master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程。
    
    • 1
    • 2
    • 3
    • 4

    注意 worker 进程数,一般会设置成机器 cpu 核数。因为更多的worker 数,只会导致进程相互竞争 cpu,从而带来不必要的上下文切换。

    使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响到其他 worker 进程。

    惊群现象

    主进程(master 进程)首先通过 socket() 来创建一个 sock 文件描述符用来监听,然后fork生成子进程(workers 进程),子进程将继承父进程的 sockfd(socket 文件描述符),之后子进程 accept() 后将创建已连接描述符(connected descriptor)),然后通过已连接描述符来与客户端通信。

    那么,由于所有子进程都继承了父进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。

    Nginx对惊群现象的处理:

    Nginx 提供了一个 accept_mutex 这个东西,这是一个加在accept上的一把互斥锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),这样就不会有惊群问题了。accept_mutex 是一个可控选项,我们可以显示地关掉,默认是打开的。

    worker进程工作流程

    当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求。一个请求,完全由 worker 进程来处理,而且只能在一个 worker 进程中处理。

    这样做带来的好处:

    1、节省锁带来的开销。每个 worker 进程都是独立的进程,不共享资源,不需要加锁。同时在编程以及问题查上时,也会方便很多。

    2、独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master 进程则很快重新启动新的 worker 进程。当然,worker 进程的也能发生意外退出。

    多进程模型每个进程/线程只能处理一路IO,那么 Nginx是如何处理多路IO呢?

    如果不使用 IO 多路复用,那么在一个进程中,同时只能处理一个请求,比如执行 accept(),如果没有连接过来,那么程序会阻塞在这里,直到有一个连接过来,才能继续向下执行。

    而多路复用,允许我们只在事件发生时才将控制返回给程序,而其他时候内核都挂起进程,随时待命。

    核心:Nginx采用的 IO多路复用模型epoll

    epoll通过在Linux内核中申请一个简易的文件系统(文件系统一般用什么数据结构实现?B+树),其工作流程分为三部分:

    1、调用 int epoll_create(int size)建立一个epoll对象,内核会创建一个eventpoll结构体,用于存放通过epoll_ctl()向epoll对象中添加进来的事件,这些事件都会挂载在红黑树中。
    2、调用 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 在 epoll 对象中为 fd 注册事件,所有添加到epoll中的事件都会与设备驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个sockfd的回调方法,将sockfd添加到eventpoll 中的双链表。
    3、调用 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 来等待事件的发生,timeout 为 -1 时,该调用会阻塞知道有事件发生
    
    • 1
    • 2
    • 3
    • 4

    这样,注册好事件之后,只要有 fd 上事件发生,epoll_wait() 就能检测到并返回给用户,用户就能”非阻塞“地进行 I/O 了。

    epoll() 中内核则维护一个链表,epoll_wait 直接检查链表是不是空就知道是否有文件描述符准备好了。(epoll 与 select 相比最大的优点是不会随着 sockfd 数目增长而降低效率,使用 select() 时,内核采用轮训的方法来查看是否有fd 准备好,其中的保存 sockfd 的是类似数组的数据结构 fd_set,key 为 fd,value 为 0 或者 1。)

    能达到这种效果,是因为在内核实现中 epoll 是根据每个 sockfd 上面的与设备驱动程序建立起来的回调函数实现的。那么,某个 sockfd 上的事件发生时,与它对应的回调函数就会被调用,来把这个 sockfd 加入链表,其他处于“空闲的”状态的则不会。在这点上,epoll 实现了一个”伪”AIO。但是如果绝大部分的 I/O 都是“活跃的”,每个 socket 使用率很高的话,epoll效率不一定比 select 高(可能是要维护队列复杂)。

    可以看出,因为一个进程里只有一个线程,所以一个进程同时只能做一件事,但是可以通过不断地切换来“同时”处理多个请求。

    例子:Nginx 会注册一个事件:“如果来自一个新客户端的连接请求到来了,再通知我”,此后只有连接请求到来,服务器才会执行 accept() 来接收请求。又比如向上游服务器(比如 PHP-FPM)转发请求,并等待请求返回时,这个处理的 worker 不会在这阻塞,它会在发送完请求后,注册一个事件:“如果缓冲区接收到数据了,告诉我一声,我再将它读进来”,于是进程就空闲下来等待事件发生。

    这样,基于 多进程+epoll, Nginx 便能实现高并发。

    使用 epoll 处理事件的一个框架,代码转自:http://www.cnblogs.com/fnlingnzb-learner/p/5835573.html

    for( ; ; )  //  无限循环
          {
              nfds = epoll_wait(epfd,events,20,500);  //  最长阻塞 500s
              for(i=0;i<nfds;++i)
              {
                  if(events[i].data.fd==listenfd) //有新的连接
                  {
                      connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); //accept这个连接
                      ev.data.fd=connfd;
                     ev.events=EPOLLIN|EPOLLET;
                     epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); //将新的fd添加到epoll的监听队列中
                 }
                 else if( events[i].events&EPOLLIN ) //接收到数据,读socket
                 {
                     n = read(sockfd, line, MAXLINE)) < 0    //读
                     ev.data.ptr = md;     //md为自定义类型,添加数据
                     ev.events=EPOLLOUT|EPOLLET;
                     epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改标识符,等待下一个循环时发送数据,异步处理的精髓
                 }
                 else if(events[i].events&EPOLLOUT) //有数据待发送,写socket
                 {
                     struct myepoll_data* md = (myepoll_data*)events[i].data.ptr;    //取数据
                     sockfd = md->fd;
                     send( sockfd, md->ptr, strlen((char*)md->ptr), 0 );        //发送数据
                     ev.data.fd=sockfd;
                     ev.events=EPOLLIN|EPOLLET;
                     epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改标识符,等待下一个循环时接收数据
                 }
                 else
                 {
                     //其他的处理
                 }
             }
         }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    Nginx 与 多进程模式 Apache 的比较:

    事件驱动适合于I/O密集型服务,多进程或线程适合于CPU密集型服务: 
    1、Nginx 更主要是作为反向代理,而非Web服务器使用。其模式是事件驱动。 
    2、事件驱动服务器,最适合做的就是这种 I/O 密集型工作,如反向代理,它在客户端与WEB服务器之间起一个数据中转作用,纯粹是 I/O 操作,自身并不涉及到复杂计算。因为进程在一个地方进行计算时,那么这个进程就不能处理其他事件了。 
    3、Nginx 只需要少量进程配合事件驱动,几个进程跑 libevent,不像 Apache 多进程模型那样动辄数百的进程数。 
    5、Nginx 处理静态文件效果也很好,那是因为读写文件和网络通信其实都是 I/O操作,处理过程一样。

    参考 http://codinglife.sinaapp.com/?p=40



    展开全文
  • 初步探索Nginx高并发原理

    万次阅读 热门讨论 2016-10-26 17:30:51
    使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。多进程的工作模式1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。 2、接收来自外界的信号,向各worker进程发送信号,每...

    Nginx

    首先要明白,Nginx采用的是多进程(单线程)&多路IO复用模型。使用了I/O多路复用技术的Nginx,就成了”并发事件驱动“的服务器。

    这里写图片描述

    多进程的工作模式

    1、Nginx在启动后,master进程fork()多个相互独立的worker进程。
    2、接收来自外界的信号,然向各worker进程发送信号,每个进程都有可能来处理这个连接。
    3、 master进程能监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动再fork()新worker进程。
    

    注意worker进程数,一般会设置成机器cpu核数。因为更多的worker只会导致进程之间相互竞争cpu,从而带来不必要的上下文切换。

    使用多进程模式,不仅能提高并发率,而且进程之间是相互独立的,一 个worker进程挂了不会影响到其他worker进程。

    惊群现象

    master进程首先通过socket()来创建一个监听描述符,然后fork()若干个worker,子进程将继承父进程的监听描述符,之后子进程在该监听描述符上accept()创建已连接描述符(connected descriptor),然后通过已连接描述符来与客户端通信。

    那么,由于所有子进程都继承了父进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。

    Nginx对惊群现象的处理:

    Nginx提供了一个accept_mutex这个东西,这是一个加在accept上的一把互斥锁。即每个worker进程在执行accept()之前都需要先获取锁,accept()成功之后再解锁。有了这把锁,同一时刻,只会有一个进程执行accpet(),这样就不会有惊群问题了。accept_mutex是一个可控选项,我们可以显示地关掉,默认是打开的。

    worker进程工作流程

    当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求。一个请求,完全由worker进程来处理,而且只会在一个worker进程中处理。

    这样做带来的好处:

    1、节省锁带来的开销。每个worker进程都彼此独立地工作,不共享任何资源,因此不需要锁。同时在编程以及问题排查上时,也会方便很多。

    2、独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程。当然,worker进程自己也能发生意外退出。

    核心:Nginx采用的 IO多路复用模型epoll

    多路复用,允许我们只在事件发生时才将控制返回给程序,而其他时候内核都挂起进程,随时待命。

    epoll通过在Linux内核中申请一个简易的文件系统(文件系统一般用B+树数据结构来实现),其工作流程分为三部分:

    1、调用 int epoll_create(int size)建立一个epoll对象,内核会创建一个eventpoll结构体,用于存放通过epoll_ctl()向epoll对象中添加进来的事件,这些事件都会挂载在红黑树中。
    2、调用 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 在 epoll 对象中为 fd 注册事件,所有添加到epoll中的事件都会与设备驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个sockfd的回调方法,将sockfd添加到eventpoll 中的双链表。
    3、调用 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 来等待事件的发生,timeout 为 -1 时,该调用会阻塞知道有事件发生
    

    这样,注册好事件之后,只要有fd上事件发生,epoll_wait()就能检测到并返回给用户,用户执行阻塞函数时就不会发生阻塞了。

    epoll()在中内核维护一个链表,epoll_wait直接检查链表是不是空就知道是否有文件描述符准备好了。顺便提一提,epoll与select、poll相比最大的优点是不会随着sockfd数目增长而降低效率,使用select()时,内核采用轮训的方法来查看是否有fd准备好,其中的保存sockfd的是类似数组的数据结构fd_set,key 为 fd,value为0或者1(发生时间)。

    能达到这种效果,是因为在内核实现中epoll是根据每 sockfd 上面的与设备驱动程序建立起来的回调函数实现的。那么,某个sockfd上的事件发生时,与它对应的回调函数就会被调用,将这个sockfd加入链表,其他处于“空闲的”状态的则不会。在这点上,epoll 实现了一个"伪"AIO。

    可以看出,因为一个进程里只有一个线程,所以一个进程同时只能做一件事,但是可以通过不断地切换来“同时”处理多个请求。

    例子:Nginx 会注册一个事件:“如果来自一个新客户端的连接请求到来了,再通知我”,此后只有连接请求到来,服务器才会执行 accept() 来接收请求。又比如向上游服务器(比如 PHP-FPM)转发请求,并等待请求返回时,这个处理的 worker 不会在这阻塞,它会在发送完请求后,注册一个事件:“如果缓冲区接收到数据了,告诉我一声,我再将它读进来”,于是进程就空闲下来等待事件发生。

    这样,基于 多进程+epoll, Nginx 便能实现高并发。

    使用 epoll 处理事件的一个框架,代码转自:http://www.cnblogs.com/fnlingnzb-learner/p/5835573.html

    for( ; ; )  //  无限循环
          {
              nfds = epoll_wait(epfd,events,20,500);  //  最长阻塞 500s
              for(i=0;i<nfds;++i)
              {
                  if(events[i].data.fd==listenfd) //有新的连接
                  {
                      connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); //accept这个连接
                      ev.data.fd=connfd;
                     ev.events=EPOLLIN|EPOLLET;
                     epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); //将新的fd添加到epoll的监听队列中
                 }
                 else if( events[i].events&EPOLLIN ) //接收到数据,读socket
                 {
                     n = read(sockfd, line, MAXLINE)) < 0    //读
                     ev.data.ptr = md;     //md为自定义类型,添加数据
                     ev.events=EPOLLOUT|EPOLLET;
                     epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改标识符,等待下一个循环时发送数据,异步处理的精髓
                 }
                 else if(events[i].events&EPOLLOUT) //有数据待发送,写socket
                 {
                     struct myepoll_data* md = (myepoll_data*)events[i].data.ptr;    //取数据
                     sockfd = md->fd;
                     send( sockfd, md->ptr, strlen((char*)md->ptr), 0 );        //发送数据
                     ev.data.fd=sockfd;
                     ev.events=EPOLLIN|EPOLLET;
                     epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改标识符,等待下一个循环时接收数据
                 }
                 else
                 {
                     //其他的处理
                 }
             }
         }
    

    Nginx 与 多进程模式 Apache 的比较:

    事件驱动适合于I/O密集型服务,多进程或线程适合于CPU密集型服务:
    1、Nginx能够大量作为反向代理使用。
    2、事件驱动服务器,最适合做的就是这种I/O密集型工作,如反向代理,它在客户端与WEB服务器之间起一个数据中转作用,纯粹是I/O操作,自身并不涉及到复杂计算。因为进程在一个地方进行计算时,那么这个进程就不能处理其他事件了。
    3、Nginx只需要少量进程配合事件驱动,起几个进程跑libevent,不像 Apache传统多进程模型那样动辄数百的进程数。
    4、Nginx处理静态文件效果也很好,那是因为读写文件和网络通信其实都是I/O操作,处理过程是一样的。

    这里仅将Nginx与传统多进程工作模式下的Apache做比较,Apache也有事件驱动的工作模式。

    参考 http://codinglife.sinaapp.com/?p=40

    展开全文
  • nginx启动后,在unix系统中会以daemon(守护)的方式在后台运行,后台进程包含一个master(主干)进程和多个worker进程,nginx是以多进程的方式工作的,nginx也是支持多线程的,但是默认方式是多进程 方式。...
    nginx启动后,在unix系统中会以daemon(守护)的方式在后台运行,后台进程包含一个master(主干)进程和多个worker进程,nginx是以多进程的方式工作的,nginx也是支持多线程的,但是默认方式是多进程 方式。
    

    master进程主要用来管理worker进程,包含:接受来自外界的信号,向各worker进程发送信号,监控worker进程的
    运行状态,当worker进程异常退出后,会自动重新启动新的worker进程,而基本网络时间是在worker进程中处理的,
    多个worker进程之间是平等的,他们同等竞争来自客户端的请求,各进程之间独立,一个请求,只可能在一个worker进程中
    处理,worker进程的个数一般设置与机器cpu核数一致,因为与nginx的进程模型以及事件处理模型分不开。

    nginx的进程模型,如图:


    每个worker进程都是master进程分出来的,当master进程建立好需要listen的socket(listenfd)之后,再分
    成多个worker进程,所有worker进程的listenfd会在新连接到来时变得可读,为了保证只有一个进程处理该连接,
    所有worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读
    事件里调用accept接受该连接。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请
    求,产生数据后,再返回给客户端,最后才断开连接


    采用这种进程模型的好处:
    1,对于每个worker进程来说,独立的进程,不需要加锁,省掉了锁带来的开销
    2,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其他进程可以继续工作,服务不会中断,master进程很快会启动新的worker进程来 顶替退出的worker进程;当worker进程异常退出时,会导致当前worker进程中的所有请求失败,不过不会影响到其他worker进程中的请求,所以可以降低风险。

    nginx采用多worker的方式来处理请求,每个worker进程中只有一个主线程,是如何实现高并发的呢?
    nginx采用异步非阻塞的方式来处理请求,nginx是可以同时处理成千上万个请求的。

    什么是异步非阻塞呢?

    非阻塞就是当事件没有准备好,马上返回EAGAIN,意思是说,事件还没有准备好,一会再来处理吧,再过一会再来检查这个事件,直到事件准备好了为止,在这期间,你可以做更多其他的事情,但带来的开销也是不小的,所以就有了异步非阻塞的事件处理机制。它提供了一种机制,可以同时监控多个事件,调用他们是阻塞的,但是可以设置超时时间,在超时时间内,如果有事件准备好了,就返回。这种机制正好解决了我们上面的两个问题。

    举个简单的例子:一群小伙子(请求)来检查身体,但是必须是裸体检查,我(worker进程)是一个医生,我要求他们站成一堆儿(事件未准备好时),脱衣服,脱好了衣服的来我面前检查,A小伙子第一个准备就绪(事件准备好了),我拿出仪器对他进行检查(对它进行读写处理),检查完毕后(当读写返回EAGAIN时),我让他再次回到队伍中。这样就可以并发处理大量的并发了,当然,这样的并发请求,指的是未处理完的请求,线程只有一个,所以同时能处理的请求只有一个,只是在请求间进行不断的切换,切换也是因为异步事件未准备好,而主动让出的,这里的切换没有任何代价,可以理解为循环处理多个准备好的事件。与多线程相比而言,这种事件处理方式是有很大的优势的,不需要创建线程,每个请求占用的内存也很少,没有上下文切换,事件处理非常的轻量级,并发数再多也不会导致无畏的资源浪费(上下文切换)。更多的并发数,只是会占用更多的内存而已。

    经过测试,在24G内存的机器上,处理的并发请求数达到过200万。

    展开全文
  • Nginx现在是非常火爆的web服务器,她使用更少的资源,支持更多的并发连接数,她实现了linux的epoll模型,能够支持高达50,000个并发连接数的响应。Nginx采用的是多进程单线程和多路IO复用模型。使用了I/O多路复用技术...

    Nginx现在是非常火爆的web服务器,她使用更少的资源,支持更多的并发连接数,她实现了linux的epoll模型,能够支持高达 50,000 个并发连接数的响应。Nginx采用的是多进程单线程和多路IO复用模型。使用了I/O多路复用技术的Nginx,就成了”并发事件驱动“的服务器。这里再强调下重点,

    • 多进程单线程
    • 多路IO复用模型

    一、多进程单线程

    Nginx 自己实现了对epoll的封装,是多进程单线程的典型代表。使用多进程模式,不仅能提高并发率,而且进程之间是相互独立的,一 个worker进程挂了不会影响到其他worker进程。

    master进程管理worker进程:

    1. 接收来自外界的信号。
    2. 向各worker进程发送信号。
    3. 监控woker进程的运行状态。
    4. 当woker进程退出后(异常情况下),会自动重新启动新的woker进程。

    注意worker进程数,一般会设置成机器cpu核数。因为更多的worker只会导致进程之间相互竞争cpu,从而带来不必要的上下文切换。

    二、IO多路复用模型epoll

    多路复用,允许我们只在事件发生时才将控制返回给程序,而其他时候内核都挂起进程,随时待命。

    epoll通过在Linux内核中申请一个简易的文件系统(文件系统一般用B+树数据结构来实现),其工作流程分为三部分:

    1. 调用 int epoll_create(int size)建立一个epoll对象,内核会创建一个eventpoll结构体,用于存放通过epoll_ctl()向epoll对象中添加进来的事件,这些事件都会挂载在红黑树中。
    2. 调用 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 在 epoll 对象中为 fd 注册事件,所有添加到epoll中的事件都会与设备驱动程序建立回调关系,也就是说,当相应的事件发生时会调用这个sockfd的回调方法,将sockfd添加到eventpoll 中的双链表。
    3. 调用 int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 来等待事件的发生,timeout 为 -1 时,该调用会阻塞知道有事件发生。

    注册好事件之后,只要有fd上事件发生,epoll_wait()就能检测到并返回给用户,用户执行阻塞函数时就不会发生阻塞了。

    epoll()在中内核维护一个链表,epoll_wait直接检查链表是不是空就知道是否有文件描述符准备好了。顺便提一提,epoll与select、poll相比最大的优点是不会随着sockfd数目增长而降低效率,使用select()时,内核采用轮训的方法来查看是否有fd准备好,其中的保存sockfd的是类似数组的数据结构fd_set,key 为 fd,value为0或者1(发生时间)。

    能达到这种效果,是因为在内核实现中epoll是根据每 sockfd 上面的与设备驱动程序建立起来的回调函数实现的。那么,某个sockfd上的事件发生时,与它对应的回调函数就会被调用,将这个sockfd加入链表,其他处于“空闲的”状态的则不会。在这点上,epoll 实现了一个"伪"AIO。

    可以看出,因为一个进程里只有一个线程,所以一个进程同时只能做一件事,但是可以通过不断地切换来“同时”处理多个请求。

    例子:Nginx 会注册一个事件:“如果来自一个新客户端的连接请求到来了,再通知我”,此后只有连接请求到来,服务器才会执行 accept() 来接收请求。又比如向上游服务器(比如 PHP-FPM)转发请求,并等待请求返回时,这个处理的 worker 不会在这阻塞,它会在发送完请求后,注册一个事件:“如果缓冲区接收到数据了,告诉我一声,我再将它读进来”,于是进程就空闲下来等待事件发生。

    这样,基于 多进程+epoll, Nginx 便能实现高并发。

    三、worker进程工作流程

    当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求。一个请求,完全由worker进程来处理,而且只会在一个worker进程中处理。优点:

    1. 节省锁带来的开销。每个worker进程都彼此独立地工作,不共享任何资源,因此不需要锁。同时在编程以及问题排查上时,也会方便很多。
    2. 独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程。当然,worker进程自己也能发生意外退出。

    四、对惊群效应的处理

    Nginx提供了一个accept_mutex这个东西,这是一个加在accept上的一把互斥锁。即每个worker进程在执行accept()之前都需要先获取锁,accept()成功之后再解锁。有了这把锁,同一时刻,只会有一个进程执行accpet(),这样就不会有惊群问题了。accept_mutex是一个可控选项,我们可以显示地关掉,默认是打开的。

    展开全文
  • 1.nginx高并发原理(多进程+epool实现高并发) 1.Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程 2.每个子进程只有一个线程,采用的 IO多路复用模型epoll,实现高并发 2.epoll能实现高并发...
  • nginx高并发优化

    2017-01-16 21:57:02
    1.安装nginx 1.1解压nginx,进入到目录 1.2配置安装选项 #./configure --prefix=/usr/local/nginx --add-module=/app/ngx_http_consistent_hash-master --with-http_stub_status_module 配置选项是一致性哈希,...
  • nginx实现高并发原理

    千次阅读 2018-02-23 14:15:45
    nginx实现高并发原理Nginx首先要明白,Nginx 采用的是多进程(单线程) &amp; 多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。异步非阻塞(AIO)的详解...
  • 二、Nginx如何处理高并发 1、Apache面对高并发,为什么很无力? Apache处理一个请求是 同步阻塞 的模式。 每到达一个请求,Apache都会去fork一个子进程去处理这个请求,直到这个请求处理完毕。 面对...
  • Nginx 是如何实现高并发的? Nginx 采用的是多进程(单线程) & 多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。其实现了异步,非阻塞,使用了epoll 和大量的底层代码优化...
  • Nginx 是如何实现高并发的?Nginx 采用的是多进程(单线程) & 多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。其实现了异步,非阻塞,使用了epoll 和大量的底层代码优化。...
  •  抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发nginx 能保持低资源低消耗高性能   高度模块化的设计,编写模块相对简单   社区活跃,各种高性能模块出品迅速啊   a
  • 5G、IOT、多屏合一、万物互联时代来了,SpringCloud+Nginx分布式微服务架构已经成为Java后端应用的主流架构,但是对于SpringCloud RPC底层原理Nginx底层原理等核心知识,广大的Java开发同学们相对欠缺,而且市面上...
  • 一、nginx 高并发原理 简单介绍:nginx 采用的是多进程(单线程) + io多路复用(epoll)模型 实现高并发 二、nginx 多进程 启动nginx 解析初始化配置文件后会 创建(fork)一个master进程 之后 这个进程会...
  • Nginx 作为业界知名的性能服务器,被广泛的应用。它的性能正是由于其优秀的架构设计,其架构主要包括这几点:模块化设计、事件驱动架构、请求的多阶段异步处理、管理进程与多工作进程设计、内存池的设计,以下...
  • Nginx Ingress Controller 基于 Nginx 实现了 Kubernetes Ingress API,Nginx 是公认的性能网关,但如果不对其进行一些参数调优,就不能充分发挥出性能的优势。之前我们在Nginx Ingress on TKE 部署最佳实践一文...
  • 文章目录Nginx进程模型解析Worker的抢占机制Nginx的事件处理机制小结 Nginx进程模型解析 nginx包含了两种进程: worker进程:主进程 master进程:工作进程 通过下面的命令可以看出: [root@localhost html]# ps -...
  • 高并发下的Nginx性能优化实战 1. Nginx入门 2. Nginx实战应用 3. 高并发下的Nginx优化 解读Nginx的核心知识、掌握nginx核心原理Nginx高并发下的性能优化
  • nginx高可用?nginx 是如何实现并发的?为什么nginx不使用多线程?nginx常见的优化手段有哪些?502错误可能原因有哪些? 面试官心理分析 主要是看应聘人员的对NGINX的基本原理是否熟悉,因为大多数运维人员多多少...
  • 最近由于项目的需要,学习了一下Nginx的知识,特此记录一下
  • 高并发利器Nginx.xmind

    2020-05-11 17:54:23
    学习nginx高级笔记,内容中涉及到调优细节和原理, 备工作中遇到速查和深入理解,不断完善中,需要的同学自取
  • 1 epoll编程,如何实现高并发服务器开发? - 知乎 https://www.zhihu.com/question/21516827/answer/55127881 nginx 多进程网络编程的巅峰 memcached 多线程网络编程的巅峰 redis单线程网络编程的巅峰~~ 2 为...
  •  高并发下的Nginx性能优化实战、解读Nginx的核心知识、掌握nginx核心原理?通过本期课程将解答我们的疑惑。
  • Nginx高并发神器!

    2019-12-26 08:48:00
    对于开发来说,我们在工作中多多少少都会遇到web服务的性能优化、高并发等问题,而Nginx 是一个万能药。可以在百万并发连接下实现高吞吐量的 Web 服务,同时诸多应用场景下的问题都可...
  •  高并发下的Nginx性能优化实战、解读Nginx的核心知识、掌握nginx核心原理?通过本期课程将解答我们的疑惑。
  •  高并发下的Nginx性能优化实战、解读Nginx的核心知识、掌握nginx核心原理?通过本期课程将解答我们的疑惑。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,404
精华内容 16,561
关键字:

nginx高并发原理