nginx工作原理、配置以及web服务器的资源请求过程

nginx简介

Nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由俄罗斯的伊戈尔·赛索耶夫开发的,第一个公开版本0.1.0于2004年10月10日。

源代码以类BSD许可证的形式发布,因其稳定性、丰富的功能集、简单的功能集、简单的配置文件和低级系统的消耗而闻名。2011年6月1日,nginx1.0.4发布

Nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like协议下发行。其特点是内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、腾讯、淘宝、京东等。

nginx的特性与优点

nginx的特性

nginx是一个很牛的高性能Web和反向代理服务器,它具有很多非常优越的特性:

  • 在高连接并发的情况下,nginx是Apache服务器不错的替代品,能够支持高达50000个并发连接数的响应
  • 使用epoll and kqueue作为开发模型
  • nginx作为负载均衡服务器:nginx既可在内部直接支持和PHP程序对外进行服务,也可支持作为HTTP代理服务器对外进行服务
  • nginx采用C进行编写,不论系统资源开销还是CPU使用效率都比Perlbal要好很多
nginx的优点
  • 高并发连接:官方测试能够支撑5万并发连接,在实际生产环境中跑到2-3万并发连接数

  • 内存消耗少:在3万并发连接下,开启的10个nginx进程才消耗150M内存(15M*10=150M)

  • 配置文件非常简单:风格跟程序一样通俗易懂

  • 成本低廉:nginx为开源软件,可以免费使用。而购买F5 BIG-IP、NetScaler等硬件负载均衡交换机则需要十多万至几十万人民币

  • 支持Rewrite重写规则:能够根据域名、URL的不同,将HTTP请求分到不同的后端服务器群组

  • 内置的健康检查功能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端访问

  • 节省带宽:支持GZIP压缩,可以添加浏览器本地缓存的Header头

  • 稳定性高:用于反向代理,宕机的概率微乎其微

  • 模块化设计:模块可以动态编译

  • 外围支持好:文档全,二次开发和模块较多

  • 支持热部署:可以不停机重载配置文件

  • 支持事件驱动、AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化

nginx工作原理

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

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

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

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

Nginx的模块从功能上分为如下三类:
  • Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息操作。handlers处理器模块一般只能有一个。

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

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

#######nginx进程架构
nginx的进程架构
启动nginx时,会启动一个master进程,这个进程不处理任何客户端的请求,主要用来产生worker线程,一个worker线程用来处理n个request。
而worker线程的线程数可以根据自己的需求来进行配置

[root@localhost conf]# pwd
/usr/local/nginx/conf
[root@localhost conf]# vim nginx.conf
3 worker_processes  1;  //这个地方就是用来设置worker进程个数的
[root@localhost conf]# vim nginx.conf
3 worker_processes  3;

[root@localhost conf]# systemctl restart nginx.service 
[root@localhost conf]# ps -ef | grep nginx
root     119118      1  0 18:29 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx    119120 119118  0 18:29 ?        00:00:00 nginx: worker process
nginx    119121 119118  0 18:29 ?        00:00:00 nginx: worker process
nginx    119122 119118  0 18:29 ?        00:00:00 nginx: worker process

图解:首先用户通过http/https协议访问nginx的主机,这时nginx会启动一个master进程,这个进程,不处理客户端的请求,而是生成worker线程(这里是一个负载均衡集群),通过worker线程来处理客户端的请求,若用户请求网站服务,worker就会到web server这个服务集群提取对应的资源给客户端,同理,这个Application server可以用来访问应用服务器,Memcached缓存服务器,backup是后端的意思。


web服务器请求资源的过程

1.客户端发起请求,然后与服务端建立tcp连接
2.服务器接收请求
3.进行反向代理,然后服务器处理请求
4.查看访问资源的类型(可能是本地的资源,也可能是通过NFS挂载的资源)
5.构建响应报文
6.通过网络接口返回响应报文给客户端
7.服务端将本次的操作记录到日志中

图解:首先客户端要与服务端建立连接(没有连接就无法从服务端获取想要的资源)我们访问的时候都是通过域名去访问服务端的,而域名是可以通过DNS将IP解析成域名去访问的,所以实际上是访问的服务器的IP。
接收客户端请求报文中记录了对某资源的一次请求的过程;服务器对请求报文进行解析,并获取请求的资源及请求方法等相关信息,根据方法,资源,首部和可选的主体部分对请求进行处理;处理完成个之后就去对象存储里去取相应的资源,取到之后构建一个响应报文;然后将客户请求的资源进行封装,并通过网络接口发送响应报文,客户端收到对应的资源之后,web服务器会在日志文件中添加一个条目,来描述已执行的事务。


单进程I/O模型:启动一个进程处理用户请求,而且一次只处理一个,多个请求被串行响应;
多进程I/O模型:并行启动多个进程,每个进程响应一个连接请求;
复用I/O结构:启动一个进程,同时响应N个连接请求
复用的多进程I/O模型:启动x个进程,每个进程响应y个连接请求,同时接收x*y个请求。

