nginx学习笔记

nginx介绍

轻量级,高性能,跨平台Web服务器,基于REST架构风格,以统一资源描述符(URI)或统一资源定位符(URL)作为沟通依据,通过HTTP为浏览器等客户端程序提供各种网络服务.

nginx特性

  1. 更快
    1. 单次请求得到更快的响应
    2. 高并发下比其它web服务器更快地响应请求
  2. 高扩展性
  3. 高可靠性
  4. 低内存消耗
  5. 高并发
  6. 热部署 不停服升级nginx,不停服更新配置,不停服更快日志文件等
  7. 开源(BSD许可)

核心:支持高并发的同时保持高效的服务

nginx编译安装

源码获取

nginx官网

1
2
3
wget http://nginx.org/download/nginx-1.15.6.tar.gz
tar zxvf nginx-1.15.6.tar.gz
cd nginx-1.15.6

编译安装

1
2
3
./configure
make
make install

configure命令检测操作系统内核,检测已安装软件,参数解析,中间目录生成,根据参数生成C源码文件和Makefile文件
make执行configure命令生成的Makefile文件编译nginx工程,并生成目标文件和最终的二进制文件
make install根据configure执行时的参数将nginx部署到指定的安装目录,包括相关目录的建立和二进制文件,配置文件的复制

nginx命令

启动

默认配置文件/usr/local/nginx/conf/nginx.conf

1
/usr/local/nginx/sbin/nginx

可以通过-c参数指定配置文件

1
/usr/local/nginx/sbin/nginx -c /etc/nginx.conf

测试配置文件信息是否有错误

1
/usr/local/nginx/sbin/nginx -t

停止服务

stop强制停止nginx服务
quit处理完所有当前请求再停止服务

1
2
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx -s quit

重读配置并生效

1
/usr/local/nginx/sbin/nginx -s reload

日志文件回滚

先将当前日志文件改名或转移到别的地址,再执行下面命令生成新的日志文件

1
/usr/local/nginx/sbin/nginx -s reopen

nginx配置

nginx进程

在生产环境部署nginx都是采用一个master进程管理多个worker进程的模式.一般情况下,woker进程的数量和服务器上的CPU核心数相等即可(最好每个worker进程都绑定特定的CPU核心,让进程间切换的代价最小).
woker进程提供正在的互联网服务,master进程负责监控woker进程(当worker进程意外退出立即启动新的worker进程继续提供服务),为管理员提供命令行服务(启动服务,停止服务,重新载入配置,平滑升级程序等)

1
2
3
4
5
6
7
8
9
                     |--> worker进程 ------HTTP请求---- Client
|
|--> worker进程 ------HTTP请求---- Client
| |
master进程 ---管理---- |---HTTP请求---- Client
|
|--> worker进程 ------HTTP请求---- Client
|
|--> worker进程 ------HTTP请求---- Client

nginx配置

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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#块配置项由一个块配置项名和一对大括号组成 events http server location upstream等都是块配置项
#块配置项一定会用大括号把所属的一系列所属的配置项包含进来,表示大括号内的配置项同时生效
#块配置项可以嵌套,内层块直接继承外层块

#配置项单位 空间: K或者k千字节 M或m兆字节 时间:ms(毫秒),s(秒),m(分钟),h(小时),d(天),w(周),M(月),y(年)

#以守护进程方式运行Nginx 默认on
daemon on;

#以mater/worker(一个master进程管理多个worker进程)方式工作,如果关闭就不会fork出worker子进程,而是master进程自身来处理请求 默认on
master_process on;

#error日志设置 语法: error_log /path/file level;
#/path/file是一个具体文件, /path/file也可以设置为/dev/null,不再输出任何日志(关闭error日志的唯一手段)
#level是日志等级 debug info notice warn error crit alert emerg 从左到右等级依次增大 如果想把日志等级设置为debug,必须在configure时加入--with-debug配置项
error_log /var/log/nginx/error.log error;
#error_log logs/error.log notice;
#error_log logs/error.log info;


#限制coredump核心转储文件的大小,防止core文件过大占满了磁盘 语法: worker_rlimit_core size;
worker_rlimit_core 1024M;

