理解Nginx

Posted by AceKei on November 1, 2019

1. Nginx 是什么

Nginx官网说明
nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.
nginx [engine x]是HTTP和反向代理服务器,邮件代理服务器和通用TCP / UDP代理服务器,最初由Igor Sysoev编写。

2. 安装

基于centOS7 安装

直接一键安装

1
yum -y install nginx

ps:可能出现的问题

1
2
没有可用软件包 nginx。
错误:无须任何处理

这个时候是因为 nginxyum 里面是没有的,需要使用到 epel源 ,也就是安装 epel-release

1
yum install epel-release

安装成功后再安装 nginx

3.启动Nginx

1
[root@wsk1103 nginx]# systemctl start nginx

默认端口为 80 ,打开浏览器,访问 localhost,出现 NGINX 页面表示启动成功

关于 nginx 命令

1
2
3
4
5
6
7
8
9
10
11
12
systemctl enable nginx         开机启动nginx服务
systemctl disable nginx         禁止开机启动nginx服务
systemctl is-enable nginx      查询是否开机启动nginx服务
systemctl start nginx              启动nginx服务
systemctl stop nginx              停止nginx服务
systemctl reload nginx            重新加载nginx服务
systemctl restart nginx            重启nginx服务
systemctl status nginx             查看nginx服务状态

或者 将 systemctl 替换成 service
service nginx start             启动nginx服务
service nginx stop                停止nginx服务

4. 文件说明

安装完成后,配置文件 nginx.conf 位于 /etc/nginx/nginx.conf

1
2
3
4
5
6
7
8
[root@wsk1103 yum.repos.d]# cd /etc/nginx/
[root@wsk1103 nginx]# ls
conf.d                  koi-utf             scgi_params
default.d               koi-win             scgi_params.default
fastcgi.conf            mime.types          uwsgi_params
fastcgi.conf.default    mime.types.default  uwsgi_params.default
fastcgi_params          nginx.conf          win-utf
fastcgi_params.default  nginx.conf.default
1. nginx.conf,nginx.conf.default

主要的配置文件

2. conf.d,default.d

空的文件夹

3. fastcgi.conf, fastcgi.conf.default,fastcgi_params,fastcgi_params.default

fastcgi例子
Nginx 配置Fastcgi解析时会调用fastcgi_params配置文件来传递服务器变量,这样CGI中可以获取到这些变量的值。
这允许我们使单个的FCGI配置尽可能的简单。我们可以根据实际的路径替换 SCRIPT_FILENAMEDOCUMENT_ROOT 里面的 $document_root$ document_root 变量是硬编码的,可能无法随着我们的安装(通常会报“找不到脚本”的错误)。如果要使用NGINX +虚拟主机+ PHP,我们应该省略 SCRIPT_NAME 变量,以便 PHP 选择正确的 DOCUMENT_ROOT

4. koi-utf,koi-win,win-utf

这三个文件都是与编码转换映射文件,用于在输出内容到客户端时,将一种编码转换到另一种编码。

5. uwsgi_params,scgi_params

fastcgi_params 一样,传递哪些服务器变量,只有前缀不一样,以 uwsgi_param 开始而非 fastcgi_param

6. mime.types,mime.types.default

文件扩展名与文件类型映射表,Nginx 根据映射关系,设置http请求响应头的Content-Type值。当在映射表找不到时,使用nginx.conf中default-type指定的默认值。
默认配置中的指定的default-type为application/octet-stream。

1
2
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

访问日志路径 和 错误日志路径

1
[root@wsk1103 wsk]# cd /var/log/nginx/

里面有日志 access.log(接收日志) 和 error.log(错误处理日志)

5. 正向代理和反向代理

5.1. 反向代理

指服务器以代理服务器的形式,将接受到的网络请求转发到内部的其他服务器上,并从该内部服务器将响应结果返回给网络请求,这个时候请求者只知道代理服务器的IP地址,而不知道真正的服务器地址,防止真正的服务器受到不必要的攻击。

image

反向代理的好处
  • 保护真正的后台服务器,使黑客不知道真正的服务器的IP地址。
  • 通过缓存静态资源,加速Web请求。
  • 实现负载均衡。

