Nginx之旅-架构篇-常见问题

相同server_name多个虚拟主机读取的优先级

问题场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name testserver1 www.imooc.com;
location {
...
}
}

server {
listen 80;
server_name testserver2 www.imooc.com;
location {
...
}
}

上面有两个server具有相同的server_name。

优先级顺序为读取到的配置文件的优先级,几多个虚拟主机具有相同server_name的情况下会优先使用最先读取到的配置文件(哪个虚拟主机的配置文件先读到,就用哪个)。

一个虚拟主机下多个location匹配优先级

匹配顺序如下:

1
2
3
=	进行普通字符精确匹配,也就是完全匹配
^~ 表示普通字符匹配,使用前缀匹配
~\~* 表示执行一个正则匹配()

前两个为精确匹配,匹配到之后就不再往下匹配。

第三个为正则匹配,即使匹配到也会往下匹配,查看是否存在更加精准的匹配,如果没有就会使用第一次的匹配结果。其中~*表示不区分大小写,~区分大小写。

我们看下老师的🌰

1
2
3
4
5
6
7
8
9
10
11
location = /code1/ {
rewrite ^(.*)$ /code1/index.html break;
}

location ~ /code.* {
rewrite ^(.*)$ /code3/index.html break;
}

location ^~ /code {
rewrite ^(.*)$ /code2/index.html break;
}

上面如果我们直接访问/code1/访问到的是第一个location,我们把第一个注释掉的情况下,访问到的将会是第三个location。这是因为正则匹配的优先级没有^~高。

Nginx的try_files的使用

按顺序查找文件是否存在,如果存在则返回文件内容,如果不存在则会对路径进行对应的规则。

1
2
3
location / {
try_files $uri $uri/ /index.php
}

上面配置的含义是我们访问一个uri的时候先去查找是否存在,如果不存在则会为uri添加一个/后缀。如果加了后缀还不存在则会返回/index.php文件。

我们看下老师的🌰:

1
2
3
4
5
6
7
8
9
location / {
root /opt/app/code;
try_files /cache $uri @java_page;
}


location @java_page{
proxy_pass http://127.0.0.1:9090;
}

上面配置的含义是将请求先放到/cache下查找,如果查找不到再去访问uri如果还是找不到再去查找下面的location

适用场景:让用户先去访问缓存文件区,如果缓存不存在再去请求逻辑区。

Nginx的alias和root区别

root是用于指定程序的目录位置。

我们看下root的请求

1
2
3
4
5
6
7
8
9
location /request_path/image/ {
root /local_path/image/;
}

# 我们访问下面一个url
http://www.imooc.com/request_path/image/cat.png

# 实际访问的地址为
/local_path/image/request_path/image/cat.png

实际访问地址就是root指定路径和请求路径的结合。

再看下alias的请求

1
2
3
4
5
6
7
8
9
10
location /request_path/image/ {
alias /local_path/image/;
}

# 我们访问下面一个url
http://www.imooc.com/request_path/image/cat.png


# 实际请求路径
/local_path/image/cat.png

实际访问地址是alias指定地址和文件地址结合(除了location匹配)。

如何获取用户真实的ip信息

ruTRIK.png

当一个用户经过多层代理的时候,如果获取到用户真实的IP呢?

在第一级代理的时候,告诉代理设置一个请求头给传过来

1
2
3
4
5
在一级代理设置 放到头信息中
set x_real_ip = $remote_addr

在服务器中获取到头信息
$x_real_ip=IP1
Nginx中常见错误码
1
2
3
4
5
6
7
8
Nginx: 413 Request Entity Too Large  表示用户请求数据过大
解决方式对文件上传进行限制 修改 client_max_body_size

502 bad gateway 后端服务无响应
tomcat关闭等原因

504 Gateway Time-out 后端服务执行超时
后端服务是执行,但是可能是连接数据库耗时太长或其他原因导致超时 超过Nginx的默认等待时间是60s
Nginx的性能优化
性能优化考虑点
  1. 当前系统结构瓶颈

    观察指标、压力测试

  2. 了解业务模式

    接口业务类型、系统层次化结构

  3. 性能与安全

