[TOC]

Nginx服务器架构初探

  1. Nginx服务器的Web请求处理机制

    多进程方式

    多线程方式

    异步方式。异步方式是和多进程多线程方式完全不同的一种处理客户端请求的方式。其中包含几个概念:

    网络通信中的同步机制和异步机制是描述通信模式的概念。同步机制,是指发送方发送请求后,需要等待接收到接收方的相应后,才接着发送下一个请求。异步机制,发送方发出一个请求后,不等待接收方相应这个请求,就继续发送下个请求。
    阻塞和非阻塞用来描述进程处理调用的方式。在网络通信中,主要指socket的阻塞和非阻塞的方式,而socket的实质也就是IO操作。其调用方式为,调用结果返回前,当前线程从运行状态被挂起,一直等到调用结果返回后,才进入就绪状态,获取CPU后继续执行。非阻塞调用方式中,如果调用结果不能马上返回,当前线程不会被挂起,而是立即返回执行下一个调用。

  2. Nginx服务器的事件处理机制

    在非阻塞调用中,IO调用是如何把自己的状态通知给工作进程的呢。一般有两个方案,轮询和事件驱动模型。IO调用完全由事件驱动模型来管理,事件准备好后就通知工作进程事件已经准备就绪。

    事件驱动模型一般是由事件收集器、事件发送器、事件处理器组成。

    事件收集器收集用户行为、硬件行为、软件行为。事件发送器每传递过来一个请求,目标对象创建一个进程/线程/一个待处理事件列表使用非阻塞IO方式,调用事件处理器来处理该请求。

    select库。是linux和windows都支持的基本事件驱动模型库。它首先创建所关注事件的描述符集合。对于一个描述符,可以关注其上面的读事件,写事件,异常事件,所以要创建三类事件描述符集合,分别用来收集读事件、写事件、异常事件的描述符。其次调用底层提供的select()函数,等待事件发生,然后轮询所有事件描述符集合中的每个事件描述符,检查是否有相应事件发生。

    poll库,Windows不支持。其和select的基本工作方式相同,区别在于select需要轮询三个集合,而poll只需要创建一个集合,在每个描述符对应的结构上分别设置读事件、写事件、异常事件,最后轮询的时候同时检查这三种事件是否发生。是select的一个优化。

    epoll库,是一种高效的方式。上两种的方式是创建一个待处理事件列表,然后把列表给内核,返回的时候再去轮询检查这个列表,以判断事件是否发生。在epoll中,把描述符列表的管理交给内核,一旦有某种事件发生,内核把发生事件的描述符列表通知给epoll库,这样避免了轮询整个描述符列表。epoll库的IO效率不随描述符数目增加而线性下降,因为它只会对内核上报的活跃的描述符进行操作。

Nginx服务器的代理服务

  1. 正向代理服务,局域网内的机器借助代理服务器访问局域网外的网站,主要是为了增强局域网内部网络的安全性。正向代理服务器不支持外部对内部网络的访问。

  2. 反向代理服务,如果局域网向Internet提供资源,让Internet上的其他用户可以访问局域网内的资源,也可以设置一个代理服务器,它提供的服务就叫反向代理。可以看到反向代理服务和正向代理服务在功能逻辑上是相反的。

  3. Buffer和Cache虽然都是用于提供IO吞吐效率的,但是它们是一对不同的概念,“缓冲”和“缓存”。缓冲主要用于传输效率不同步或者优先级别不相同的设备之间传递数据,一般工作对一方数据进行临时存放,再统一发送的办法传递给另一方,以降低进程之间的等待时间,保证速度较快的进程不发生间断,当数据传送完了,数据本身就没有用处了。缓存主要用于将硬盘上已有的数据在内存中建立缓存数据,提高数据的访问效率。

  4. 一个典型的反向代理配置:

    upstream backend {
    
         server 192.168.1.27:8080 weight=6;
    
         server 192.168.1.27:8081 weight=4;
    
     }
    
     server {
    
         listen 80;
    
         location / {
    
             proxy_pass http://backend;
    
             proxy_set_header Host $host;
    
             proxy_set_header X-Real-IP $remote_addr;
    
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
         }
    
     }
    

    在实际中,可以对所有请求实行轮询、加权,对特定资源,不同域名等进行负载均衡。