IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Nginx工作原理,配置 -> 正文阅读

[系统运维]Nginx工作原理,配置

Nginx工作原理,配置

1. 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等进行交互,实现服务代理和负载均衡等功能。

Nginx模块常规的HTTP请求和响应的过程

img

2.Nginx工作原理

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

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

img

3. Nginx的进程模型

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

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

3.1 master进程:管理进程

master进程主要用来管理worker进程,具体包括如下4个主要功能:

  • 接收来自外界的信号。
  • 向各worker进程发送信号。
  • 监控woker进程的运行状态。
  • 当woker进程退出后(异常情况下),会自动重新启动新 的woker进程。

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

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

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

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

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

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

3.2 worker进程:处理请求

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

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

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

  • 接收请求:首先,每个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接受该连接。

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

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

nginx的进程模型,可以由下图来表示:
img

img

4. Nginx配置

nginx常见的配置文件及其作用

配置文件作用
nginx.confnginx的基本配置文件
mime.typesMIME类型关联的扩展文件
fastcgi.conf与fastcgi相关的配置
proxy.conf与proxy相关的配置
sites.conf配置nginx提供的网站,包括虚拟主机

Core functionality (nginx.org)官方参考文档

nginx.conf配置详解

nginx.conf的内容分为以下几段:

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

配置指令:要以分号结尾,语法格式如下:

derective value1 [value2 ...];

支持使用变量:

  • 内置变量:模块会提供内建变量定义
  • 自定义变量:set var_name value

用于调试、定位问题的配置参数

daemon {on|off};    //是否以守护进程方式运行nginx,调试时应设置为off
master_process {on|off};    //是否以master/worker模型来运行nginx,调试时可以设置为off
error_log 位置 级别;    //配置错误日志

error_log里的位置和级别能有以下可选项:

位置级别
file stderr syslog:server=address[,parameter=value] memory:sizedebug:若要使用debug级别,需要在编译nginx时使用–with-debug选项 info notice warn error crit alert emerg

正常运行必备的配置参数

user USERNAME [GROUPNAME];    //指定运行worker进程的用户和组
pid /path/to/pid_file;    //指定nginx守护进程的pid文件
worker_rlimit_nofile number;    //设置所有worker进程最大可以打开的文件数,默认为1024
worker_rlimit_core size;    //指明所有worker进程所能够使用的总体的最大核心文件大小,保持默认即可

优化性能的配置参数

worker_processes n;    //启动n个worker进程,这里的n为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数
worker_cpu_affinity cpumask ...;    //将进程绑定到某cpu中,避免频繁刷新缓存
//cpumask:使用8位二进制表示cpu核心,如:
    0000 0001   //第一颗cpu核心
    0000 0010   //第二颗cpu核心
    0000 0100   //第三颗cpu核心
    0000 1000   //第四颗cpu核心
    0001 0000   //第五颗cpu核心
    0010 0000   //第六颗cpu核心
    0100 0000   //第七颗cpu核心
    1000 0000   //第八颗cpu核心
timer_resolution interval;    //计时器解析度。降低此值,可减少gettimeofday()系统调用的次数
worker_priority number;    //指明worker进程的nice值

事件相关的配置:event{}段中的配置参数

accept_mutex {off|on};    //master调度用户请求至各worker进程时使用的负载均衡锁;on表示能让多个worker轮流地、序列化地去响应新请求
lock_file file;    //accept_mutex用到的互斥锁锁文件路径
use [epoll | rtsig | select | poll];    //指明使用的事件模型,建议让nginx自行选择
worker_connections #;    //每个进程能够接受的最大连接数

网络连接相关的配置参数

keepalive_timeout number;    //长连接的超时时长,默认为65s
keepalive_requests number;    //在一个长连接上所能够允许请求的最大资源数
keepalive_disable [msie6|safari|none];    //为指定类型的UserAgent禁用长连接
tcp_nodelay on|off;    //是否对长连接使用TCP_NODELAY选项,为了提升用户体验,通常设为on
client_header_timeout number;    //读取http请求报文首部的超时时长
client_body_timeout number;    //读取http请求报文body部分的超时时长
send_timeout number;    //发送响应报文的超时时长

nginx配置

//服务控制方式,使用nginx命令
    -t  //检查配置文件语法
    -v  //输出nginx的版本
    -c  //指定配置文件的路径
    -s  //发送服务控制信号,可选值有{stop|quit|reopen|reload}
    
//默认启动nginx时,使用的配置文件是:安装路径/conf/nginx.conf文件
//可以在启动nginx时通过-c选项来指定要读取的配置文件

//worker_processes n; 启动n个worker进程
[root@localhost nginx]# vim conf/nginx.conf
worker_processes  4;
[root@localhost nginx]# sbin/nginx -s reload 
[root@localhost nginx]# ps -ef | grep nginx 
root        2109       1  0 00:31 ?        00:00:00 nginx: master process nginx
nginx     299949    2109  0 03:53 ?        00:00:00 nginx: worker process
nginx     299950    2109  0 03:53 ?        00:00:00 nginx: worker process
nginx     299951    2109  0 03:53 ?        00:00:00 nginx: worker process
nginx     299952    2109  0 03:53 ?        00:00:00 nginx: worker process
root      300290  190531  0 03:54 pts/0    00:00:00 grep --color=auto nginx