nginx的配置

nginx的编译分为两种:

  • 静态编译:静态编译就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(so)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库,所以其优缺点与动态编译的可执行文件正好互补
  • 动态编译:动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令。

所以其优点一方面是缩小了执行文件本身的体积,另一方面是加快了编译速度,节省了系统资源。

缺点是:哪怕是很简单的程序,只用到了链接库中的一两条命令,也需要附带一个相对庞大的链接库;二是如果其他计算机上没有安装对应的运行库,则用动态编译的可执行文件就不能运行。

nginx的安装与配置

下载nginx的源码包
想要安装不同的版本可以取官网下载:https://nginx.org/en/download.html

[root@localhost ~]# wget http://nginx.org/download/nginx-1.20.1.tar.gz

解决nginx的依赖

[root@localhost ~]# yum -y install pcre-devel openssl openssl-devel gd-devel gcc gcc-c++ zlib make

解压nginx的tar包

[root@localhost ~]# tar -xzf nginx-1.20.1.tar.gz -C /usr/local

创建系统用户

[root@localhost ~]# useradd -r -M -s /sbin/nologin nginx

创建日志存放目录

[root@localhost ~]# mkdir -p /var/log/nginx
[root@localhost ~]# chown -R nginx.nginx /var/log/nginx

编译安装nginx

[root@localhost 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@localhost nginx-1.20.1]# make && make install

配置nginx环境变量

[root@localhost ~]# echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh

[root@localhost ~]# source /etc/profile.d/nginx.sh

配置nginx的service文件使用systemctl控制nginx

[root@localhost system]# pwd
/usr/lib/systemd/system

[root@localhost system]# cat > nginx.service << EOF
[Unit]
Description=Nginx server daemon
After=network.target 

