nginx配置文件

本文详细介绍了Nginx的工作原理,包括其模块结构、处理器模块、过滤器模块和代理类模块,以及Nginx的进程模型,重点讨论了单工作进程和多工作进程模式。此外,还讲解了Nginx的Web请求处理机制,对比了多进程、多线程和异步方式。最后,文章介绍了Nginx的安装、配置,特别是配置文件的关键参数,如worker_processes和keepalive_timeout,并提到了HTTPS配置和状态界面的开启。
摘要由CSDN通过智能技术生成

一. Nginx工作原理

Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块:

核心模块:HTTP模块、EVENT模块和MAIL模块

基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块,

第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。

用户根据自己的需要开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。

Nginx的模块从功能上分为如下三类。

Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。

Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。

Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块,这些模块主要与后端一些服务比如FastCGI等进行交互,实现服务代理和负载均衡等功能。

图1-1展示了Nginx模块常规的HTTP请求和响应的过程。

在这里插入图片描述

Nginx本身做的工作实际很少,当它接到一个HTTP请求时,它仅仅是通过查找配置文件将此次请求映射到一个location block,而此location中所配置的各个指令则会启动不同的模块去完成工作,因此模块可以看做Nginx真正的劳动工作者。通常一个location中的指令会涉及一个handler模块和多个filter模块(当然,多个location可以复用同一个模块)。handler模块负责处理请求,完成响应内容的生成,而filter模块对响应内容进行处理。

Nginx的模块直接被编译进Nginx,因此属于静态编译方式。启动Nginx后,Nginx的模块被自动加载,不像Apache,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。在解析配置文件时,Nginx的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。

二. Nginx的进程模型

在工作方式上,Nginx分为单工作进程和多工作进程两种模式。在单工作进程模式下,除主进程外,还有一个工作进程,工作进程是单线程的;在多工作进程模式下,每个工作进程包含多个线程。Nginx默认为单工作进程模式。

Nginx在启动后,会有一个master进程和多个worker进程。

1、master进程:管理进程
master进程主要用来管理worker进程,具体包括如下4个主要功能:
(1)接收来自外界的信号。
(2)向各worker进程发送信号。
(3)监控woker进程的运行状态。
(4)当woker进程退出后(异常情况下),会自动重新启动新的woker进程。

用户交互接口:master进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理worker进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。

重启work进程:我们要控制nginx,只需要通过kill向master进程发送信号就行了。比如kill -HUP pid,则是告诉nginx,从容地重启nginx,我们一般用这个信号来重启nginx,或重新加载配置,因为是从容地重启,因此服务是不中断的。

master进程在接收到HUP信号后是怎么做的呢?

1)、首先master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以光荣退休了。

2)、新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。

直接给master进程发送信号,这是比较传统的操作方式,nginx在0.8版本之后,引入了一系列命令行参数,来方便我们管理。比如,./nginx -s reload,就是来重启nginx,./nginx -s stop,就是来停止nginx的运行。如何做到的呢?我们还是拿reload来说,我们看到,执行命令时,我们是启动一个新的nginx进程,而新的nginx进程在解析到reload参数后,就知道我们的目的是控制nginx来重新加载配置文件了,它会向master进程发送信号,然后接下来的动作,就和我们直接向master进程发送信号一样了。

2、worker进程:处理请求
而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。

worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?

Nginx采用异步非阻塞的方式来处理网络事件,类似于Libevent,具体过程如下:

1)接收请求:首先,每个worker进程都是从master进程fork过来,在master进程建立好需要listen的socket(listenfd)之后,然后再fork出多个worker进程。所有worker进程的listenfd会在新连接到来时变得可读,每个work进程都可以去accept这个socket(listenfd)。当一个client连接到来时,所有accept的work进程都会受到通知,但只有一个进程可以accept成功,其它的则会accept失败。为保证只有一个进程处理该连接,Nginx提供了一把共享锁accept_mutex来保证同一时刻只有一个work进程在accept连接。所有worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。

2)处理请求:当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。

我们可以看到,一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。worker进程之间是平等的,每个进程,处理请求的机会也是一样的。

nginx的进程模型,可以由下图来表示:
在这里插入图片描述
在这里插入图片描述

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

Web服务器和客户端是一对多的关系,Web服务器必须有能力同时为多个客户端提供服务。
在这里插入图片描述

一般来说,完成并行处理请求工作的有三种方式可供选择:多进程方式,多线程方式和异步方式。

多进程方式
多进程方式是指,服务器每当接收到一个客户端时,就由服务器主进程生成一个子进程出来和客户端建立连接进行交互,直到连接断开,该子进程就结束。

多进程方式的优点在于,设计和实现相对简单,各个子进程之间相互独立,处理客户端请求的过程彼此不受到干扰,并且当一个子进程产生问题时,不容易将影响漫延到其他进程中,这保证了提供服务的稳定性。

