言成言成啊 | Kit Chen's Blog

Nginx基础

发布于2021-07-12 22:23:03,更新于2023-08-30 23:32:51,标签:java nginx  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

参考

  1. Nginx快速入门(本文参考的主要文章)
  2. nginx代理的原理和三种模式
  3. Centos8安装Nginx
  4. Nginx官方文档
  5. Nginx中文文档-反向代理
  6. Nginx中文文档-正向代理
  7. 正向代理通过服务器访问公司内网
  8. 负载均衡之加权轮询算法
  9. Nginx配置文件详解

一、背景

最初的项目并发量小,用户使用的少,只需要启动一个项目、一台服务器就足够用了。

随着用户越来越多,并发量越来越大,一台服务器无法满足需求,此时就需要进行横向扩展。

这个时候,几个项目启动在不同的服务器上,用户要访问,就需要增加一个代理服务器,通过代理服务器来帮我们转发和处理请求。

二、了解

Nginx完全基于C语言开发。

Nginx的作用

  1. 正向代理:代理客户端的,比如vpn
  2. 反向代理:代理服务器端的
  3. 负载均衡

正向代理示意图

反向代理示意图

Nginx提供的负载均衡策略

  1. 内置策略:轮询、加权轮询、ip hash
  2. 动静分离策略

2.1 内置策略

轮询就是在服务器间,按顺序分配请求,就类似于扑克牌发牌。

轮询没有考虑到每台服务器的处理数据的能力,而加权轮询,就是根据服务器的能力来分配权值。

1
2
3
4
5
6
7
8
http {  
upstream cluster {
server a weight=1;
server b weight=2;
server c weight=3;
}
...
}

如上配置文件,加权轮询就是在每6个请求中,1个请求给a,2个给b,3个给c;以此轮流,如果不满足整除,除了权重最多的执行最多,别的就不好说了。如果某一台机器挂掉了,返回500或者404,就会将请求转发下一台服务器(本质上这种都会降低效率,毕竟多了一层判断是否正常连接)。如图

iphash是对客户端请求的ip进行hash操作,然后将同一个hash的请求分配给同一台服务器进行处理,可以解决session不共享的问题!如下图所示。

iphash的缺点:如果一台服务器挂了,数据就会丢失,凉凉了。比较好的方法是可以通过缓存与Cookie实现session共享

2.2 动静分离策略

动静分离就是静态资源直接访问本地服务器,不进行代理,并进行缓存;这个比较简单,直接将静态资源放到本地服务器即可。

对动态资源进行转发和处理请求。

三、配置

Nginx的下载

  1. 官方下载页
  2. centos安装nginx
  3. meethigher/nginx-cluster-demo: 通过nginx实现简易集群的负载均衡
  4. windows无脑安就可以了

管理命令如下

1
2
3
4
5
./nginx #启动
./nginx -s stop #停止
./nginx -s quit #安全退出
./nginx -s reload #重新加载配置文件
ps aux|grep nginx #查看nginx进程

通过nginx配置代理来访问集群,通过访问本地的127.0.0.1:13000,实现代理8080、8081、8082的server集群

3.1 配置轮询转发

在根配置中,配置nginx加载vhost下的所有conf文件

nginx.conf