[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx 
ExecStop=/usr/local/nginx/sbin/nginx -s quit
ExecReload=/bin/kill -HUP \$MAINPID

设置开机自启

[root@localhost system]# systemctl enable --now nginx

nginx主目录下各个目录的作用

/usr/local/nginx/         #为服务安装目录,若你安装在/opt目录下则是/opt/nginx,根据你安装的不同目录也不同
/usr/local/nginx/sbin  #为服务主程序目录
/usr/local/nginx/sbin/nginx  #为服务程序文件
/usr/local/nginx/modules/  #为模块目录
/usr/local/nginx/conf/  #为服务的配置文件目录
/usr/local/nginx/html/  # 为服务网页根目录
/usr/local/nginx/conf/nginx.conf  #为服务配置文件
/usr/local/nginx/logs/  #为服务日志文件目录
/usr/local/nginx/logs/nginx.pid  #服务pid文件
/usr/local/nginx/logs/error.log  #服务错误日志文件
/usr/local/nginx/logs/access.log  #服务访问日志文件

nginx服务命令

/usr/local/nginx/sbin/nginx 启动nginx
/usr/local/nginx/sbin/nginx -v  #查看nginx版本
/usr/local/nginx/sbin/nginx -V  #显示除版本信息意外的其他配置参数信息
/usr/local/nginx/sbin/nginx -t  #检查nginx配置文件是否正确
/usr/local/nginx/sbin/nginx -s reload  #重新加载nginx
/usr/local/nginx/sbin/nginx -s quit #正常关闭nginx,建议使用这种方式关闭nginx,这个是优雅的关闭nginx
/usr/local/nginx/sbin/nginx -s stop  #快速关闭nginx
/usr/local/nginx/sbin/nginx -c //用来指定配置文件的路径

nginx的配置文件详解

主配置文件默认位置:/usr/local/nginx/conf/nginx.conf //在不指定安装路径的情况下

  • 默认启动nginx时,使用的配置文件是:安装路径/conf/nginx.conf文件
  • 可以在启动nginx时通过-c选项来指定要读取的配置文件

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

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

nginx.conf配置详解

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

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

配置指令的语法格式

derective value1 [value2 ...];

支持使用变量:

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

检查nginx配置文件的语法cuowu

[root@localhost conf]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

查看nginx的版本信息

[root@localhost conf]# nginx -v
nginx version: nginx/1.20.1

[root@localhost conf]# nginx -V   //-V不仅能看到nginx的版本信息,还能看到编译nginx时编译了那些功能等信息
nginx version: nginx/1.20.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --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

使用nginx服务控制命令重启并指定配置文件路径

[root@localhost conf]# pwd
/usr/local/nginx/conf

[root@localhost conf]# cp nginx.conf mime.types /opt/
[root@localhost conf]# cd /opt/
[root@localhost opt]# ls
mime.types  nginx.conf  nginx.sh  packages
 
[root@localhost opt]# head -3 nginx.conf 

#user  nobody;
worker_processes  1;

[root@localhost opt]# nginx -s quit ; nginx -c /usr/local/nginx/conf/nginx.conf

[root@localhost opt]# head -3 /usr/local/nginx/conf/nginx.conf

#user  nobody;
worker_processes  3;

[root@localhost opt]# ps -ef | grep nginx
root      42776      1  0 11:00 ?        00:00:00 nginx: master process nginx -c /usr/local/nginx/conf/nginx.conf
nginx     42777  42776  0 11:00 ?        00:00:00 nginx: worker process
nginx     42778  42776  0 11:00 ?        00:00:00 nginx: worker process
nginx     42779  42776  0 11:00 ?        00:00:00 nginx: worker process
root      43003   1358  0 11:00 pts/0    00:00:00 grep --color=auto nginx

[root@localhost opt]# nginx -s quit ; nginx -c /opt/nginx.conf
[root@localhost opt]# ps -ef | grep nginx
root      45058      1  0 11:02 ?        00:00:00 nginx: master process nginx -c /opt/nginx.conf
nginx     45059  45058  0 11:02 ?        00:00:00 nginx: worker process
root      45134   1358  0 11:02 pts/0    00:00:00 grep --color=auto nginx
用于调试,定位问题的配置参数

是否以守护进程方式运行Nginx
守护进程(daemon)是脱离终端并且在后台运行的进程。它脱离终端是为了避免进程执行过程中的信息在任何终端上显示,这样一来,进程也不会被任何终端所产生的信息所打断。Nginx毫无疑问是一个需要以守护进程方式运行的服务,因此,默认都是以这种方式运行的。

不过Nginx还是提供了关闭守护进程的模式,之所以提供这种模式,是为了方便跟踪调试Nginx,毕竟用gdb调试进程时最烦琐的就是如何继续跟进fork出的子进程了。

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

用法:
Syntax: daemon on | off;   //语法
Default: daemon on;        //默认值
Context:    main           //可以配置在那个字段中
[root@localhost conf]# head -4 nginx.conf

#user  nobody;
worker_processes  3;
daemon off

[root@localhost conf]# systemctl restart nginx.service
// 此时nginx将不会以守护进程的方式运行,会一直占据着前台屏幕  

master_process {on|off}; //是否以master/worker模型来运行nginx,调试时可以设置为off

//用法
Syntax: master_process on | off;
Default:  master_process on;
Context:  main

// nginx默认是以master/worker模型来运行
[root@localhost opt]# head -4 nginx.conf 

#user  nobody;
worker_processes  1;
master_process off;

//重新读取nginx配置文件
[root@localhost opt]# systemctl stop nginx.service ; nginx -c /opt/nginx.conf 
[root@localhost opt]# ps -ef | grep nginx
root      13256      1  0 11:47 ?        00:00:00 nginx -c /opt/nginx.conf
root      13466   1358  0 11:47 pts/0    00:00:00 grep --color=auto nginx

error_log 位置 级别; //配置错误日志

//用法,在不同的字段有不同的含义,比如在main字段写就会对整个nginx产生影响,在http字段写就会对某个网站产生影响

Syntax: error_log file [level];
Default: error_log logs/error.log error;
Context:  main, http, mail, stream, server, location

[root@localhost opt]# head -4 nginx.conf 

#user  nobody;
worker_processes  1;
error_log  logs/error.log;

重启nginx服务让配置文件生效
[root@localhost opt]# systemctl stop nginx; nginx -c /opt/nginx.conf

[root@localhost opt]# ls /usr/local/nginx/logs/
error.log  nginx.pid

[root@localhost opt]# ls /usr/local/nginx/logs/
error.log  nginx.pid
[root@localhost opt]# curl http://192.168.182.131/sx.txt

404 Not Found

404 Not Found


nginx/1.20.1
[root@localhost opt]# cat /var/log/nginx/error.log 2021/10/25 17:18:19 [error] 10117#0: *1 open() "/usr/local/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.182.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.182.131", referrer: "http://192.168.182.131/" 2021/10/25 18:29:13 [notice] 119113#0: signal process started 2021/10/25 18:33:46 [notice] 124307#0: signal process started 2021/10/25 19:29:31 [notice] 56895#0: signal process started 2021/10/26 10:53:47 [notice] 35176#0: signal process started 2021/10/26 10:53:47 [notice] 35188#0: signal process started 2021/10/26 10:57:44 [notice] 39890#0: signal process started 2021/10/26 10:57:44 [notice] 39893#0: signal process started

error_log里的位置和级别能有以下可选项:
位置 | 级别
file | 记录到某个文件中
stdree | 记录到标准错误中(不推荐)
syslog:server=address[,parameter=value] | 记录到某台日志服务器中
memory:size | 记录到内存中(不推荐)

日志级别 含义
debug 若要使用debug级别,需要在编译nginx时使用–with-debug选项
info 一般信息
notice 不影响正常功能,需要注意的消息
warn 可能影响系统功能,需要提醒用户的重要事件
error 错误信息(常用的)
cuit 紧急,比较严重的
alert 必须马上处理的
emerg 会导致系统不可用的

正常运行必备的配置参数

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

你可能感兴趣的:(nginx工作原理、配置以及web服务器的资源请求过程)