一、nginx的组成
1.nginx二进制可执行文件 (由各模块源码编译出来的一个文件)
2.nginx.conf配置文件(主要控制nginx的行为)
3.access.log访问日志(记录每一条http请求信息)
4.error.log错误日志(用于定位问题的日志模块)
此外nginx 分为openresty 商业版(nginx.com)和开源版(nginx.org)
二、nginx的基本模块
Nginx的核心模块包括内核模块和事件驱动模块,即CoreModule和EventsModule;另外还有第三方模块HTTP内核模块即HttpCoreModule,它是Nginx服务器的核心模块。CoreModule和EventsModule模块的配置相对于HttpCoreModule会少一些,但是它们的配置将会影响系统的性能,而非功能上的差异。
1、CoreModule用于控制Nginx服务器的基本功能;
2、EventsModule用于控制Nginx如何处理连接。该模块的指令的一些参数会对应用系统的性能产生重要的影响;
3、HttpCoreModule提供HTTP访问Nginx服务器。
nginx将各功能模块组织成一条链,当有请求到达的时候,请求依次经过这条链上的部分或者全部模块进行处理。每个模块实现特定的功能。例如,实现对请求解压缩的模块、实现SSI的模块、实现与上游服务器进行通讯的模块、实现与FastCGI服务进行通讯的模块。
模块分三类:1、核心模块;2、辅助模块;3、第三方模块
根据官方文档排版,辅助模块还分了以下几类:1、http;2、mail;3、stream,而根据其功能可以分成这几大类:
一、handler模块
此类型的模块也被直接称为handler模块。主要负责处理客户端请求并产生待响应内容,比如ngx_http_static_module模块,负责客户端的静态页面请求处理并将对应的磁盘文件准备为响应内容输出。
二、filter模块
过滤响应头和内容的模块,可以对回复的头和内容进行处理。它的处理时间在获取回复内容之后,向用户发送响应之前。
三、upstream模块
upstream模块实现反向代理的功能,将真正的请求转发到后端服务器上并从后端服务器上读取响应,发回客户端。upstream模块是一种特殊的handler,只不过响应内容不是真正由自己产生的,而是从后端服务器上读取。
四、load balance模块
负载均衡模块,实现特定的算法,在众多的后端服务器中,选择一个服务器出来作为某个请求的转发服务器。
Nginx对于网络请求是有Connection和Request的概念和封装的。
Nginx的源码组织架构是模块化的,不同的模块实现不一样的职责。
三、nginx内部进程模型
Nginx是以多进程的方式来工作的,当然Nginx也是支持多线程的方式的,只是主流的还是多进程的方式。这也是Nginx的默认方式。master进程主要负责读取和评估配置,并维护worker进程。Nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控 worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是在worker进程中处理。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的,需要注意的是,每个Worker只有主线程,即所谓的单线程。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的数量在配置文件中定义,可以指定一个固定值,也可以根据可用CPU内核的数量自动调整,一般我们会设置与机器CPU核数一致,这里面的原因与Nginx的进程模型以及事件处理模型是分不开的。nginx为更好的利用多核特性,提供了cpu亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。更多的worker数,只会导致进程来竞争cpu资源。nginx及其模块的工作方式由配置文件决定。默认情况下,配置文件的名字叫nginx.conf。并且所在位置是/usr/local/nginx/conf, /etc/nginx, 或/usr/local/etc/nginx 。
Nginx在启动时,会解析配置文件,得到需要监听的端口与IP地址,然后在Nginx的master进程里面,先初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的IP地址端口,再listen),然后再fork(一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程 )出多个子进程出来,然后子进程会竞争accept新的连接。 此时,客户端就可以向Nginx发起连接了。当客户端与Nginx进行三次握手,与Nginx建立好一个连接后,某一个子进程会accept成功,得到这个建立好的连接的socket,然后创建Nginx对连接的封装,即ngx_connection_t结构体。 接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换。
最后,Nginx或客户端来主动关掉连接,到此,一个连接就寿终正寝了。
四、事件模型
Nginx对于事件,以异步非阻塞方式来实现。
异步和非异步,阻塞和非阻塞是两组不同的概念,前者更多对于应用程序而言,而后者更多对于CPU而言。
1、异步:执行一个动作之后,可以去操作别的操作,然后等待通知再回来执行刚才没执行完的操作。
2、非异步(同步):执行一个操作之后,等待结果,然后才继续执行下面的操作。
3、阻塞:给CPU传达任务之后,一直等待CPU处理完毕(即使会产生I/O),然后才执行后面的操作。
4、非阻塞:给CPU传达任务之后,继续处理后面的操作,隔段时间再来询问之前的操作是否完成。这样的过程也叫轮询。
Nginx的异步非阻塞方式,具体到系统调用的话就像select/poll/epoll/kqueue这样的系统调用。它们提供了一种机制,让你可以同时监控多个事件,调用他们是阻塞的但可以设置超时时间,在超时时间之内如果有事件准备好了就返回。
五、Nginx处理http请求
在nginx中我们指http请求,具体到nginx中的数据结构是ngx_http_request_t。它是对一个http请求的封装,nginx通过ngx_http_request_t来保存解析请求与输出响应相关的数据。
一个http请求,包含请求行、请求头、请求体、响应行、响应头、响应体。
一般性的网络请求处理过程:
1、客户端发送一个请求;
2、然后我们读取一行数据,分析出请求行中包含的method、uri、http_version信息。
3、然后再一行一行处理请求头,并根据请求method与请求头的信息来决定是否有请求体以及请求体的长度,然后再去读取请求体。
4、得到请求后,我们处理请求产生需要输出的数据,然后再生成响应行,响应头以及响应体。
5、最后将响应发送给客户端,一个完整的请求就处理完成了。
Nginx处理请求过程:nginx处理一个请求的抽象概念过程:
1、request 请求进来
2、初始化HTTP Request, 生成 HTTP Request对象
3、处理请求头
4、处理请求体
5、调用与此请求关联的handler(根据你URL或者Location配置)
6、依次调用各阶段handler进行处理
7、获取location配置
8、产生适当的响应
9、发送response header
10、发送response body
六、nginx配置文件的结构
nginx由配置文件中的指令所控制的模块组成。指令分为简单指令和块指令。简单指令由名称和参数组成,它们之间用空格隔开,以分号;结束。块指令的结构与简单指令相同,但它不是以分号结尾,而是一组由大括号{ 和 }包围的附加指令。如果一个block指令可以在大括号中包含其他指令,那么它被称为上下文(例如:events, http, server 和 location)。events 和 http 指令在main上下文中,server指令在http中,location在server中。
Nginx是支持热部署的,也就是说当我们修改配置文件后,不用关闭Nginx,就可以实现让配置生效。
nginx常用做静态内容服务器和代理服务器,直面外来请求然后转发给后面的应用服务器(tomcat,django等)。
nginx的配置系统由一个主配置文件和其他一些辅助配置文件构成。这些配置文件均是纯文本文件,全部位于nginx安装目录下的conf目录下。
指令由nginx的各个模块提供,不同的模块会提供不同的指令来实现配置。
nginx.conf中的配置信息,根据其逻辑上的意义,对它们进行了分类,也就是分成了多个作用域,或者称之为配置指令上下文。不同的作用域含有一个或者多个配置项。
nginx.conf:Nginx 的基本配置文件
mime.types:MIME 类型关联的扩展文件
fastcgi.conf:与 fastcgi相关的配置
proxy.conf:与proxy相关的配置
sites.conf:配置Nginx提供的网站,包括虚拟主机。
nginx中只有一个nginx.conf主配置文件,其他的自定义的配置都可以通过include proxy.conf;
命令引入。
nginx.conf 配置文件主要分成四个部分:
main,全局设置,影响其它部分所有设置
server,主机服务相关设置,主要用于指定虚拟主机域名、IP 和端口
location,URL匹配特定位置后的设置,反向代理、内容篡改相关设置
upstream,上游服务器设置,负载均衡相关配置
他们之间的关系:server继承main,location继承server;upstream既不会继承指令也不会被继承。