0%

Nginx入门篇

Nginx是什么?

Nginx (engine x) 是一个高性能的HTTP静态页面服务器,更是一个常用的反向代理服务器,同时还可以作为IMAP/POP3/SMTP代理服务器。

经常使用Nginx服务器,进行一些简单配置,但只是从网上照抄,知其然不知其所以然。
本文,我们主要学习一下nginx的目录结构和基础规则,补一补nginx基础。

目录结构

因为nginx目录是可以指定的,所以真实使用的目录结构请以命令查看。
ps aux | grep nginx

配置目录

可能的默认配置目录:

1
2
/etc/nginx/
/etc/nginx/conf

nginx.conf一般放在这两个目录中,nginx.conf中会写清楚子配置目录,比如:

1
2
3
http {
include /etc/nginx/conf.d/*.conf;
}

那么,子配置文件就放在 /etc/nginx/conf.d/ 目录中,并且子配置文件必须以 .conf 结尾。一般情况下,我们比较少修改 nginx.conf,大部分时候都是修改子配置文件。

根目录

可能的默认根目录:

1
/usr/share/nginx/html

根目录下一般会有nginx自带的index.html和50x.html。

curl ${nginx_server}时看到内容,就是index.html文件中的内容。

我们自己的静态页面项目,最好不要放到默认根目录下,因为默认根目录可以通过ip和路径访问到,这往往是不符合预期的。
推荐的静态页面项目目录为:/usr/share/nginx/work

日志目录

可能的默认日志目录:

1
/var/log/nginx

日志文件中一般有两个日志文件,error.log和access.log。

常见配置

静态页面服务器配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name www.voidking.com;
charset utf-8;

location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

root /usr/share/nginx/html/;
index index.html;
}
}

这个配置,是一个标准的静态页面服务器配置。
使用以上配置,如果已经配置好了域名解析,那么访问 www.voidking.com 时,就会看到nginx首页,也就是 index.html。

反向代理到其他域名

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
server_name www.voidking.com;
charset utf-8;

location / {
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://voidking.coding.me;
}
}

使用以上配置,访问 www.voidking.com 时,实际上看到的是 voidking.coding.me 这个域名返回的内容。

反向代理到一个服务

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
listen 80;
server_name www.voidking.com;
charset utf-8;

location / {
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://192.168.56.101:8080;
}
}

使用以上配置,访问 www.voidking.com 时,实际上看到的是 192.168.56.101:8080 这个服务返回的内容。

反向代理到upstream

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
upstream www_voidking_com{
server 192.168.56.101:8080 weight=5;
server 192.168.56.102:8081 weight=2;
server 192.168.56.103:8000;
}

server {
listen 80;
server_name www.voidking.com;
charset utf-8;

location / {
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://www_voidking_com;
}
}

使用以上配置,访问 www.voidking.com 时,实际上看到的是upstream里的服务返回的内容。
但是问题来了,upstream里有三个服务,到底是哪个服务返回的内容呢?答:不一定,这就要用到传说中的加权轮询算法了。
三个服务的权值分别为 5、2、1(默认),从权值来看,最大可能打到第一个服务。
有没有想到什么知识点?没错,负载均衡,使用了加权轮询算法的负载均衡。

反向代理到websocket服务

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
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80;
server_name www.voidking.com;
charset utf-8;

location ^~ /ws {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# websocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

proxy_pass http://192.168.56.101:8080;
}

location / {
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://192.168.56.101:8080;
}
}
}

更多内容参考一篇带给你Nginx代理WebSocket方法NGINX as a WebSocket Proxy

四层代理

nginx四层代理依赖ngx_stream_core_module模块(nginx参数为--with-stream),在nginx1.22.0以上版本已经默认支持并开启ngx_stream_core_module模块。

1
nginx -V

如果是低版本的nginx,需要自行编译并开启ngx_stream_core_module模块。

一个四层代理的实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
http {
upstream remote_mysql {
host $remote_addr consistent; # 通过配置一致性 hash 来防止调度异常
server 192.168.1.1:3306;
}

server {
listen 3306 so_keepalive=on; # 开始TCP存活探测
proxy_connect_timeout 10s; # 连接超时时间
proxy_timeout 300s; # 端口保持时间
proxy_pass remote_mysql;
}
}

基础规则

location规则

在常见配置中,我们看到了一个叫 location 的关键字。location规则为:

1
location [ = | ~ | ~* | ^~ ] /uri/ { ... }

紧跟在location后面的,是可选的修饰符,uri是要匹配的字符串。

常见匹配:

  • location = /uri 精确匹配
  • location ^~ /uri 前缀匹配,在正则匹配之前
  • location ~ pattern 正则匹配,区分大小写
  • location ~* pattern 正则匹配,不区分大小写
  • location /uri 前缀匹配,在正则匹配之后
  • location / 通用匹配,未匹配到其它location的请求会匹配到它

详情参考location 匹配规则

匹配规则

匹配过程:
1、精确匹配
2、前缀匹配(^~
3、正则匹配(按配置顺序)
4、前缀匹配(/xxx
5、通用匹配

其中前缀匹配如果有包含关系时,遵循最大匹配原则。

proxy_pass规则

如果nginx作为反向代理使用,那么必须要搞明白的就是proxy_pass的规则,这关系到请求能否打到正确的接口。
proxy_pass规则:

  • 如果proxy_pass后面没有路径,那么转发时带上uri
  • 如果proxy_pass后面有路径,那么转发时使用该路径替换匹配到的uri

保留uri

1
2
3
4
5
6
7
location  /test {
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://192.168.56.101:8080;
}

访问 www.voidking.com/test/index 会被代理到 http://192.168.56.101:8080/test/index 这个url,/test/index 被保留转发给了后端服务。

去掉uri

1
2
3
4
5
6
7
location  /test {
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://192.168.56.101:8080/;
}

访问 www.voidking.com/test/index 会被代理到 http://192.168.56.101:8080/index 这个url,/test 被去掉了。

替换uri

1
2
3
4
5
6
7
location  /test {
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://192.168.56.101:8080/qa/;
}

访问 www.voidking.com/test/index 会被代理到 http://192.168.56.101:8080/qa/index 这个url,/test/index 被替换成了 /qa/index,然后转发给了后端服务。

1
2
3
4
5
6
7
location  /test {
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://192.168.56.101:8080/qa;
}

访问 www.voidking.com/test/index 会被代理到 http://192.168.56.101:8080/qaindex 这个url,/test/index 被替换成了 /qaindex,然后转发给了后端服务。

常用命令

测试配置

nginx -t

重新加载配置

nginx -s reload

map指令

map 的作用是创建自定义变量。

语法:

1
map $var1 $var2 {...}

map 的var1为源变量,通常是nginx的内置变量,var2 是自定义变量。 var2 的值取决于 var1 在对应表达式的匹配情况。如果一个都匹配不到则 var2 就是 default 对应的值。

例子:

1
2
3
4
map $args $foo {
default 0;
debug 1;
}

args 是nginx内置变量,就是获取的请求 url 的参数。 如果 args 匹配到 debug 那么 foo 的值会被设为 1 ,如果 args 一个都匹配不到 foo 就是 default 定义的值,在这里就是 0

参考文档Nginx map 使用详解

rewrite指令

rewrite指令的作用是重定向。

语法:

1
rewrite regex replacement [flag];
  • rewrite:该指令是实现URL重写的指令。
  • regex:用于匹配URI的正则表达式。
  • replacement:将regex正则匹配到的内容替换成 replacement。
  • flag: flag标记。

flag有如下值:

  • last: 本条规则匹配完成后,继续向下匹配新的location URI 规则。(不常用)
  • break: 本条规则匹配完成即终止,不再匹配后面的任何规则(不常用)。
  • redirect: 返回302临时重定向,浏览器地址会显示跳转新的URL地址。
  • permanent: 返回301永久重定向。浏览器地址会显示跳转新的URL地址。

例子:

1
rewrite ^/(.*) http://www.baidu.com/$1 permanent;
  • rewrite 是固定关键字,表示开始进行rewrite匹配规则。
  • regex 是 ^/(.*),这是一个正则表达式,匹配完整的域名和后面的路径地址。
  • replacement 是 http://www.baidu.com/$1,其中$1是取regex部分()里面的内容,如果匹配成功后跳转到的URL
  • flag 是 permanent,代表永久重定向的含义,即跳转到 http://www.baidu.com/$1

参考文档Nginx中的Rewrite的重定向配置与实践

状态码

  • 1xx:信息响应类,表示接收到请求并且继续处理
  • 2xx:处理成功响应类,表示动作被成功接收、理解和接受
  • 3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理
  • 4xx:客户端错误,客户请求包含语法错误或者是不能正确执行
  • 5xx:服务端错误,服务器不能正确执行一个正确的请求

详情参考HTTP 状态码详解与选用

  • 本文作者: 好好学习的郝
  • 本文链接: https://www.voidking.com/dev-nginx-start/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!源站会及时更新知识点及修正错误,阅读体验也更好。欢迎分享,欢迎收藏~