Nginx基础流程与启动过程解析

最近在学习Nginx源码,由于时间有限,主要看主体逻辑流程,事件模块,HTTP模块等重要模块。本章首先对Nginx启动过程做详细分析。

Nginx架构设计理念

Nginx的架构设计思想非常的好,很适合高性能服务器的要求,这种服务器的特点在于同时注重系统的整体性能和单次服务的延时性,而Nginx的出现完美填补了这一块的空缺。

模块化

Nginx设计的最大特点是模块化,具体分成http模块、http过滤模块、event模块、core模块、mail模块等。这样做的好处在于系统的可拓展性变高,如果想要增加功能,可以直接增加一个模块,并将其加入即可。同时,降低模块之间的耦合程度,提高模块自身的内聚程序,将系统的服务功能分散到不同的模块之间,这样的设计也符合软件工程中的设计概念。

进程模型

Nginx采用的是多进程服务器模型,系统启动的时候只会有一个master进程,在conf文件中可以指定启动的worker进程数目(一般而言,推荐worker进程的数目为cpu核数),从而形成单一master进程管理多个worker进程的模型。
这里就有一个问题,一般的高性能io模型都是coroutines + threadpool 、或者one loop per thread + threadpool(多线程),简单而言线程之间的切换开销较小,而且同个进程的线程之间有很多资源共享,这样就为了高性能提供了基础。那多进程的io模型如何实现高性能?这里贴一份知乎大神的解答。

作者:linuor
链接:https://www.zhihu.com/question/22062795/answer/20197329
来源:知乎
如果一个server采用一个进程负责一个request的方式,那么进程数就是并发数。那么显而易见的,就是会有很多进程在等待中。等什么?最多的应该是等待网络传输。其缺点题主应该也感觉到了,此处不述。而nginx 的异步非阻塞工作方式正是利用了这点等待的时间。在需要等待的时候,这些进程就空闲出来待命了。因此表现为少数几个进程就解决了大量的并发问题。
nginx是如何利用的呢,简单来说:同样的4个进程,如果采用一个进程负责一个request的方式,那么,同时进来4个request之后,每个进程就负责其中一个,直至会话关闭。期间,如果有第5个request进来了。就无法及时反应了,因为4个进程都没干完活呢,因此,一般有个调度进程,每当新进来了一个request,就新开个进程来处理。
nginx不这样,每进来一个request,会有一个worker进程去处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么傻等着,他会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。于是他就休息去了。此时,如果再有request 进来,他就可以很快再按这种方式处理。而一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着往下走。

简单而言,异步(回调事件)、非阻塞(每个进程执行期间不允许阻塞)、epoll(多路复用基础)等机制联合起来导致了nginx的高性能。

主要应用功能

Nginx目前在工业界也有很好的应用,但是基本上就会作为静态资源服务,或者作为内网与外网的第一个通道,作为负载均衡或者反向代理的服务器,接下来简单介绍其主要应用功能。

反向代理

反向代理服务器的功能是将外网上的请求转发到内网的服务器中,作为外网和内网之间的桥梁。理解正向代理和反向代理区别最好的一句话就是:正向代理是代理客户端,反向代理是代理服务器。反向代理有很多好处:

  1. 可以提高内部服务器集群的安全性。代理服务器作为内部服务器的访问的一个接口,所有对内部服务器的访问都要通过反向代理服务进行转发,而反向代理服务器就可以作为第一层的保护屏障。
  2. 一些访问量大的静态资源可以直接放在反向代理服务器,减少带宽压力。
  3. 反向代理服务器可以规划好内部路由请求。当内部集群有多个系统分布在不同的机器上,如果想要通过外网访问这些服务(前提是防火墙允许的情况下),可以很好地利用反向代理请求。

负载均衡

负载均衡从名字就可以看出其作用,当多台服务器提供相同的功能时候,有时候可能出现所有请求都到离其最近的服务器上,这样就会导致部分服务器负载很大,而部分服务器没有提供服务,这时候就需要负载均衡服务器。常用于将工作负载分布到多个服务器来提高网站、应用、数据库或其他服务的性能和可靠性。
这里就涉及到负载均衡算法(通过什么方式将请求分发给不同的服务器)
常见的负载均衡算法有三种:

  1. 轮询算法(Round Robin)按顺序轮询的分配请求给服务器
  2. 最小连接算法(Least Connections)将请求分配给连接数最小的服务器
  3. hash ip算法(Source)根据请求的ip地址,可以保证每次请求hash后分配给固定的服务器

动静分离

通常来说,Nginx一般可以存储静态资源(如html,css,js),因为这种资源是每次请求都要获取的,而动态资源则放到不同的服务器上(常用tomcat代理)。

Nginx启动过程概述

Nginx启动过程如下图所示(nginx.c):
nginx启动过程

  1. Nginx在启动的时候首先会解析命令行,处理各种参数。然后主要是确定配置文件nginx.conf路径。
  2. 第二步就是判断是否需要平滑升级。
  3. 然后就是各种初始化。
  4. 然后判断nginx是否是以单进程运行,如果是则调用所有模块的init方法,然后会进行正常的工作模式,如果是master-worker模式则会后面具体分析。

master进程

master进程的工作室管理worker进程,master不会去处理网络事件,只会通过信号管理worker进程,其主要的工作在ngx_master_process_cycle(ngx_process_cycle.c)函数中,流程如下:
master进程流程
master的工作很简单,一开始初始化好信号,然后sigprocmask阻塞这些关联的信号,以防其阻碍到fork,然后再循环中,每次sigsuspend挂起进程等待信号,当有信号来的时候,唤起master进程,进程随机查看标志位分别进行处理。
这里标志主要包括:reap、terminate、quit、reconfigure、restart、reopen、change_binary、noaccept。

worker进程

worker进程主要用于处理网络事件。通过master进程中调用ngx_start_worker_processes函数,ngx_start_worker_processes函数调用ngx_spawn_process函数,实际上fork的工作是在ngx_spawn_process函数中进行的,然后worker进程的主循环是在函数ngx_worker_process_cycle中,流程如下:
worker进程流程图
worker的工作也很简单,基本上上图说明了一切。重点关注几个标志位的意义即可。

参考:

  1. 知乎
  2. nginx启动
  3. nginx开发从入门到精通
  4. 深入理解nginx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章