5.2. 正向代理

正向代理服务器,一个位于客户端和后台服务器之间的服务器,为了从后台服务器取得内容,客户端向代理发送一个请求并指定目标(后台服务器),然后代理向后台服务器转交请求并将获得的内容返回给客户端。

image

6. Nginx 配置文件

配置文件目录

1
[root@wsk1103 ~]# vi /etc/nginx/nginx.conf

文件说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

#定义 nginx 运行的用户和用户组
user nginx;

#nginx 进程数,建议设置为等于 CPU 总核心数。
#worker_processes auto这个是不建议的,最好是设置成固定数值
worker_processes auto;

#nginx 默认没有开启利用多核 CPU, 通过增加 worker_cpu_affinity 配置参数来充分利用多核 CPU 以下是 8 核的配置参数
#这个配置用于将 worker process 与指定 CPU 核绑定,降低由于多 CPU 核切换造成的寄存器等重建带来的性能损耗。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

#所有错误输出的日志位置
error_log /var/log/nginx/error.log;

#进程文件
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
#nginx启动时会优先加载这个目录下的所有 .conf 文件
#该目录里面的文件 mod-http-image-filter.conf  mod-http-perl.conf  mod-http-xslt-filter.conf  mod-mail.conf  mod-stream.conf
include /usr/share/nginx/modules/*.conf;

events {
    #单个后台 worker process 进程的最大并发链接数
    worker_connections 1024;
}

http {
    # 写入日志文件的日志格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    # 访问日志记录位置
    access_log  /var/log/nginx/access.log  main;

    #开启高效文件传输模式,sendfile 指令指定 nginx 是否调用 sendfile 函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘 IO 重负载应用,可设置为 off,以平衡磁盘与网络 I/O 处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成 off。
    sendfile            on;
    
    #防止网络阻塞
    tcp_nopush          on;
    
    #防止网络阻塞
    tcp_nodelay         on;
    
    #开启目录列表访问,适合下载服务器,默认关闭。
    autoindex on; 
    
    ##连接客户端超时时间各种参数设置##
    #单位是秒,客户端连接时时间,超时之后服务器端自动关闭该连接 如果 nginx 守护进程在这个等待的时间里,一直没有收到浏览发过来 http 请求,则关闭这个 http 连接
    keepalive_timeout   65;
    #客户端请求头的超时时间
    client_header_timeout 10;    
    #客户端请求主体超时时间
    client_body_timeout 10;   
    #关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间
    reset_timedout_connection on; 
    #客户端响应超时时间,在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,nginx 就会关闭连接
    send_timeout 10;      
    
    #FastCGI 相关参数是为了改善网站的性能:减少资源占用,提高访问速度。
    #Nginx 的 buffer 机制,对于来自 FastCGI Server 的 Response,Nginx 将其缓冲到内存中,然后依次发送到客户端浏览器。缓冲区的大小由 fastcgi_buffers 和 fastcgi_buffer_size 两个值控制。
    #连接超时
    fastcgi_connect_timeout 300;
    #发生超时
    fastcgi_send_timeout 300;
    #读取超时
    fastcgi_read_timeout 300;
    #缓存区大小
    fastcgi_buffer_size 8k;
    #控制 nginx 最多创建 4 个大小为 8K 的缓冲区
    fastcgi_buffers 4 8k;
    ##默认值是fastcgi_buffer的2倍
    fastcgi_busy_buffers_size 16k;
    #写入缓存文件使用多大的数据块,默认值是fastcgi_buffer的2倍
    fastcgi_temp_file_write_size 16k;
    
    #影响散列表的冲突率。types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。
    types_hash_max_size 2048;
    #服务器名字的 hash 表大小
    server_names_hash_bucket_size 128; 
    
    #上传文件大小限制
    client_header_buffer_size 1k; 
    #设定请求缓,一般来说默认就够了。发生414 (Request-URI Too Large) 错误时请增大这两个参数。
    large_client_header_buffers 4 8k; 
    #客户端上传的body的最大值。超过最大值就会发生413(Request Entity Too Large)错误。默认为1m,最好改大一点。
    client_max_body_size 8m; 
    
    #对传输文件压缩-gzip 模块设置
    #开启 gzip 压缩输出
    gzip on; 
    #最小压缩文件大小
    gzip_min_length 1k; 
    #压缩缓冲区
    gzip_buffers 4 16k; 
    #压缩版本
    gzip_http_version 1.1; 
    #压缩等级,gzip 压缩比,1 为最小,处理最快;9 为压缩比最大,处理最慢,传输速度最快,也最消耗 CPU;
    gzip_comp_level 2; 
    #压缩类型,默认就已经包含  application/xml; text/html
    gzip_types text/plain application/x-javascript text/css
    gzip_vary on;
    
    #文件扩展名与文件类型映射表
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    upstream wsk1103.github.io {
        #upstream 的负载均衡,weight 是权重,可以根据机器配置定义权重。weigth 参数表示权值,权值越高被分配到的几率越大。
        #另外还有 ip_hash 轮训
        server 192.168.134.2 weight=1;
        server 192.168.134.3 weight=2;
        server 192.168.134.4 weight=3;
    }

    #虚拟主机的配置
    server {
        #监听端口,默认服务
        listen *:80 | *:8000; # 监听所有的 80 和 8000 端口
        #域名可以有多个,用空格隔开
        server_name  wsk1103.github.io wsk1103.github.com;
        #server_name .wsk1103.com  www.wsk1103.  wsk1103.*; # 使用通配符
        #server_name ~^w{3}.wsk1103.com$; # 使用正则
        #配置中,可以用正则的地方,都以~开头
        # 当匹配到多个时,处理优先级
        # 1. 准确匹配到 server_name
        # 2. 通配符在开始时匹配到 server_name
        # 3. 通配符在结尾时匹配到 server_name
        # 4. 正则表达式匹配 server_name
        # 5. 顺序加载
        
        index index.html index.htm index.php;
        root         /usr/share/nginx/html;
        # 访问 localhost 时,重定向到 https://wsk1103.github.io
        rewrite ".*" https://wsk1103.github.io;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        
        # location 的4种匹配模式,匹配优先级 ‘ = > 其他 ’
        # 1. = :用于标准 uri前,要求请求字符串与其严格匹配,成功则立即处理
        # 2. ^~ :用于标准 uri前,并要求一旦匹配到,立即处理,不再去匹配其他的正则 uri
        # 3. ~ :用于正则 uri前,表示 uri 包含正则表达式,并区分大小写
        # 4. ~* :用于正则 uri前, 表示 uri 包含正则表达式,不区分大小写

        location ~ .*.(php|java)?$ {
            fastcgi_pass 127.0.0.1:8081;
            fastcgi_index index.php;
            include fastcgi.conf;
        }
        
        #缓存时间设置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {
            expires 10d;
            #d表示天,h表示小时
        }
        
        #服务器收到请求后,首先要在服务端指定的目录中寻找请求资源
        location /image/ {
            # 将访问 /image/ 下的文件指向 系统定义的目录 /home/wsk/image/ 中
            root /home/wsk/;
            autoindex on;
        }

        #对 "/" 启用反向代理
        location / {
            #代理到本地的8081端口
            proxy_pass http://127.0.0.1:8081; 
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            #使后端服务器可以通过 X-Forwarded-For 获取用户真实 IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #以下是一些反向代理的配置,可选。
            proxy_set_header Host $host;
            client_max_body_size 10m; #允许客户端请求的最大单文件字节数
            client_body_buffer_size 128k; #缓冲区缓冲用户端请求的最大字节数,

            ##代理设置 以下设置是 nginx 和后端服务器之间通讯的设置##
            proxy_connect_timeout 90; #代理连接超时
            proxy_send_timeout 90; #代理发送超时
            proxy_read_timeout 90; #代理接收超时
            proxy_buffering on;    #该指令开启从后端被代理服务器的响应内容缓冲 此参数开启后 proxy_buffers 和 proxy_busy_buffers_size 参数才会起作用
            proxy_buffer_size 4k;  #设置代理服务器(nginx)保存用户头信息的缓冲区大小
            proxy_buffers 4 32k;   #设置4个缓冲区,大小限制为 32k 
            proxy_busy_buffers_size 64k; #高负荷下缓冲大小,默认为 proxy_buffers 的2倍
            proxy_max_temp_file_size 2048m; #默认 1024m, 该指令用于设置当网页内容大于 proxy_buffers 时,临时文件大小的最大值。如果文件大于这个值,它将从 upstream 服务器同步地传递请求,而不是缓冲到磁盘
            proxy_temp_file_write_size 512k; 这是当被代理服务器的响应过大时 nginx 一次性写入临时文件的数据量。
            proxy_temp_path  /var/tmp/nginx/proxy_temp;    ##定义缓冲存储目录,之前必须要先手动创建此目录
            proxy_headers_hash_max_size 51200;
            proxy_headers_hash_bucket_size 6400;
        }
        
        # 404时显示的页面
        error_page 404 /404.html;
            location = /40x.html {
        }
        # 50*时显示的页面
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
        
        #本地动静分离反向代理配置
        #所有 jsp 的页面均交由 tomcat 处理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }
        #设定查看 nginx 状态的地址
        location /nginxStatus {
            stub_status on;
            access_log on;
            auth_basic "nginxStatus";
            auth_basic_user_file conf/htpasswd;
            #htpasswd 文件的内容可以用 apache 提供的 htpasswd 工具来产生。
        }

    }

    # 设置HTTPS
# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        # 将 http 强制转换成 https
#        if ($scheme = 'http') {
#            rewrite ^(.*)$ https://$host$uri;
#        }
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
}

7. Nginx的Master-Worker模式

Nginx 采用的是工作模式是 多进程&多路IO复用模型(与Netty相似)。

image

流程说明:

  1. 当 Nginx 启动后,会启动一个 master 进程和多个相互独立的 worker 进程。
  2. 当接收都请求时, master 最先接收到信息,然后再分配给 worker ,每一个 worker 都有机会来处理这次请求。
  3. master 进程持续监控着 worker 的运行状态,当 worker 异常退出时,重新启动一个新的 worker 。

PS:进程 worker 的数量一般会设置成CUP核数。如果设置过多,会导致 worker 竞争CUP,从而带来了不必要的上下文切换(这个和java的多线程类似)。使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响到其他 worker 进程。

设置 worker 的数量

在 nginx.conf 里面配置

1
2
#nginx 进程数,建议设置为等于 CPU 总核心数。
worker_processes 8;

8. Nginx实现热部署

通过修改配置文件 nginx.conf 后,不需要停止 Nginx,也不需要中断请求,就能让配置文件生效

1
2
3
4
[root@wsk1103 ~]# nginx -s reload  # 重新加载
[root@wsk1103 ~]# nginx -t     # 检查配置
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

因为 Nginx 是使用 master-worker 的模式,在修改配置文件 nginx.conf 后,会重新生成新的 worker 进程,并且用新的配置处理请求,而旧的 worker 进程,则是等把原来的请求处理完毕后,会自动 kill 。

9. Nginx在高并发下的高效处理

Nginx 采用了 Linux 的 epoll 模型, epoll 模型是基于事件驱动机制,它可以监控多个事件是否准备完毕,如果准备完成,那么放入 epoll 队列中,这个过程是异步的。 worker 只需要从 epoll 队列循环处理即可。

Nginx 与 多进程模式 Apache 的比较

  • 事件驱动适合于I/O密集型服务,多进程或线程适合于CPU密集型服务
  • Nginx 是事件驱动,更主要是作为反向代理,而不是服务器使用。
  • Nginx 只需要少量进程配合事件驱动,不需要像 Apache 多进程模型跑几百个进程。
  • Nginx 处理静态文件效果显著,因为读写文件和网络通信都是 I/O 操作。

10. Keepalived + Nginx 实现高可用

Keepalived + Nginx 实现高可用

Keepalived+Nginx实现高可用的思路:

  1. 请求不是直接打到 Nginx 上,而是先通过 Keepalived (虚拟IP,VIP)
  2. Keepalived 应该能监控 Nginx 的生命状态