//指定配置文件
[root@localhost nginx]# cp conf/nginx.conf /opt/ 
[root@localhost nginx]# cp conf/mime.types /opt/
[root@localhost nginx]# cd /opt/
[root@localhost opt]# ls
ansible.cfg  inventory  mime.types  nginx.conf
[root@localhost opt]# head 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@localhost opt]# nginx -s stop 
[root@localhost opt]# nginx -c /opt/nginx.conf 
[root@localhost opt]# ps -ef | grep nginx 
root      338126       1  0 04:17 ?        00:00:00 nginx: master process nginx -c /opt/nginx.conf
nginx     338127  338126  0 04:17 ?        00:00:00 nginx: worker process
nginx     338128  338126  0 04:17 ?        00:00:00 nginx: worker process
nginx     338129  338126  0 04:17 ?        00:00:00 nginx: worker process
nginx     338130  338126  0 04:17 ?        00:00:00 nginx: worker process
root      338468  190531  0 04:17 pts/0    00:00:00 grep --color=auto nginx

//daemon {on|off};    #是否以守护进程方式运行nginx,调试时应设置为off
[root@localhost opt]# head nginx.conf 

#user  nobody;
worker_processes  4;
daemon off;
error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;

[root@localhost opt]# nginx -s stop ;nginx -c /opt/nginx.conf 

//是否以master/worker方式工作
[root@localhost opt]# vim nginx.conf 
[root@localhost opt]# head nginx.conf 
#user  nobody;
worker_processes  4;
#daemon off;
master_process off;
error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

pid        logs/nginx.pid;
[root@localhost opt]# nginx -s stop ;nginx -c /opt/nginx.conf 
[root@localhost opt]# ps -ef | grep nginx 
root      356124       1  0 04:27 ?        00:00:00 nginx -c /opt/nginx.conf
root      356852  190531  0 04:28 pts/0    00:00:00 grep --color=auto nginx

//error日志的设置
error日志是定位Nginx问题的最佳工具,我们可以根据自己的需求妥善设置error日志的路径和级别。
/path/file参数可以是一个具体的文件,例如,默认情况下是logs/error.log文件,最好将它放到一个磁盘空间足够大的位置;/path/file也可以是/dev/null,这样就不会输出任何日志了,这也是关闭error日志的唯一手段;/path/file也可以是stderr,这样日志会输出到标准错误文件中。
level是日志的输出级别,取值范围是debug、info、notice、warn、error、crit、alert、emerg,从左至右级别依次增大。当设定为一个级别时,大于或等于该级别的日志都会被输出到/path/file文件中,小于该级别的日志则不会输出。例如,当设定为error级别时,error、crit、alert、emerg级别的日志都会输出。
如果设定的日志级别是debug,则会输出所有的日志,这样数据量会很大,需要预先确保/path/file所在磁盘有足够的磁盘空间。
注意 如果日志级别设定到debug,必须在configure时加入–with-debug配置项。

[root@localhost opt]# head nginx.conf 

#user  nobody;
worker_processes  4;
#daemon off;
master_process off;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

pid        logs/nginx.pid;
[root@localhost opt]# cat /usr/local/nginx/logs/error.log 
2021/10/24 23:50:27 [emerg] 166235#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/10/24 23:50:27 [emerg] 166235#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/10/24 23:50:27 [emerg] 166235#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/10/24 23:50:27 [emerg] 166235#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/10/24 23:50:27 [emerg] 166235#0: bind() to 0.0.0.0:80 failed (98: Address already in use)
2021/10/24 23:50:27 [emerg] 166235#0: still could not bind()
.......

[root@localhost opt]# head nginx.conf 
#user  nobody;
worker_processes  4;
#daemon off;
master_process off;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
error_log logs/error.log emerg;
[root@localhost opt]# nginx -s stop ;nginx -c /opt/nginx.conf

5.Web服务器请求资源过程

(1)建立连接 — 接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭。
(2)接收请求 — 从网络中读取一条 HTTP 请求报文。
(3)处理请求 — 对请求报文进行解释,并采取行动。
(4)访问资源 — 访问报文中指定的资源。
(5)构建响应 — 创建带有正确首部的 HTTP 响应报文。
(6)发送响应 — 将响应回送给客户端。
(7)记录事务处理过程 — 将与已完成事务有关的内容记录在一个日志文件中

img


## 5.Web服务器请求资源过程

(1)建立连接 — 接受一个客户端连接,或者如果不希望与这个客户端建立连接,就将其关闭。
(2)接收请求 — 从网络中读取一条 HTTP 请求报文。
(3)处理请求 — 对请求报文进行解释,并采取行动。
(4)访问资源 — 访问报文中指定的资源。
(5)构建响应 — 创建带有正确首部的 HTTP 响应报文。
(6)发送响应 — 将响应回送给客户端。
(7)记录事务处理过程 — 将与已完成事务有关的内容记录在一个日志文件中

在这里插入图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:32:40  更:2021-10-26 12:34:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 21:41:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码