Nginx 常见问题汇总
Nginx多Server优先级
- 在开始处理一个http请求时,nginx会取出header头中的Host变量,与nginx.conf中每个server的server_name进行匹配,以此决定到底由哪一个server来处理这个请求。但nginx如配置多个相同的server_name,会导致server_name出现优先级访问冲突。
- web01服务器(192.168.15.7)
1. 创建配置文件server1
vim /etc/nginx/conf.d/server1.conf
server {
listen 80;
server_name localhost test1.com; # localhost,允许本地的ip地址访问
location / {
root /code/test1;
index index.html;
}
}
2. 创建配置文件server2
vim /etc/nginx/conf.d/server2.conf
server {
listen 80;
server_name localhost test2.com; # localhost,允许本地的ip地址访问
location / {
root /code/test2;
index index.html;
}
}
3. 创建配置文件server3
vim /etc/nginx/conf.d/server3.conf
server {
listen 80;
server_name localhost test3.com; # localhost,允许本地的ip地址访问
location / {
root /code/test3;
index index.html;
}
}
4. 创建配置文件指定的数据文件
mkdir /code/test{1..3}
echo "test1" > /code/test1/index.html
echo "test2" > /code/test2/index.html
echo "test3" > /code/test3/index.html
5. 重启nginx服务
nginx -t
systemctl restart ngix
- 测试
添加域名解析
192.168.15.7 test1.com test2.com test3.com
我们在浏览器输入域名都是可以正常访问到我们想要的页面,但是我们输入web01服务器的ip地址,访问页面显示的是test1。
我们删除server1.conf文件,刷新浏览器,页面显示的是test2。
原因:
我们配置文件是通过域名来进行匹配的。如果我们在浏览器中输入ip地址,是无法进行域名匹配的。
Nginx默认会把/etc/nginx/conf.d目录下,以.conf结尾的最靠前的server_name的匹配文件发给浏览器。
多个ServerName优先级总结,在开始处理一个HTTP请求时,Nginx会读取header(请求头)的host,与每个Server_name进行匹配,来决定哪一个Server标签来完成处理这个请求。有可能一个Host与多个server中的server_name都匹配,这个时候就会更具匹配优先级来选择处理实际处理的server块。优先级匹配总结如下:
- 首先选择所有的字符串完全匹配的server_name(完全匹配)
- 选择通配符在前面的server_name,如".nana.com"
- 选择通配符在后面的server_name,如"nana.*"
- 最后选择使用正则表达式匹配的server_name
- 如果全部都没有匹配到,那么将选择在listen配置项后加入[default_server]的server块
- 如果没写,那么就找到匹配的listen端口的第一个Server块的匹配文件
如果公司有很多域名,但是域名相关的站点并没有响应的网站,例如:
abc.jd.com ,www.jd.com ====> 192.168.15.7 ====> 跳转官网
我们可以在192.168.15.7服务器的server_name写上*.jd.com;location匹配写入公司的官网。
Nginx禁止IP地址访问或者导流
如何通过default_server
禁止用户通过IP地址访问,或使用default_server
进行导流。
1.禁止直接通过IP访问
vim /etc/nginx/conf.d/server4.conf
server {
listen 80 default_server;
server_name _;
return 503;
}
2.导流(跳转到公司的官网)
vim /etc/nginx/conf.d/server4.conf
server {
listen 80 default_server;
server_name _;
return 302 https://zh.nana.com;
}
Nginx Include简化主配置文件
一台服务器配置多个网站,如果配置都写在nginx.conf主配置文件中,会导致nginx.conf主配置文件变得非常庞大而且可读性非常的差。那么后期的维护就变得麻烦。
假设现在希望快速的关闭一个站点,该怎么办?
- 如果是写在nginx.conf中,则需要手动注释,比较麻烦
- 如果是include的方式,那么仅需修改配置文件的扩展名,即可完成注释
Include包含的作用是为了简化主配置文件,便于人类可读。
方式一:
- 主配置文件
vim /etc/nginx/nginx.conf
...
http {
...
include /etc/nginx/conf.d/*.conf; # /etc/nginx/conf.d/下的所有文件都导入到http层
}
方式二:
include /etc/nginx/online/*.conf # 线上使用的配置
/etc/nginx/offline # 保留配置,不启用(下次使用再移动到online)
Nginx路径root与alias
root与alias路径匹配主要区别于nginx如何解释location后面的uri,这会式两者分别以不同的方式将请求映射到服务器文件上,alias是一个目录别名的定义,root则是最上层目录的定义。
- root的处理结果是:root路径+location路径
- alias的处理结果是:直接使用alias定义的路径
root处理结果
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/images.conf root路径+location路径
server {
listen 80;
server_name images.nana.com;
location /images {
root /code; # 将文件放在/code/images目录下
}
}
2. 在Nginx配置文件指定的目录下放置图片:test.jpg
cd /code/images/
rz -E test.jpg
3. 重启Nginx服务
systemctl restart nginx
- 测试
域名解析: 192.168.15.7 images.nana.com
访问路径http://images.nana.com/images/test.jpg ==> 正常访问到图片
alias处理结果
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/images.conf 直接上alias定义的路径中查找
server {
listen 80;
server_name images.nana.com;
location /images {
alias /code; # 将root改成alias,将文件直接放在/code目录下
}
}
2. 将Nginx指定目录下的文件路径做更改
mv /code/images/test.jpg /code/
# 将文件从root路径+location路径移动到alias定义的路径,访问的url路径是不变的
3. 重启Nginx服务
systemctl restart nginx
- 测试
域名解析: 192.168.15.7 images.nana.com
访问路径http://images.nana.com/images/test.jpg ==> 正常访问到图片
root+alias使用
vim /etc/nginx/conf.d/images.conf
server {
listen 80;
server_name images.nana.com
location / {
root /code; # 将数据放在code目录下
}
location ~* ^.*\.(png|jpg|gif)$ {
alias /code/images; # 将图片数据直接放在/code/images目录下
}
}
Nginx try_file路径匹配
nginx的try_file路径匹配,按顺序检查文件是否存在
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/try_file.conf
server {
listen 80;
server_name try.nana.com;
root /code;
index index.html;
location / {
try_files $uri $uri/ /500.html;
# 先匹配文件名,文件名匹配失败再匹配目录下的文件,如果都匹配失败则返回文件/500.html
}
}
$uri 匹配文件名,用户访问try.nana.com(默认会加/) ==查询==> /code ==查询==> / (/code目录下没有/,匹配失败)
用户访问try.nana.com/index.html ==查询==> /code/index.html
$uri/ 匹配目录下的文件,用户访问try.nana.com/ ==查询==> /code/index.html
2. 创建Nginx配置文件指定的数据
echo "index_try" > /code/index.html
echo "500" > /code/500.html
3. 重启Nginx服务
nginx -t
systemctl restart nginx
- 测试
我们按照该配置文件进行配置,我们请求try.nana.com/index.html和try.nana.com都可以访问到"index_try"
请求其他的url地址,那么是匹配不上的,会抛出500
uri与uri/的区别
$uri
匹配文件名,如果用户请求try.nana.com/index.html
。那么$uri
则会再对应的root指定的站点目录中查找是否存在该文件$uri/
匹配目录下的文件,如用户请求try.nana.com/
,那么$uri则会上/对应root指定的站点目录中查找文件
当用户访问try.nana.com/index.html则由Nginx提供服务,如果Nginx没有该文件则由Tomcat服务提供
- web01服务器
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/try_file.conf
server {
listen 80;
server_name try.nana.com;
root /code;
index index.html;
location / {
try_files $uri $uri/ @java_page;
}
location @java_page {
proxy_pass http://192.168.15.8:8080; # Tomcat运行在Web02服务器上
}
}
2. 创建Nginx目录指定的数据
echo "Nginx" > /code/index.html
切换到web02服务器
cd /usr/share/tomcat/webapps/ROOT/
echo "Tomcat" > index.html
systemctl restart tomcat
- 测试
我们正常访问try.nana.com或者try.nana.com/index.html,页面的输出结果都是Nginx。
我们删除Web01服务器的/code/index.html,访问try.nana.com/index.html,页面的输出结果为Tomcat。
如果直接访问try.nana.com,页面报错403(找不到主页,权限不足)。
Nginx优雅显示错误页面
将报错的响应状态码转换成图片,增加用户体验度
- web01服务器
1. 修改Nginx配置文件
vim /etc/nginx/conf.d/error.conf
server {
listen 80;
server_name try.nana.com;
root /code;
location / {
index index.html;
}
error_page 403 404 /40x.jpg; # 浏览器抛出403或者404报错,匹配location(/40x.jpg)
location = /40x.jpg { # 精确匹配,匹配优先级最高。
root /code/error; # 去/code/error目录下找/40x.jpg文件
}
}
2. 创建Nginx配置文件指定目录下的数据
cd /code/error
rz -E 40x.jpg
3. 重启Nginx服务
nginx -t
systemctl restart nginx
- 测试
我们打开浏览器输入:try.nana.com/aaa(错误url地址),浏览器不会直接抛出异常的响应状态码,页面显示我们上传的图片。
我们的web服务在负载均衡的情况下,只需要在web服务节点配置error_page
即可,如图所示:
- web01服务器
1. 创建Nginx配置文件
vim /etc/nginx/conf.d/error.conf
server {
listen 80;
server_name err.nana.com;
root /code;
location / {
index index.html;
}
error_page 404 /40x.jpg;
}
2. 创建Nginx配置文件指定目录下的数据
mv /code/error/40x.jpg /code
mv /code/index.html /code
3. 重启Nginx服务
nginx -t
systemctl restart nginx
- lb01服务
1. 配置Nginx负载均衡服务
vim /etc/nginx/conf.d/proxy_err.conf
upstream err {
server 172.16.1.7:80;
}
server {
listen 80;
server_name err.nana.com;
location / {
proxy_pass http://err;
include proxy_params;
}
}
2. 重启Nginx服务
nginx -t
systemctl restart nginx
- 测试
我们向浏览器请求err.nana.com,浏览器返回页面Nginx。
我们向浏览器请求错误的url地址,浏览器不会直接抛出异常的响应状态码,页面显示我们上传的图片