Nginx:一款高性能的反向代理服务器

Nginx 是什么?

Nginx™ [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server

环境搭建

下载

 在 Nginx Archive 下载页面,下载 nginx-1.13.12.tar.gz 安装包

安装依赖

1
2
$ yum -y install openssl openssl-devel
$ yum -y install pcre-devel

编译安装

1
2
3
4
5
$ tar zxvf nginx-1.13.12.tar.gz
# 必须要跳转到 nginx 安装目录下
$ cd nginx-1.13.12
$ ./configure --prefix=/usr/local/nginx --conf-path=/usr/local/nginx/nginx.conf
$ make -j4 && make -j4 install

启动

1
2
$ cd /usr/local/nginx/
$ sbin/nginx -c /usr/local/nginx/nginx.conf
1
$ ps -ef | grep nginx
1
2
3
4
root     107034      1  0 Oct31 ?        00:00:00 nginx: master process sbin/nginx
nobody 107036 107034 0 Oct31 ? 00:00:00 nginx: worker process
nobody 107266 107265 0 Oct31 ? 00:00:00 tsar --check --apache --cpu --mem --load --io --traffic --tcp --partition --nginx --swap
root 107270 97588 0 Oct31 pts/1 00:00:00 grep nginx

停止

1
$ sbin/nginx -s stop

校验

1
$ curl localhost
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

修改配置文件

1
$ vim nginx.conf

重新加载配置文件

1
$ sbin/nginx -s reload

查看日志

1
2
3
4
5
# 查看流量详情
$ tail -f logs/access.log

# 查看异常日志
$ tail -f logs/error.log

流量镜像

Upstream 模块

 通过 upstream 模块,可以将源地址(当前集群)和镜像地址(目标集群)分组

1
2
3
4
5
6
7
8
9
10
11
upstream curr {
server 192.168.0.101:8080;
server 192.168.0.102:8080;
keepalive 64;
}

upstream dest {
server 192.168.0.103:8080;
server 192.168.0.104:8080;
keepalive 64;
}

Server 模块

 如下定义了当前 Nginx 进程(localhost)监听的端口(80

1
2
3
4
5
server {
listen 80;
server_name localhost;
# ...
}
注意观察 logs/error.log 日志,检查是否出现端口冲突的日志,以调整这里面的端口号

Location 模块

 server 模块下的 location 模块,可以定义流量转发的规则,location / 会接受所有 Nginx 进来的流量,而 mirror /mirror; 会将流量转发到镜像地址,而 location /mirror 则定义了转发的规则

1
2
3
4
5
6
7
8
9
10
11
12
13
location / {
root html;
index index.html index.htm;
mirror /mirror;
mirror_request_body on;
proxy_pass http://curr;
}

location /mirror {
internal;
proxy_pass http://dest$request_uri;
proxy_set_header X-Original-URI $request_uri;
}

完整示例

本地转发

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
#user              nginx;
worker_processes auto;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

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 logs/access.log main;
sendfile on;

keepalive_timeout 65;

upstream curr {
server localhost:8080;
keepalive 64;
}

server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
root html;
index index.html index.htm;
mirror_request_body on;
proxy_pass http://curr;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

集群间转发

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
#user              nginx;
worker_processes auto;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

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 logs/access.log main;
sendfile on;

keepalive_timeout 65;

upstream curr {
server 192.168.0.101:8080;
server 192.168.0.102:8080;
keepalive 64;
}

upstream dest {
server 192.168.0.103:8080;
server 192.168.0.104:8080;
keepalive 64;
}

server {
listen 80;
server_name localhost;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {
root html;
index index.html index.htm;
mirror /mirror;
mirror_request_body on;
proxy_pass http://curr;
}

location /mirror {
internal;
proxy_pass http://dest$request_uri;
proxy_set_header X-Original-URI $request_uri;
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

轮询策略

RR

 按时间顺序逐一将请求发送到不同的服务器,并且服务器故障后,会被自动剔除

1
2
3
4
upstream yuzhouwan {
server 192.168.0.101:80 max_fails=3 fail_timeout=3s weight=9;
server 192.168.0.102:80 max_fails=3 fail_timeout=3s weight=9;
}
Nginx 默认会采用 RR(round-robin)简单轮询策略

balance

 支持指定轮询的几率,参数 weight 的数值和访问几率成正比,常用于集群中服务器资源不均的场景

1
2
3
4
upstream yuzhouwan {
server 192.168.0.101:80 weight=6;
server 192.168.0.102:80 weight=1;
}

ip_hash

 按访问 ip 的 hash 结果将请求发送到不同的服务器,这样每个访客固定访问一个后端服务器。可以在 Session 有状态情况下,避免请求被转发到不同的服务器后,需要重复登录的问题

1
2
3
4
5
upstream yuzhouwan {
ip_hash;
server 192.168.0.101:80;
server 192.168.0.102:80;
}

fair

 按服务器的响应时间来分配请求,响应时间短的优先分配

1
2
3
4
5
upstream yuzhouwan {
fair;
server 192.168.0.101:80;
server 192.168.0.102:80;
}

url_hash

 按访问 url 的 hash 结果来分配请求,可以充分发挥服务器上缓存的作用

1
2
3
4
5
6
upstream yuzhouwan {
hash $request_uri;
hash_method crc32;
server 192.168.0.101:80;
server 192.168.0.102:80;
}

踩过的坑

client intended to send too large body

分析

 Nginx 默认不允许发送超过 1MB 的请求体,由 client_max_body_size 参数控制

解决

1
$ vim nginx.conf
1
2
3
4
http {
client_max_body_size 10M;
# ...
}
1
$ sbin/nginx -s reload

补充

参数名 含义 默认值 作用域
chunked_transfer_encoding 是否开启 HTTP/1.1 下的 chunked 编码 on http, server, location
client_header_buffer_size 请求头的大小限制 1k http, server
client_body_timeout 读取请求体的超时限制 60s http, server, location

欢迎加入我们的技术群,一起交流学习

群名称 群号
人工智能(高级)
人工智能(进阶)
BigData
算法