1
2
3
4
http { 
...
include vhost/*.conf;
}

test.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
upstream server {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
listen 13000;
server_name localhost;
location / {
proxy_pass http://server;
}

# 访问127.0.0.1:13000/file/index.html实际会映射到/root/html/file/index.html
location /file/ {
root /root/html/;
}
}

实现接口,每个机器调用接口,返回机器的端口地址。

执行12次,最后运行结果

3.2 配置加权轮询转发

nginx.conf

1
2
3
4
http { 
...
include vhost/*.conf;
}

test.conf

1
2
3
4
5
6
7
8
9
10
11
12
upstream server {
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=2;
server 127.0.0.1:8082 weight=3;
}
server {
listen 13000 ;
server_name localhost;
location / {
proxy_pass http://server;
}
}

实现接口,每个机器调用接口,返回机器的端口地址。

执行12次,最后运行结果

四、详细配置

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
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#---- 全局配置区域 ----

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

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

#worker工作进程的个数,master进程是接收并分配请求给worker处理。这个数值简单一点
#可以设置为cpu的核数grep -c ^processor /proc/cpuinfo,也是 auto 值
worker_processes 4;

#在高并发情况下,通过设置cpu粘性来降低由于多CPU核切换造成的寄存器等现场重建带来的性能损耗。
#如worker_cpu_affinity 0001 0010 0100 1000; (四核)
worker_cpu_affinity 0001 0010 0100 1000;

#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)
#与nginx进程数相除,但是nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致.
worker_rlimit_nofile 65535;

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log info;


#---- events配置区域 ----
events {
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
#epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型
use epoll;

#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 1024;

#打开同时接受多个新网络连接请求的功能
multi_accept on;
}


#---- http配置区域 ----
http {
#文件扩展名与文件类型映射表
include mime.types;

#默认文件类型
default_type application/octet-stream;

#默认编码
charset utf-8;

#隐藏版本号
server_tokens off;

#服务器名字的hash表大小
server_names_hash_bucket_size 128;

#客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k
client_header_buffer_size 32k;

#客户端请求中较大的消息头的缓存最大数量和大小
large_client_header_buffers 4 64k;

#客户端请求体数据的Buffer大小
client_body_buffer_size 128k;

#客户端请求体数据最大值,例如上传文件
client_max_body_size 8m;

#长连接持续时间,客户端连接超时该值时会断开,为0禁用长链接
keepalive_timeout 65;

#客户端请求头读取超时时间
client_header_timeout 10;

#设置客户端请求主体读取超时时间
client_body_timeout 10;

#响应客户端超时时间
send_timeout 10;


# sendfile指令指定nginx是否调用sendfile函数(zero copy 方式)来输出文件,对于普通应用,必须设为on。
#如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。
sendfile on;

# 开启或者关闭nginx在FreeBSD上使用TCP_NOPUSH套接字选项, 在Linux上使用TCP_CORK套接字选项。
#选项仅在使用sendfile的时候才开启。
tcp_nopush on;

# 开启或关闭nginx使用TCP_NODELAY选项的功能。 这个选项仅在将连接转变为长连接的时候才被启用。
tcp_nodelay on;

#---- gzip压缩模块配置 ----

# 开启gzip压缩输出,减少网络传输
gzip on;

# 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。
#建议设置成大于1k的字节数,小于1k可能会越压越大
gzip_min_length 1k;

# 表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果
gzip_buffers 4 16k;

# 压缩版本,默认1.1,目前大部分浏览器已经支持gzip解压,前端如果是squid2.5请使用1.0
gzip_http_version 1.1;

# 压缩等级 1-9 等级越高,压缩效果越好,节约宽带,但CPU消耗大
gzip_comp_level 2;

# 压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn
gzip_types text/plain application/x-javascript text/css application/xml;

# 选项可以让前端的缓存服务器缓存经过gzip压缩的页面.例如:用squid缓存经过nginx压缩的数据
gzip_vary on;


# ---- 反向代理配置 ----

#nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 5;

#代理发送超时
proxy_send_timeout 5;

#代理接收超时
proxy_read_timeout 60;

#启动代理缓存功能
proxy_buffering on;

#设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffer_size 16k;

#设置用于读取应答(来自被代理服务器)的缓冲区数目和大小
proxy_buffers 4 32k;

#高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;

#设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;

#反向代理缓存目录
#levels=1:2 设置目录深度,第一层目录是1个字符,第2层是2个字符
#keys_zone:设置web缓存名称和内存缓存空间大小
#inactive:自动清除缓存文件时间。
#max_size:硬盘空间最大可使用值。
proxy_cache_path /data/proxy/cache levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=1g;

#指定临时缓存文件的存储路径(必须在同一分区)
proxy_temp_path /data/proxy/temp;

# ---- 负载均衡服务器池配置 ----

upstream server_pool {

#调度算法
#1.轮循(默认)(weight轮循权值)
#2.ip_hash:根据每个请求访问IP的hash结果分配。(会话保持)
#3.fair:根据后端服务器响应时间最短请求。(upstream_fair模块)
#4.url_hash:根据访问的url的hash结果分配。(需hash软件包)
#参数:
#down:表示不参与负载均衡
#backup:备份服务器
#max_fails:允许最大请求错误次数
#fail_timeout:请求失败后暂停服务时间。

server 192.168.1.109:80 weight=1 max_fails=2 fail_timeout=30;
server 192.168.1.108:80 weight=2 max_fails=2 fail_timeout=30;
}

#负载均衡调用
server {
...
location / {
proxy_pass http://server_pool;
}
}


#---- 虚拟主机配置反向代理 ----
server {

#侦听的80端口
listen 80;
server_name localhost;
location / {
#反向代理缓存设置命令(proxy_cache zone|off,默认关闭所以要设置)
proxy_cache cache_one;

#对不同的状态码缓存不同时间
proxy_cache_valid 200 304 12h;

#设置以什么样参数获取缓存文件名
proxy_cache_key $host$uri$is_args$args;

#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
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://IP;

# 图片缓存时间设置
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 10d;
}

# JS和CSS缓存时间设置
location ~ .*\.(js|css)?$ {
expires 1h;
}

#文件过期时间控制
expires 1d;
}
#配置手动清楚缓存(实现此功能需第三方模块 ngx_cache_purge)
#http://www.123.com/2017/0316/17.html访问
#http://www.123.com/purge/2017/0316/17.html清楚URL缓存
location ~ /purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge cache_one $host$1$is_args$args;
}

#设置扩展名以.jsp、.php、.jspx结尾的动态应用程序不做缓存
location ~.*\.(jsp|php|jspx)?$ {
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://IP;
}
}


#虚拟主机的配置
server
{
# 监听端口
listen 80;

# 域名可以有多个,用空格隔开
server_name 127.0.0.1;

#编码格式,若网页格式与此不同,将被自动转码
#charset koi8-r;

#日志相关定义
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#定义日志的格式。后面定义要输出的内容。
#1.$remote_addr 与$http_x_forwarded_for 用以记录客户端的ip地址;
#2.$remote_user :用来记录客户端用户名称;
#3.$time_local :用来记录访问时间与时区;
#4.$request :用来记录请求的url与http协议;
#5.$status :用来记录请求状态;
#6.$body_bytes_sent :记录发送给客户端文件主体内容大小;
#7.$http_referer :用来记录从那个页面链接访问过来的;
#8.$http_user_agent :记录客户端浏览器的相关信息


#虚拟主机访问日志定义
access_log logs/host.access.log main;

#对URL进行匹配
location / {
#访问路径,可相对也可绝对路径
root html;

#首页文件。以下按顺序匹配
index index.html index.htm;
}

#错误信息返回页面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

#php脚本请求全部转发给FastCGI处理
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;
}

#限制IP访问
location / {
deny 192.168.0.2;
allow 192.168.0.0/24;
allow 192.168.1.1;
deny all;
}

location /images {

root /var/www/nginx-default/images;
# 开启目录列表访问,合适下载服务器,默认关闭.
autoindex off;

# 显示文件大小,默认为on,显示出文件的确切大小,单位是bytes 改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_exact_size on;

# 显示文件时间 默认为off,显示的文件时间为GMT时间 改为on后,显示的文件时间为文件的服务器时间
autoindex_localtime on;
}

#Nginx运行状态,StubStatus模块获取Nginx自启动的工作状态(编译时要开启对应功能)
location /NginxStatus {
#启用StubStatus的工作访问状态
stub_status on;
#指定StubStaus模块的访问日志文件 可off
access_log logs/Nginxstatus.log;
#Nginx认证机制(需Apache的htpasswd命令生成)
#auth_basic "NginxStatus";
#用来认证的密码文件
#auth_basic_user_file ../htpasswd;
}


#根据不同的浏览器URL重写
if($http_user_agent ~ Firefox){
rewrite ^(.*)$ /firefox/$1 break;
}
if($http_user_agent ~ MSIE){
rewrite ^(.*)$ /msie/$1 break;
}

#实现域名跳转
location / {
rewrite ^/(.*)$ https://web8.example.com$1 permanent;
}

#控制跳转https
rewrite ^(.*) https://$server_name$1 permanent;
}
 server {
# 1.1版本后这样写
listen 443 ssl;
#填写绑定证书的域名
server_name www.domain.com;
# 指定证书的位置,绝对路径
ssl_certificate 1_www.domain.com_bundle.crt;
ssl_certificate_key 2_www.domain.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}

}
发布:2021-07-12 22:23:03
修改:2023-08-30 23:32:51
链接:https://meethigher.top/blog/2021/nginx/
标签:java nginx 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