#指定coredump文件生成目录,worker进程的工作目录,该配置的唯一用途是设置coredump文件防止的目录,协助定位问题,需要确保worke进程有权限向working_directory指定目录写入文件 语法: working_directory path;
working_directory /data/nginx;

#定义环境变量 语法: env VAR|VAR=VALUE; 该配置让用户直接操作操作系统上的环境变量
#嵌入其他配置文件 语法: inclue /path/file; 将其它配置文件嵌入到当前的nginx.conf文件中,参数可以是绝对路径也可以是相对路径(相对nginx配置目录)
#include nginx.d/http/server.casezheng.com.conf
#include nginx.d/*.conf

#pid文件路径 保存master进程ID的pid文件存储路径.默认和configure设置的--pid-path所指定位置相同,需要确认nginx有权在相应目录中建立pid文件
pid /run/nginx.pid;

#ningx worker进程运行的用户及用户组
user nginx;

#设置一个nginx worker进程可以打开的最大文件描述符个数
worker_rlimit_nofile 65535;

#限制信号队列 设置每个用户发往nginx的信号队列的大小,当某个用户的信号队列满了,该用户发送的信号量将被丢弃
#worker_rlimit_sigpending limit;

#nginx worker进程个数 在master/worker运行方式下,定义worker进程的个数
worker_processes auto;

#绑定nginx worker进程到指定的CPU内核 语法: worker_cpu_affinity cpumask [cpumask...]; 该配置仅针对Linux操作系统有效

#SSL硬件加速 如果服务器上有SSL硬件加速设备,可以进行配置加快SSL协议的处理速度.用户可以使用OpenSSL提供的命令来查看是否有SSL硬件加速设备: openssl engine -t
#ssl_engine device;

#nginx worker进程的优先级设置, 优先级有静态优先级和进程执行情况共同决定.这里设置的是静态优先级. 语法: worker_priority nice; nice -20 ~ +19, -20最高优先级 +19最低优先级 希望nginx占用更多系统资源可以将其设置小点,但不建议比内核进程的nice(-5)小.
#worker_priority 0;