当子进程退出时,其占用资源会被操作系统回收,也不会留下任何垃圾。而其缺点也是明显的。操作系统中生成一个子进程需要进行内存复制等操作,在资源和时间上会产生一定的额外开销,因此,如果Web服务器接收大量并发请求,就会对系统资源造成压力,导致系统性能下降。

初期的Apache服务器就是采用这种方式对外提供服务的。为了应对大量并发请求,Apache服务器采用“预生成进程”的机制对多线程方式进行了改进。“预生成进程”的工作方式很好理解。

它将生成子进程的时机提前,在客户端请求还没有到来之前就预先生成好,当请求到来时,主进程分配一个子进程和该客户端进行交互,交互完成之后,该进程也不结束,而被主进程管理起来等待下一个客户端请求的到来。

改进的多进程方式在一定程度上缓解了大量并发请求情形下Web服务器对系统资源造成的压力。但是由于Apache服务器在最终的架构设计上采用了多进程方式,因此这不能从根本上解决问题。

多线程方式
多线程方式和多进程方式相似,它是指,服务器每当接收到一个客户端时,会有服务器主进程派生一个线程出来和该客户端进行交互。

由于操作系统产生一个线程的开销远远小于产生一个进程的开销,所以多线程方式在很大程度上减轻了Web服务器对系统资源的要求。

该方式使用线程进行任务调度,开发方面可以遵循一定的标准,这相对来说比较规范和有利于协作。但在线程管理方面,该方式有一定的不足。

多个线程位于同一个进程内,可以访问同样的内存空间,彼此之间相互影响。同时,在开发过程中不可避免地要由开发者自己对内存进行管理,其增加了出错的风险。服务器系统需要长时间连续不停的运转,错误的逐渐积累可能最终对整个服务器产生重大影响。

IIS服务器使用了多线程方式对外提供服务,它的稳定性相对来说还是不错的,但对于经验丰富的Web服务器管理人员而言,他们通常还是会定期检查和重启服务器,以预防不可预料的故障发生。

异步方式
异步方式是和多进程方式及多线程方式完全不同的一种处理客户端请求的方式。在介绍该方式之前,我们先复习一下同步、异步以及阻塞、非阻塞的概念。

网络通信中的同步机制和异步机制是描述通信模式的概念。同步机制,是指发送方发送请求后,需要等待接收到接收方发回的响应后,才接着发送下一个请求。

异步机制,和同步机制正好相反,在异步机制中,发送方发出一个请求后,不等待接收方响应这个请求,就继续发送下个请求。在同步机制中,所有的请求在服务器端得到同步,发送方和接收方对请求的处理步调是一致的。在异步机制中,所有来自发送方的请求形成一个队列,接收方处理完成后通知发送方。

阻塞和非阻塞用来描述进程处理调用的方式,在网络通信中,主要指网络套接字Socket的实质也就是IO操作。

Socket的阻塞调用方式为,调用结果返回之前,当前线程从运行状态被挂起,一定等到调用结果返回之后,才进入就绪状态,获取CPU后继续执行。

Socket的非阻塞调用方式和阻塞调用方式正好相反,在非阻塞方式中,如果调用结果不能马上返回,当前线程也不会被挂起,而是立即返回执行下一个调用。 在网络通信中,经常可以看到有人将同步和阻塞等同、异步和非阻塞等同。事实上,这两对概念有一定的区别,不能混淆。两对概念的组合,就会产生四个新的概念,同步阻塞、异步阻塞、同步非阻塞、异步非阻塞。

同步阻塞方式,发送方接收方发送请求后,一直等待响应。接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。

比如,在超市排队付账时,客户(发送方)向收款员(接收方)付款(发送请求)后需要等待收款员找零,期间不能做其他的事情。而收款员要等待收款机返回结果(IO操作)后才能把零钱取出来交给客户(响应请求),期间也只能等待,不能做其他事情。这种方式实现简单,但是效率不高。

同步非阻塞方式,发送方向接收方发送请求后,一直等待响应。接收方处理请求时进行的IO操作如果补鞥呢马上得到结果,就立刻返回,去做其他事情,但由于没有得到请求处理结果,不响应发送方,发送方一直等待,一直到IO操作完成后,接收方获得结果响应发送方后,接收方才进入下一次请求过程。在实际中不适用这种方式。

异步阻塞方式,发送方向接收方发送请求后,不用等待响应,可以接着进行其他工作。接收方处理请求时进行的IO操作如果不能马上得到结果,就一直等到返回结果后,才响应发送方,期间不能进行其他工作。这种方式在实际中也不使用。

异步非阻塞方式,发送方向接收方发送请求后,不用等待响应,可以继续其他工作。接收方处理请求时进行的IO操作如果不能马上得到结果,也不等待,而是马上返回去做其他事情,当IO操作完成以后,将完成状态和结果通知接收方,接收方再响应发送方。

继续使用在超市排队付账的例子。客户(发送方)向收款员(接收方)付款(发送请求)后在等待收款员找零的过程中,还可以做其他事情,比如打电话、聊天等。

