nginx的工作原理与nginx的配置
1.nginx的工作原理
nginx 的模块直接被编译进nginx ,因此属于静态编译方式。
启动nginx 后,nginx 的模块被自动加载,与Apache 不一样,首先将模块编译为一个so文件,然后在配置文件中指定是否进行加载。
在解析配置文件时,nginx 的每个模块都有可能去处理某个请求,但是同一个处理请求只能由一个模块来完成。
nginx 的进程架构: 启动nginx 时,会启动一个Master 进程,这个进程不处理任何客户端的请求,主要用来产生worker 线程,一个worker 线程用来处理n个request 。
下图展示了nginx 模块一次常规的HTTP请求和响应的过程
下图展示了基本的WEB服务请求步骤
-
建立连接:接收或拒绝连接请求:三次握手的过程 -
接收请求:接收客户端请求报文中对某资源的一次请求的过程,请求报文 -
处理请求 -
访问资源: -
构建响应报文: -
发送响应报文 -
记录日志
2.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模块、可选Http模块、邮件模块、第三方模块和补丁等
- nginx基本模块:所谓基本模块,指的是nginx默认的功能模块,它们提供的指令,允许你使用定义nginx基本功能的变量,在编译时不能被禁用,包括:
- 核心模块:基本功能和指令,如进程管理和安全。常见的核心模块指令,大部分是放置在配置文件的顶部
- 事件模块:在Nginx内配置网络使用的能力。常见的events(事件)模块指令,大部分是放置在配置文件的顶部
- 配置模块:提供包含机制
具体的指令,请参考nginx 的官方文档
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
[root@nginx ~]#
下载nginx
[root@nginx ~]# cd /usr/src
[root@nginx src]# wget http://nginx.org/download/nginx-1.20.1.tar.gz
--2021-10-25 03:47:20-- http://nginx.org/download/nginx-1.20.1.tar.gz
正在解析主机 nginx.org (nginx.org)... 52.58.199.22, 3.125.197.172,
2021-10-25 03:47:26 (196 KB/s) - 已保存 “nginx-1.20.1.tar.gz” [1061461/1061461])
[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 //指定配置文件的路径
-s //发送服务控制信号,可选值有{stop|quit|reopen|reload}
启动nginx
[root@nginx ~]# nginx
[root@nginx ~]# ss -antl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:80 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@nginx ~]#
nginx.conf的内容分为以下几段:
main配置段:全局配置段。其中main配置段中可能包含event配置段 event {}:定义event模型工作特性 http {}:定义http协议相关的配置
5.优化性能的配置参数
worker_processes n; 启动n个worker进程,这里的n为了避免上下文切换,通常设置为cpu总核心数-1或等于总核心数
[root@nginx ~]# cd /usr/local/nginx/conf/
[root@nginx conf]# cp nginx.conf /opt/
[root@nginx conf]# cp mime.types /opt/
[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;
#error_log logs/error.log info;
#pid logs/nginx.pid;
[root@nginx conf]#
[root@nginx ~]# ps -ef |grep nginx
root 215466 1 0 07:29 ? 00:00:00 nginx: master process nginx -c /opt/nginx.conf
nginx 215467 215466 0 07:29 ? 00:00:00 nginx: worker process
nginx 215468 215466 0 07:29 ? 00:00:00 nginx: worker process
nginx 215469 215466 0 07:29 ? 00:00:00 nginx: worker process
nginx 215470 215466 0 07:29 ? 00:00:00 nginx: worker process
root 215983 188055 0 07:29 pts/0 00:00:00 grep --color=auto nginx
[root@nginx ~]#
[root@nginx ~]# nginx -s stop
[root@nginx ~]# nginx
[root@nginx ~]# ps -ef | grep nginx
root 217963 1 0 07:30 ? 00:00:00 nginx: master process nginx
nginx 217964 217963 0 07:30 ? 00:00:00 nginx: worker process
root 218156 188055 0 07:30 pts/0 00:00:00 grep --color=auto nginx
[root@nginx ~]#
#####6. 是否以master/worker方式工作
几乎所有的产品环境下,Nginx都以“一个master进程管理多个worker进程的方式运行的”这种方式工作。
与daemon配置相同,提供master_process配置也是为了方便跟踪调试Nginx。如果用off关闭了master_process方式,就不会fork出worker子进程来处理请求,而是用master进程自身来处理请求。
[root@nginx ~]# nginx -s stop
[root@nginx ~]# nginx
[root@nginx ~]# 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 ~]# ps -ef | grep nginx
root 223600 1 0 07:33 ? 00:00:00 nginx: master process nginx
nginx 223601 223600 0 07:33 ? 00:00:00 nginx: worker process
root 224154 188055 0 07:34 pts/0 00:00:00 grep --color=auto nginx
[root@nginx ~]#
[root@nginx ~]# nginx -s stop;nginx -c /opt/nginx.conf
[root@nginx ~]# 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 ~]# ps -ef |grep nginx
root 215466 1 0 07:29 ? 00:00:00 nginx: master process nginx -c /opt/nginx.conf
nginx 215467 215466 0 07:29 ? 00:00:00 nginx: worker process
nginx 215468 215466 0 07:29 ? 00:00:00 nginx: worker process
nginx 215469 215466 0 07:29 ? 00:00:00 nginx: worker process
nginx 215470 215466 0 07:29 ? 00:00:00 nginx: worker process
root 215983 188055 0 07:29 pts/0 00:00:00 grep --color=auto nginx
[root@nginx ~]#
7.error日志的设置
rror日志是定位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@nginx logs]# 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;
[root@nginx logs]# cat /usr/local/nginx/logs/error.log
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
[root@nginx logs]#
[root@nginx ~]# vim /opt/nginx.conf
[root@nginx ~]# nginx -s stop;nginx -c /opt/nginx.conf
[root@nginx ~]# head /opt/nginx.conf
#user nobody;
worker_processes 4;
#daemon off;
master_process on;
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log logs/error.log info;
[root@nginx ~]# cat /usr/local/nginx/logs/error.log
2021/10/25 07:43:05 [notice] 240568#0: using the "epoll" event method
2021/10/25 07:43:05 [notice] 240568#0: nginx/1.20.1
2021/10/25 07:43:05 [notice] 240568#0: built by gcc 8.5.0 20210514 (Red Hat 8.5.0-3) (GCC)
2021/10/25 07:43:05 [notice] 240568#0: OS: Linux 4.18.0-257.el8.x86_64
2021/10/25 07:43:05 [notice] 240568#0: getrlimit(RLIMIT_NOFILE): 1024:262144
2021/10/25 07:43:05 [notice] 240569#0: start worker processes
2021/10/25 07:43:05 [notice] 240569#0: start worker process 240570
2021/10/25 07:43:05 [notice] 240569#0: start worker process 240571
2021/10/25 07:43:05 [notice] 240569#0: start worker process 240572
2021/10/25 07:43:05 [notice] 240569#0: start worker process 240573
2021/10/25 07:43:07 [info] 240570#0: *1 client closed connection while waiting for request, client: 192.168.100.146, server: 0.0.0.0:80
2021/10/25 07:43:13 [info] 240570#0: *2 client closed connection while waiting for request, client: 192.168.100.146, server: 0.0.0.0:80
[root@nginx ~]#
[root@nginx ~]# vim /opt/nginx.conf
[root@nginx ~]# head /opt/nginx.conf
#user nobody;
worker_processes 4;
#daemon off;
master_process on;
#error_log logs/error.log;
error_log logs/error.log debug;
#error_log logs/error.log notice;
#error_log logs/error.log info;
[root@nginx ~]#
[root@nginx ~]# nginx -s stop;nginx -c /opt/nginx.conf
[root@nginx ~]# cat /usr/local/nginx/logs/error.log
2021/10/25 07:43:05 [notice] 240568#0: using the "epoll" event method
2021/10/25 07:43:05 [notice] 240568#0: nginx/1.20.1
2021/10/25 07:43:05 [notice] 240568#0: built by gcc 8.5.0 20210514 (Red Hat 8.5.0-3) (GCC)
2021/10/25 07:43:05 [notice] 240568#0: OS: Linux 4.18.0-257.el8.x86_64
2021/10/25 07:43:05 [notice] 240568#0: getrlimit(RLIMIT_NOFILE): 1024:262144
略。。。。。。
2021/10/25 07:44:31 [debug] 243044#0: timer delta: 0
2021/10/25 07:44:31 [debug] 243044#0: worker cycle
2021/10/25 07:44:31 [debug] 243044#0: epoll timer: -1
[root@nginx ~]#
8.Nginx配置文件详解
[root@localhost ~]
user www-data;
worker_processes 2;
error_log logs/error.log;
pid logs/nginx.pid;
events {
use epoll;
worker_connections 2048;
keepalive_timeout 60;
client_header_buffer_size 2k;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
server {
listen 80;
server_name domain2.com www.domain2.com;
access_log logs/domain2.access.log main;
location / {
proxy_pass http://127.0.0.1:8000;
deny 192.24.40.8;
allow 192.24.40.6;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
upstream backend_server {
server 192.168.0.1:8000 weight=5;
server 192.168.0.2:8000 weight=1;
server 192.168.0.3:8000;
server 192.168.0.4:8001 backup;
}
server {
listen 80;
server_name big.server.com;
access_log logs/big.server.access.log main;
charset utf-8;
client_max_body_size 10M;
location / {
proxy_pass http://backend_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
|