include /usr/share/nginx/modules/*.conf;

events {
#对指定的客户端输出debug级别的日志 语法: debug_connection [IP|CIDR]; 该配置属于事件类配置,必须放在events配置块中才有效,值可以是IP地址或CIDR地址 可以用于高并发请求下定位问题
debug_connection 127.0.0.1;
debug_connection 127.0.0.0/24;

#accept锁 accept_mutex是Nginx的负载均衡锁,让多个worker进程轮流的,序列化地与新的客户端建立TCP连接,当一个worker进程建立的连接达到worker_connections配置的最大连接数的7/8时,大大减少该worker进程试图建立新TCP连接的机会,以此实现所有worker进程上处理的客户端请求数尽量接近. accept锁默认打开,关闭后建立TCP连接的耗时会更短,但worker进程间的负载会不均衡,因此不建议关闭它
accept_mutex on;

#使用accept锁后真正建立连接的延迟时间 语法: accept_mutext_delay Nms; 在使用accept锁后,同一时间只有一个worker进程可以获取到accept锁,accept锁不是阻塞锁,如果获取不到会立即返回.如果有一个worker进程试图获取accept锁而没有获取到,至少要等accept_mutex_delay定义的时间间隔后才能再次试图获取锁.

#批量建立新连接 当事件模型通知有新连接时,尽可能对本次调度中客户端发起的所有TCP请求都建立连接. 语法: multi_accept [on|off];
multi_accept off;

#选择事件模型 语法: use [kququ | rtsig | epoll | /dev/poll | select | poll | eventport]; nginx默认会选择最合适的事件模型
use epoll;

#每个worker可以处理的最大连接数
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 on;
#gzip on;

#内存和磁盘资源的分配
#client_body_in_file_only HTTP包体只存储在磁盘空间中 语法:client_body_in_file_only on|clean|off; 默认off; 适用于配置块:http,server,location 当非off值时,用户请求中的HTTP包体一律存储到磁盘文件中,即使只有0字节也会存储为文件.当请求结束时如果配置为on,则该文件不会被删除(一般用于调试定位问题),若配置为clean,则会删除该文件
client_body_in_file_only off;
#client_body_in_single_buffer on|off; HTTP包体尽量写到一个内存buffer中.如果HTTP包体的大小超过了client_body_buffer_size设置的值,包体还是会写入到磁盘文件中 适用于配置块:http,server,location
client_body_in_single_buffer off;
#client_header_buffer_size size; 存储HTTP头部的内存buffer大小 配置块:http,server 存储HTTP头部的内存buffer大小 定义了正常情况下Nginx接收用户请求中HTTP header部分(包括HTTP行和HTTP头部)时分配的内存buffer大小.如果请求中的HTTP header部分超过client_header_buffer_size,large_client_header_buffers将会生效
client_header_buffer_size 1K;
#large_client_header_buffers number size; 配置块:http,server large_client_header_buffers定义了nginx接收超大HTTP头部请求的buffer个数和每个buffer的大小.如果HTTP请求行的大小超过单个buffer,则返回"Request URI toolager"(414).请求中一般有多个header,每个header的大小也不能超过单个buffer的大小.否则返回"Bad request"(400).请求行和请求头部的总和也不可以超过buffer个数和*buffer大小
large_client_header_buffers 4 8K;
#client_body_buffer_size size; 配置块:http,server,location 存储HTTP包体的内存buffer大小 定义了nginx接收HTTP包体的内存缓冲区大小 即HTTP包体会先接收到指定的这块内存中,之后才决定是否写入磁盘.
#如果用户请求中包含HTTP头部Content-Length,并且其标识长度小于定义的buffer长度,nginx会自动降低本次请求所使用的内存buffer,降低内存消耗.
client_body_buffer_size 16k;
#client_body_temp_path dir-path [level1[level2[level3]]]; 配置块:http,server,location 定义HTTP包体存放的临时目录.在请求HTTP包体时,如果包体大小大于client_body_buffer_size,则会以一个递增的整数命名并存放到client_body_temp_path所指定的目录中.其后跟随的level1,level2,level3是为了防止一个目录下文件太多导致性能下降,因此使用level参数,按照临时文件名最多再加三层目录.
client_body_temp_path client_body_temp 1 2;
#connection_pool_size size; 配置块:http,server nginx对每个建立的TCP连接会预先分配一个内存池,size指定该内存池的初始大小,用于减少内核对小块内存的分配次数,需谨慎设置.过大的size会使服务器消耗内存增多,更小的size会引发更多的内存分配次数.
connection_pool_size 256;
#request_pool_size size; 配置块:http,server nginx开始处理HTTP请求时,会为每个请求分配一个内存池,size配置项指定该内存池的初始大小,用于减少内核对小块内存的分配次数.TCP连接关闭时会销毁connection_pool_size指定的连接池,HTTP请求结束时会销毁request_pool_size指定的HTTP请求内存池.但TCP连接内存池和HTTP请求内存池的创建和销毁时间并不一致,因为一个TCP连接可能被复用于多个HTTP请求.
request_pool_size 4k;

#网络连接的设置
#client_header_timeout time(默认单位s); 配置块:http,server,location 读取HTTP头部的超时时间 客户端和服务器建立连接后开始接收HTTP头部,如果在一个时间间隔内没有读取到客户端发来的字节,则认为超时,并向客户端返回408("Request timed out")响应.
client_header_timeout 60;
#client_body_timeout time(默认单位s); 配置块:http,server,location 读取HTTP包体的超时时间
client_body_timeout 60;
#send_timeout time; 配置块:http,server,location 发送响应的超时时间 nginx服务器向客户端发送数据包,但客户端一直没有去接收这个数据包.如果某个连接超过send_timeout定义的超时时间,nginx将关闭这个连接
send_timeout 60;
#reset_timedout_connection on|off; 配置块:http,server,location 连接超时后将通过向客户端发送RST包来直接重置连接.该选项打开后,nginx会在某个连接超时后,不是使用正常情况下的四次挥手关闭TCP连接,而是直接向用户发送RST重置包,不在等待用户的应答,直接使用nginx服务器上关于该套接字的所有缓存,与正常关闭方式相比,使得服务器避免了产生更多处于FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT状态的TCP连接. 但是,使用RST重置包关闭连接会带来一些问题,默认情况下不会开启.
reset_timedout_connection off;
#lingering_close off|on|always; 配置块:http,server,location 控制nginx关闭用户连接的方式.always表示关闭用户连接前必须无条件地处理连接上所有用户发送的请求.off表示关闭连接时完全不管连接上是否有已经准备就绪的来自用户的数据.on是中间值,一般情况下在关闭前都会处理l连接上用户发送的数据,除了有些情况下在业务上认定之后的数据是不必要的.
lingering_close on;
#lingering_time time; 配置块:http,server,location lingering_close启用后,对上传大文件很有用,当用户上传的Content-Length大于max_client_body_size时,nginx服务器向用户发送413(Request entity too large)响应,如果客户端不管413返回值继续上传HTTP body,经过lingering_time设置的时间后,nginx将不管用户是否仍在上传,都将连接关闭掉
lingering_time 30s;
#lingering_timeout time; 配置块:http,server,location lingering_close生效后,在关闭连接前,会检测是否有用户发送的数据到达服务器,如果超过了lingering_timeout还没有数据可读,就直接关闭连接,否则,必须在读取完连接缓冲区上的数据并丢弃后才能关闭连接
lingering_timeout 5s;
#keepalive_disable [msie6|safari|none...]; 配置块:http,server,location HTTP请求的keepalive功能让多个请求复用一个HTTP长连接,对服务器的性能提高很有帮助,但有的浏览器对keepalive功能的POST请求有功能项问题,因此可以对特定浏览器禁用keepalive功能
keepalive_disable msie6 safari;
#keepalive_timeout time(秒); 配置块:http,server,location 一个httpalive在闲置一定时间后,服务器和浏览器都会去关闭这个连接,keepalive_timeout配置项用来约束nginx服务器,nginx会按照规范将keepalive_timeout传给浏览器,但每个浏览器对keepalive的策略有可能不同
keepalive_timeout 65;
#keepalive_requests n; 配置块:http,server,location 一个keepalive长连接上允许的请求最大数 即一个keepalive连接上最多只能发送n个请求
keepalive_requests 100;
#tcp_nodelay on|off; 配置块:http,server,location 确定对keepalive连接是否使用TCP_NODELAY选项
tcp_nodelay on;
#tcp_nopush on|off; 配置块:http,server,location 在打开sendfile选项时,确认是否开启FreeBSD系统的TCP_NOPUSH或Linux系统上的TCP_CORK功能,打开tcp_nopush后,将在发送响应时把真个响应头放在一个TCP包中发送.
tcp_nopush on;

#MIME类型的设置
#MIME type与文件扩展的映射 语法: type {...}; 配置块:http,server,location 定义MIME type到文件拓展名的映射.多个拓展名可映射到同一个MIME type.
#默认MIME type 语法:default_type MIME-type; 配置块:http,server,location 当找不到相应的MIME type与文件扩展名之间的映射时使用默认的MIME type作为HTTP header中的Content-Type.
default_type application/octet-stream;
#types_hash_bucket_size size; 默认type_hash_bucket_size 32|64|128; 配置块:http,server,location 为了快速查找相应MIME type,nginx使用散列表来存储MIME type与文件扩展名.types_hash_bucket_size设置了每个散列桶占用内存大小
types_hash_bucket_size 64;
#types_hash_max_size size; 配置块:http,server,location 影响散列表的冲突率,types_hash_max_size越大,消耗内存越大,打散列表的冲突率会降低,检索速度会更快,types_hash_max_size越小,消耗内存越少,但散列表冲突率会上升.
types_hash_max_size 2048;

#文件操作的优化
#sendfile系统调用 sendfile on|off; 配置块:http,server,location 启用Linux上的sendfile系统调用来发送文件,减少系统内核和用户态之间的两次内存复制,从磁盘中直接读取文件后直接在内核态发送到网卡设备.提高发送文件的效率.
#sendfile off;
#AIO系统调用 aio on|off; 配置块:http,server,location 表示是否在FreeBSD或Linux系统上启用内核级别的异步文件I/O功能.该配置和sendfile功能互斥
aio on;
#directio size|off; 配置块:http,server,location 在FreeBSD和Linux系统上使用O_DIRECT选项来读文件,缓冲区大小为size,通常对大文件的读取速度有优化功能,与sendfile功能相斥.
directio off;
#directio_alignment size; 配置块:http,server,location 与directio配合使用,指定以directio方式读取文件时的对齐方式.
directio_alignment 512;
#打开文件缓存 open_file_cache max=N[inactive=time]|off; 配置块:http,server,location 文件缓存会在内存中存储3种信息:1.文件句柄,文件大小和上次修改时间 2.已经打开过的目录结构 3.没有找到的或者没有操作权限的文件信息
#open_file_cache 后面跟3个参数.max表示在内存中存储元素的最大个数,当达到最大值后,将采用LRU算法从缓存中淘汰最近最少使用的元素.inactive表示在inactive指定的时间段内没有被访问过的元素将被淘汰.默认时间为60秒.off关闭缓存功能
open_file_cache off;
#open_file_cache max=100 inactive=20s;
#缓存打开文件错误的信息 open_file_cache_errors on|off; 配置块:http,server,location
open_file_cache_errors off;
#不被淘汰的最小访问次数 open_file_cache_min_uses number; 配置块:http,server,location 与open_file_cache中的inactive参数配合使用.如果在inactive指定时间段内,访问次数超过了open_file_cache_min_uses指定的最小次数,那么将不会被淘汰出缓存.
open_file_cache_min_uses 1;
#检查缓存中元素有效性的频率. open_file_cache_valid time; 配置块:http,server,location
open_file_cache_valid 60s;

include /etc/nginx/mime.types;
include /etc/nginx/default.d/*.conf;
include /etc/nginx/conf.d/*.conf;

#server_names_hash_bucket_size设置nginx存储server_name的散列表每个散列桶占用的内存大小 适用于配置块:http,server,location 取值32,64,128
server_names_hash_bucket_size 128;
#server_names_hash_max_size影响散列表的冲突率,值越大消耗内存越多,散列key的冲突率约低,检索速度越快 适用于配置块:http,server,location
server_names_hash_max_size 512;

#对客户端请求的特殊处理
#忽略不合法的HTTP头部 ignore_invalid_headers on|off; 配置块:http,server 如果将其设置为off,当出现不合法的HTTP头部时,ngin将拒绝服务,并直接想用户发送400(Bad Request)错误,如果设置为on,则将忽略此HTTP头部.
ignore_invalid_headers on;
#HTTP头部允许下划线 underscores_in_headers on|off; 配置块:http,server 默认off,表示HTTP头部名称中不允许带"_"
underscores_in_headers off;
#If-Modified-Since头部的处理策略 if_modified_since [off|exact|before]; 配置块:http,server,location Web浏览器一般会缓存文件到本地,并存储当时获取的时间,下次向Web服务器获取缓存过的资源时,使用If-Modified-Since头部把上次获取的时间捎带上,而if_modified_since将根据后面的参数决定如何处理If-Modified-Since头部.
#off: 直接忽略用户请求中的If-Modified-Since头部,如果获取一个文件,会正常返回文件内容,HTTP响应吗通常为200
#exact: 将If-Modified-Since头部包含的时间和将要返回的文件上次修改时间做精准比较,如果没有匹配上则返回200和文件实际内容,如果匹配上了,则表示浏览器缓存的已经是最新的啦,没有必要再返回文件浪费时间和宽带,返回304 Not Modified,浏览器收到后会直接读取自己的本地缓存
#before: 比exact更宽松,只要文件上次修改时间等于或早于用户请求中的If-Modified-Since头部的时间,会向客户端返回304Not Modified.
if_modified_since exact;
#文件未找到时记录到error日志 log_not_found on|off; 配置块:http,server,location 表示当处理用户请求且需要访问文件时,如果未找到文件,是否将错误记录到error.log日志.可用于定位问题.
log_not_found on;
#merge_slashes on|off; 配置块:http,server,location 合并相邻的"/".
merge_slashes on;
#DNS解析地址 resolver address ...; 配置块:http,server,location 设置DNS名字解析服务器地址.
#DNS解析超时时间 resolver_timeout time; 配置块:http,server,location
resolver_timeout 30s;
#server_tokens on|off; 返回错误页面时是否在Server中注明nginx版本 配置块:http,server,location 方便定位问题
server_tokens on;

#server块 虚拟主机定义
server {
#监听端口 默认监听80端口 listen决定nginx服务如何监听端口.在listen后面可以只加IP地址,端口或主机名
#listen 127.0.0.1:8080;
#listen 127.0.0.1; #不写端口时,默认监听80端口
#listen *:80;
#listen localhost:80;
#listen后面也可以加其他参数
#1. default/default_server: 将这个server块作为整个Web服务的默认server块.未设置则将nginx解析配置时找到的第一个server块作为默认块,当一个请求无法匹配配置文件中所有主机域名时,选择默认的虚拟主机.
#2. backlog=num: 表示TCP中backlog队列的大小,默认为-1,表示不予设置.在TCP三次握手的工程中,进程还没有开始处理监听句柄,这时backlog队列会放置这些新连接.如果backlog队列已满,新的客户端试图建立新连接将会失败.
#3. rcvbuf=size: 设置监听句柄的SO_RCVBUF参数
#4. sndbuf=size: 设置监听句柄的SO_SNDBUF参数
#5. accept_filter: 设置accept过滤器,只对FreeBSD操作系统有效
#6. deferred: 设置该参数,若用户发起建立连接请求,并且完成TCP的三次握手,内核也不会调度worker进程来处理这个连接,当用户真的发送请求数据时,内核才会调度worker进程处理这个连接,这个参数适合大并发的情况下,减轻worker进程的负担
#7. bind: 绑定当前端口/地址对, 只有同时对一个端口监听多个地址才会生效
#8. ssl: 在当前监听的端口上建立的连接必须基于SSL协议
listen 80 default_server;
listen [::]:80 default_server;

#主机名称 server_name可以跟多个主机名称
#server_name localhost test.casezheng.date;
#server_name localhost 127.0.0.1;
#当nginx处理一个HTTP请求时,nginx取出header头中的host,与每个server中的server_name匹配.匹配规则如下:
#1. 完全匹配server_name
#2. 通配符在前面的server_name
#3. 通配符在后面的server_name
#4. 正则表达式才匹配的server_name
#5. 前面都未匹配到,找listen配置项后加了default或default_server的server块
#6. 前面都未匹配到,找匹配listen端口的第一个server块
#server_name后面跟空字符串表示匹配没有host这个HTTP头部的请求
server_name localhost test.casezheng.date;

#server_name_in_redirect 重定向主机名称 配合server_name使用,当打开时表示重定向请求时会使用server_name里配置的第一个主机名代替原先请求中的Host头部,关闭时表示在重定向请求时使用请求本身的Host头部. 适用于配置块:http,server,location 默认on
server_name_in_redirect on;

#charset koi8-r;

#location 语法: location [=|~|~*|^~|@]/uri/ { ... } 适用于配置块:server location尝试根据用户请求中的URI来匹配/uri表达式,如果可以匹配,就选择location块中的配置处理用户请求, 匹配规则如下:
#1. =表示把URI作为字符串,以便与参数中的uri做完全匹配
#2. ~表示匹配URI时是大小写敏感的
#3. ~*表示匹配URI时忽略字母大小写问题
#4. ^~表示匹配URI时只需要其前半部分与uri参数匹配即可
#5. @表示仅用于nginx服务内部请求之间的重定向
#在uri参数中可以使用正则表达式进行匹配
#location存在顺序,当一个请求有可能匹配多个location时,该请求将被第一个location处

root /data/nginx/;

#对客户端请求的限制
#对HTTP方法名限制用户请求 limit_except method ... { ... } 配置块:location nginx通过limit_except后面指定的方法名来限制用户请求.方法名取值包括:GET,HEAD,POST,PUT,DELETE,MKCOL,COPY,MOVE,OPTIONS,PROPFIND,PROPPATCH,LOCK,UNLOCK或者PATCH.
#请求包体的最大值 client_max_body_size size; 配置块:http,server,location 浏览器发送含较大HTTP包体的请求时,其头部有Content-Length字段,client_max_body_size是用来限制Content-Length所示值的大小的.nginx在接受到包头后,发现Content-Length的值大于client_max_body_size,直接发送403("Request Entity Too Large")响应给客户端
client_max_body_size 1m;

#对请求的限制 limit_rate speed; 配置块:http,server,location,if 对客户端请求限制每秒传输的字节数. 0表示不限速.
limit_rate 0;
#limit_rate_after length; 表示nginx向客户端发送的请求长度超过limit_rate_after后才开始限速.
limit_rate_after 100m;

location = /test_root {
#以root方式设置资源路径 适用于配置块:http,server,location,if root根据完整的URI请求来映射
#root /data/nginx/;
limit_except GET {
allow 192.168.1.0/32;
deny all;
}
}

location = /test_alias {
#以alias方式设置资源路径 适用于配置块:location alias在URI向实际文件路径的映射过程中,会丢弃掉location后面配置的那部分uri
alias /data/nginx/test_alias/;
}

location / {
#访问首页 语法: index file ...; 用ngx_http_index_module模块提供的index配置实现返回网站首页,nginx按照配置的顺序访问index后配置的文件
root /data/nginx;
index index.html index.htm;
}

#error_page code [code...][=|=answer-code]uri|@named_location 适用于配置块:http,server,location,if
#当某个请求返回错误码时,如果匹配上了erro_page中设置的code,则重定向到新的URI中.
#error_page 404 /404.html;
#error_page 404 =200 /404.html; #重定向后返回的错误码还是原来的,可以通过=更改返回的错误码
#error_page 404 = /404.html; #也可以不指定确切的返回码,由重定向后实际处理的真实结果决定
#如果不行修改URI,只是将错误请求重定向到另一个location处理,可以如下配置,将错误请求代理到http://test.casezheng.date/test_root上游服务器处理
location /test_error_fallback {
error_page 404 @fallback;
}
location @fallback {
proxy_pass http://test.casezheng.date;
}
#递归使用error_page recursive_error_pages [on|off]
recursive_error_pages off; #默认不允许递归定义error_page

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /data/nginx;
}

location ^~ /test_try_files {
#try_files后跟若干路径,最后必须有uri参数. nginx尝试按顺序访问每个路径,如果可以有效访问则返回,否则继续读取下一个.如果所有路径都读取不到则重定向到最后的参数uri上.因此最后的uri参数必须存在而且是可以重定向的.
#try_files适用于server,location配置块
try_files /test_try1 /test_try2 /test_try3 @fallback;
}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}


# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;

# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;

# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;

# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;

# location / {
# root html;
# index index.html index.htm;
# }
#}
}

nginx配置反向代理服务器

反向代理(reverse proxy)方式指用代理服务器接受Internet上的连接请求,然后将请求转发给内部网络中的上游服务器,并将从上游服务器得到的结果返回给Internet上请求连接的客户端.反向代理服务器必须能够能支持大量并发请求

1
2
3
4
5
6
7
8
                                      Nginx
---静态文件请求--->
静态Web服务器
<---文件内容-------
Web浏览器
---静态文件请求---> ---转发动态请求--->
反向代理服务器 处理复杂业务的动态Web服务器
<---转发动态应答--- <----动态应答------

nginx的反向代理特点

  • 2 用户发来的请求将会完整地缓存到nginx代理服务器,之后才会向后端服务器转发
  • 3 nginx反向代理服务器可以按照多种方案从上游服务器的集群中选择一台.负载均衡方案包括按IP地址做散列等
  • 5 如果上游服务器返回内容,则不会先完整缓存到nginx代理服务器再发给客户端,而是边接收边转发到客户端
1
2
3
4
5
6
7
                                    2----> 缓存的HTTP包体                   上游服务器
|
--------1------> | ---------3--------->
客户端 nginx反向代理服务器 上游服务器
<-------5------- <--------4----------

上游服务器

nginx的反向代理方案主要是为了降低上游服务器的并发压力.缺点是:延长了一个请求的处理时间,并增加了用于缓存请求内容的内存和磁盘空间,增加了nginx的压力.

负载均衡和反向代理的基本配置

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
... ...
http {
... ...
#upstream name {...} 配置块:http upstream块定义一个上游服务器的集群,便于反向代理中proxy_pass使用.
#server name [parameters]; 配置块:upstream server配置项指定了一个上游服务器的名字,可以是域名,IP地址端口,UNIX句柄等,其后可跟如下参数
#1. weight=number:设置向这台上游服务器转发的权重,默认为1
#2. max_fails=number:与fail_timeout配合使用,指在fail_timeout时间段内,如果向当前的上游服务器转发失败次数超过number,则认为在当前的fail_timeout时间段内这台上游服务器不可用,max_fails默认为1,设置为0表示不检查失败次数
#3. fail_timeout:表示该时间段内转发失败多少次后就认为上游服务器暂时不可用,用于优化反向代理功能.该值与向上游服务器建立连接的超时时间,读取上游服务器的响应超时时间等完全无关.fail_timeout默认为10s
#4. down:表示所在的上游服务器永久下线,只在使用ip_hash配置项时才有用
#5. backup:在使用ip_hash配置时无效,表示所在的上游服务器只是备份服务器,当所有非备份上游服务器都失效后,才会向所在的上游服务器转发请求
#ip_hash; 配置块:upstream 按ip hash转发,确保同一个客户端的请求只转发到指定的上游服务器, ip_hash不可与weight配置同时使用. 当upstream集群有一台上游服务器不可用时不可直接删除该配置,而是用down参数标识,确保转发的一致性.
upstream backend1 {
server example1.casezheng.date weight=5;
server example2.casezheng.date max_fails=2 fail_timeout=30s;
server example3.casezheng.date down;
server example4.casezheng.date;
}
upstream backend2 {
ip_hash;
server example1.casezheng.date;
server example2.casezheng.date;
server example3.casezheng.date down;
server example4.casezheng.date;
}
#proxy_pass URL; 配置块:location, if 将当前请求反向代理到URL参数指定的服务器上,URL可以是主机名或IP加端口或直接使用upstream块 默认情况下反向代理不转发请求中的Host头部,如果需要转发,需要加上 proxy_set_header Host $host;
#proxy_method method; 配置块:http,server,location 表示转发时的协议方法名
#proxy_hide_header the_header; 配置块:http,server,location nginx将上游服务器的响应转发给客户端,但默认不转发以下HTTP头部字段:Data,Server,X-Pad和X-Accel-*.使用proxy_hide_header后k而已任意指定哪些HTTP头部字段不能被转发
#proxy_pass_header the_header; 配置块:http,server,location 与proxy_hide_header相反,将原本被禁止的header设置为允许转发.
#proxy_pass_request_body on|off; 配置块:http,server,location 向上游服务器发送HTTP包体
#proxy_pass_request_headers on|off; 配置块:http,server,location 向上游服务器发送HTTP包头
#proxy_redirect [default|off|redirect reqlacement]; 配置块:http,server,location
#proxy_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off]; 配置块:http,server,location 表示当向一台上游服务器转发请求错误时,继续换一台上游服务器处理这个请求
server {
listen 80;
server_name exampel.casezheng.date;

proxy_method POST;
proxy_pass_request_body on;
proxy_pass_request_headers on;
#proxy_redirect default;
proxy_next_upstream error timeout;
location / {
proxy_pass http://backend2;
}
}
}

nginx http模块调用的简化流程

nginx http模块调用的简化流程

nginx基础架构

nginx数据结构

ngx_list_t

nginx ngx_list_t链表结构内存分布

nginx源码阅读

nginx-1.15.6源码阅读注释

参考资料

  • 深入理解Nginx模块开发与架构解析第2版