而收款员在等待收款机产生结果后,收款员给客户端结账(响应请求)。在四种方式中,这种方式是发送方和接收方通信效率最高的一种。

Nginx服务器如何处理请求
Nginx服务器的一个显著优势是能够同时处理大量并发请求。它结合多进程机制和异步机制对外提供服务。异步机制使用的是异步非阻塞方式。

Nginx服务器启动后,可以产生一个主进程(master process)和多个工作进程(worker processes),其中可以在配置文件中指定产生的工作进程数量。Nginx服务器的所有工作进程都用于接收和处理客户端的请求。

这类似于Apache使用的改进的多进程机制,预先生成多个工作进程,等待处理客户端请求。

注意
实际上,Nginx服务器的进程模型有两种:Single模型和Master-Worker模型。Single模型为单进程方式,性能较差,一般在实际工作中不使用。

Master-Worker模型实际上被更广泛地称为Master-Slave模型。在Nginx服务器中,充当Slave角色的是工作进程。

每个工作进程使用了异步非阻塞方式,可以处理多个客户端请求。当某个工作进程接收到客户端的请求以后,调用IO进行处理,如果不能立即得到结果,就去处理其他的请求。而客户端在此期间也无需等待响应,可以去处理其他的事情。当IO调用返回结果时,就会通知此工作进程。

该进程得到通知,暂时挂起当前处理的事务,去响应客户端请求。 客户端请求数量增长、网络负载繁重时,Nginx服务器使用多进程机制能够保证不增长对系统资源的压力。

同时使用异步非阻塞方式减少了工作进程在I/O调用上的阻塞延迟,保证了不降低对请求的处理能力。

Nginx服务器的事件处理机制
Nginx服务器的工作进程调用IO后,就去进行其他工作了。当IO调用返回后,会通知工作进程。这里有一个问题,IO调用时如何把自己的状态通知给工作进程的呢?

一般解决这个问题的方案有两种。一是,让工作进程在进行其他工作的过程中间隔一段时间就去检查一下IO的运行状态,如果完成,就去响应客户端,如果未完成就继续正在进行的工作。

而是,IO调用在完成后能主动通知工作进程。对于前者,虽然工作进程在IO调用过程中没有等待,但不断的检查仍然在时间和资源上导致了不小的开销,最理想的解决方案是第二种。

具体来说,select/poll/epoll/kqueue等这样的系统调用就是用来支持第二种解决方案的。

这些系统调用,也被称为时间驱动模型,它们提供了一种机制,让进程可以同时处理多个并发请求,不用关心IO调用的具体状态。IO调用完全由事件驱动模型来管理,事件准备好之后就通知工作进程已经就绪。

3.nginx的安装

//创建用户
[root@localhost ~]# useradd -r -M -s /sbin/nologin nginx
//安装依赖包
[root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++
[root@localhost ~]# yum -y groups mark install 'Development Tools'
创建日志存放目录
[root@nginx ~]# mkdir -p /var/log/nginx
[root@nginx ~]# chown -R nginx.nginx /var/log/nginx
下载nginx
[root@nginx ~]# cd /usr/src
[root@nginx src]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
[root@nginx src]# 
[root@nginx src]# ls
debug                zabbix-5.4.4
kernels              zabbix-5.4.4.tar.gz
nginx-1.20.1.tar.gz
[root@nginx src]# 
//编译安装
[root@nginx src]# tar xf nginx-1.20.1.tar.gz 
[root@nginx src]# cd nginx-1.20.1
[root@nginx nginx-1.20.1]# ./configure \
> --prefix=/usr/local/nginx \
> --user=nginx \
> --group=nginx \
> --with-debug \
> --with-http_ssl_module \
> --with-http_realip_module \
> --with-http_image_filter_module \
> --with-http_gunzip_module \
> --with-http_gzip_static_module \
> --with-http_stub_status_module \
> --http-log-path=/var/log/nginx/access.log \
> --error-log-path=/var/log/nginx/error.log
[root@nginx nginx-1.20.1]# make && make install

4.nginx的配置

配置环境变量

[root@nginx ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
[root@nginx ~]# . /etc/profile.d/nginx.sh
[root@nginx ~]# 
//服务控制方式,使用nginx命令
    -t  //检查配置文件语法
    -v  //输出nginx的版本
    -c  //指定配置文件的路径

ginx.conf配置详解
nginx.conf的内容分为以下几段:

main配置段:全局配置段。其中main配置段中可能包含event配置段
event {}:定义event模型工作特性
http {}:定义http协议相关的配置

5.优化性能的配置参数

worker_processes n; 启动n个worker进程,这里的n为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数

[root@nginx conf]# head /opt/nginx.conf 

#user  nobody;
worker_processes  4;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

[root@nginx conf]# 
[root@nginx conf]# head /usr/local/nginx/conf/nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#er
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值