ab接口压力测试工具

1、安装

1
[root@xiaoyang ~]# yum install httpd-tools

2、使用

1
2
3
4
5
[root@xiaoyang ~]# ab -n 2000 -c 2 http://127.0.0.1/

-n 总的请求次数
-c 并发数
-k 是否开启长连接
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
[root@xiaoyang ~]# ab -n 100 -c 10 https://www.bilibili.com/
# 请求100 次 并发 10
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.bilibili.com (be patient).....done


Server Software:
Server Hostname: www.bilibili.com # 域名
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-RSA-AES128-GCM-SHA256,2048,128

Document Path: / # 路由
Document Length: 177 bytes

Concurrency Level: 10
Time taken for tests: 4.722 seconds # 总耗时
Complete requests: 100
Failed requests: 31
(Connect: 0, Receive: 0, Length: 31, Exceptions: 0)
Write errors: 0
Non-2xx responses: 100
Total transferred: 69484 bytes
HTML transferred: 17852 bytes
Requests per second: 21.18 [#/sec] (mean) # 每秒处理请求数
Time per request: 472.151 [ms] (mean) # 客户端请求服务器耗时
Time per request: 47.215 [ms] (mean, across all concurrent requests) # 服务器处理客户端请求耗时
Transfer rate: 14.37 [Kbytes/sec] received

nginx访问静态资源的时候,是不需要后台服务进行资源处理的(静态资源应该有nginx直接处理)

系统与Nginx的性能优化

网络、系统、服务、程序、数据库、底层服务

文件句柄设置

文件句柄

Linux/Unix中一切皆文件,文件句柄就是一个索引

每次请求都会新建一个文件句柄,而对于操作系统来说这个文件句柄不是无限大的,有默认值。

设置方式

系统全局性修改、用户局部性修改、进程局部性修改

对于全局修改 在文件/etc/security/limits.conf中我们看下如下配置

1
2
3
4
5
* soft nofile 100001 # 全局用户 软连接 文件句柄设置为 100001 超出也没事
* hard nofile 100002

root soft nofile 100001
root hard nofile 100002 # 针对root 用户 硬连接 文件句柄 100002

我们也可以针对Nginx进程单独设置,比如在/etc/nginx/nginx.conf配置文件中加入如下配置

1
worker_rlimit_nofile 65535;
CPU亲和配置

CPU的亲和:进程通常不会在处理器之间频繁的迁移,减少性能损耗。

查看主机的物理CPU个数

1
2
[root@xiaoyang ~]# cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
1

查看CPU的核数

1
2
[root@xiaoyang ~]# cat /proc/cpuinfo | grep "cpu cores" | uniq
cpu cores : 1

1 * 1 核

rQ0QQU.png

基于Nginx架构的安全篇
恶意行为控制手段
  1. 常见的恶意行为

    爬虫行为和恶意抓取、资源盗用

下面是三种常用的恶意行为控制手段:

基础防盗链功能–目的不让恶意用户能够轻易爬取网站对外数据

secure_link_module–对数据安全性提高 加密验证和失效性 适合核心重要数据

access_module–对后台、部分用户服务的数据提供IP防控

攻击手段之暴力破解
  1. 常见的攻击手段

    后台密码撞库–通过猜测密码字典不断对后台系统尝试性登录,从而获取后台登录密码

防范手段:

方法一:加大后台登录密码的复杂度

方法二:access_module对后台登录IP进行防控

方法三:预警机制(检测到多次登录不成功就告警)

文件上传漏洞–利用这些可以上传的接口将恶意代码植入到服务器中,再通过url去访问以执行代码

如将一些恶意的php代码放到伪造好的照片之中,然后上传到服务器。
r1vYND.png

SQL注入–利用未过滤/未审核用户输入的攻击方法,让应用运行本不应该运行的SQL语句。

r3SvKs.png

# 在SQL中代表着注释

Nginx+LUA实现waf防火墙

r3pFGF.png

一个大牛的waf项目:https://github.com/loveshell/ngx_lua_waf

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!