zoukankan      html  css  js  c++  java
  • 【Nginx】Nginx处理请求过程

    1. worker进程工作机制
      现在我们了解了当我们在操作nginx的时候,nginx内部做的一些事情,那么worker进程又是如何处理请求的呢?

      我们前面有提到,worker进程之间是平等的,每个进程,处理请求的机会也是一样的。

    当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?

      首先,每个worker进程都是从master进程fork过来,在master进程里面,先建立好需要listen的socket(listenfd)之后,这句话的意思就是说master进程会监听来自客户端的请求,然后再fork出多个worker进程。且所有worker进程的listenfd会在新连接到来时变得可读,为了保证只有一个进程处理该连接,所有worker进程在注册listenfd读事件前抢accept_mutex ,worker进程处理请求的过程大概如下图所示:

    看图顺序是先看绿色,然后再看蓝色,最后看红色。
    绿色部分表示客户端发送的请求,蓝色部分表示master进程管理(fork)的worker进程,红色部分表示worker进程抢夺accept_mutex,灰色部分表示注册事件,然后accpet接受连接并处理。

      对于nginx的抢占机制来说,当master进程listen到来自client发送的请求时,会让所有处于空闲状态的worker进程抢夺accept_mutex ,抢到accept_mutex(互斥锁)的worker进程注册listenfd读事件,然后在读事件里调用accept接收并处理client的请求。

    注意:**所有**处于空闲状态的worker进程在进行accept接收client的请求之前,都会先对client的accept_mutex锁进行try_lock尝试加锁,需要强调的是这个过程是竞争式的。

      另外要明白的一点是,这里为什么是try_lock(尝试加锁),而不是lock(加锁)。

      假设是lock的话,除了对client的请求的accept_mutex进行加锁(lock)成功的worker进程外,其他所有对client的accept_mutex锁进行lock加锁的worker进程都会阻塞,除非已经对client请求的accept_mutex加锁成功的worker进程调用unlock进行解锁释放(在解锁的同时会唤醒阻塞在此accept_mutex的其他所有worker进程),否则其他worker进程会一直阻塞在此处于空闲状态,这势必会造成资源浪费。

      而如果是try_lock的话,那么其他worker进程对client尝试加锁失败就会立即返回,去处理其他client的请求,因此不会有其他worker进程阻塞在这,也就不会造成资源浪费了。

      当一个worker进程对client的accept_mutex加锁成功,accept这个连接并注册读事件,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,一个完整的请求就是这样的了。

    2. nginx处理请求过程
      nginx使用一个多进程模型来对外提供服务,一个master进程和多个worker进程,master进程负责管理nginx本身和其他worker进程。

      所有实际上的业务处理逻辑都在worker进程。worker进程中有一个函数,执行无限循环,不断处理收到的来自客户端的请求,并进行处理,直到整个nginx服务被停止。

      worker进程中,ngx_worker_process_cycle()函数就是这个无限循环的处理函数。在这个函数中,一个请求的简单处理流程如下:

    操作系统提供的机制(例如epoll, kqueue等)产生相关的事件。
    接收和处理这些事件,如是接受到数据,则产生更高层的request对象。
    处理request的header和body。
    产生响应,处理响应数据并发送回客户端。
    完成request的处理。
    重新初始化定时器及其他事件,断开连接。
    ---------------------

    转自:https://blog.csdn.net/qq_35733751/article/details/79832005 

  • 相关阅读:
    学习进度汇总
    session系列(一)--之--session 与cookie
    遇到一个合适的人到底有多难
    Spring Bean学习创建及使用<二>
    Spring Bean学习创建及使用<一>
    转发:Java对象及其引用
    多线程分配线程的实现方案:CountDownLatch类
    java基础知识
    java静态标示符static详解
    淘宝TAE平台定时任务包的部署步骤
  • 原文地址:https://www.cnblogs.com/itplay/p/10681232.html
Copyright © 2011-2022 走看看