Nginx配置⽂件
Nginx主配置⽂件 /etc/nginx/nginx.conf 是⼀个纯⽂本类型的⽂件,整个配置⽂件是以区块的
形式组织的。⼀般,每个区块以⼀对⼤括号 {} 来表示开始与结束。- Main位于nginx.conf配置⽂件的最⾼层
- Main层下可以有Event、HTTP层
- HTTP层下⾯有允许有多个Server层, ⽤于对不同的⽹站做不同的配置
- Server层也允许有多个Location, ⽤于对不同的路径进⾏不同模块的配置
- nginx默认配置语法
user nginx; # 设置nginx服务的系统使⽤⽤户
worker_processes auto; # ⼯作进程,配置和CPU个数保持⼀致
error_log /var/log/nginx/error.log notice; # 错误⽇志,后⾯接⼊的是存放文件路径
pid /var/run/nginx.pid; # Nginx服务启动时的pid,,后⾯接⼊的是存放文件路径
events {
worker_connections 1024;
}
# ⾮虚拟主机的配置或公共配置定义在http{}段内, server{}段外
http {
# 必须使⽤虚拟机配置站点, 每个虚拟机使⽤⼀个server{}段
server {
listen 80; # 监听端⼝, 默认80
server_name localhost; # 提供服务的域名或主机名
#控制⽹站访问路径
location / {
root /usr/share/nginx/html; # 存放⽹站路径
index index.html index.htm; # 默认访问⾸⻚⽂件
}
# 指定错误代码, 统⼀定义错误⻚⾯, 错误代码重定向到新的Locaiton
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
# 第⼆个虚拟主机配置
server {
}
}
Nginx⽇志配置规范
配置语法包括
- access.log
- error.log
Nginx默认日志格式设置
log_format main '$remote_addr - $remote_user [$time_local] "$request"' '$status $body_bytes_sent "$http_referer"' '"$http_user_agent" "$http_x_forwarded_for"';
Nginx⽇志变量
参数 | 说明 |
---|---|
$remote_addr | 客户端地址 |
$remote_user | 客户端用户名称 |
$time_local | 访问时间和时区 |
$request | 请求的URI和HTTP协议 |
$http_host | 请求地址,即浏览器中你输入的地址(IP或域名) |
$status | HTTP请求状态 |
$upstream_status | upstream状态 |
$body_bytes_sent | 发送给客户端文件内容大小 |
$http_referer | url跳转来源 |
$http_user_agent | 用户终端浏览器等信息 |
$ssl_protocol | SSL协议版本 |
$ssl_cipher | 交换数据中的算法 |
$upstream_addr | 后台upstream的地址,即真正提供服务的主机地址 |
$request_time | 整个请求的总时间 |
$upstream_response_time | 请求过程中,upstream响应时间 |
Nginx状态监控
- 开启Nginx监控模块 (--with-http_stub_status_module)
具体配置如下
location /mystatus { stub_status on; access_log off; }
状态监控结果
Active connections: 2 server accepts handled requests 2 2 1 Reading: 0 Writing: 1 Waiting: 1
状态监控结果详细解读
Active connections: 2
当前nginx正处理的活动连接数server accepts handled requests 3 3 10
总共处理了3次连接,成功创建了3次连接,共请求了10次。总连接数-成功连接数为失败连接数Reading: o Writing: 1 Waiting: 1
- reading为nginx读取到客户端的header信息数
- Writing为nginx返回给客户端的Header信息数,Waiting开启 keep-alive的情况下,这个值等于active-(reading+writing),意思指nginx已经处理完正在等候下一次请求的驻留连接
Nginx下载站点
autoindex常⽤参数
autoindex_exact_size off;
- 默认为on, 显示出⽂件的确切⼤⼩,单位是bytes。
- 修改为off,显示出⽂件的⼤概⼤⼩,单位是kB或者MB或者GB。
autoindex_localtime on;
- 默认为off,显示的⽂件时间为GMT时间。
- 修改为on, 显示的⽂件时间为⽂件的服务器时间。
charset utf-8,gbk;
- 默认中⽂⽬录乱码,添加上解决乱码
- 配置⽬录浏览功能
location /www {
#root /data;
alias /data/www/; # 指定目录
autoindex on; # 列出整个目录列表
autoindex_localtime on; # 显示的文件时间为文件的服务器时间
charset utf-8,gbk; # 解决中文乱码
autoindex_exact_size off; # 以kB或者MB或者GB单位显示出文件的大小,而不是字节
}
Nginx访问限制
- nginx 文档地址
- ngx_http_limit_req_module 模块文档地址
- 配置
http { # http段配置请求限制, rate限制速率,限制⼀秒钟最多⼀个IP请求 limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s; server {} }
key
定义用于限制请求的变量,在这个示例中使用的是NGINX的自带变量 $binary_remote_addr(客户端的ip地址)zone
定义用于存储前面定义的key变量,如zone=mylimit:10m 就是一个名为mylimit的大小为10m的共享内存空间rate
允放相同标识的客户端的访问频次, 在这个例子中:就是同一个ip地址在每秒内只能访问1次
使用
server { location / { # limit_req zone=req_zone; # limit_req zone=perip burst=2; limit_req zone=perip burst=2 nodelay; } }
burst
如上例子burst=2,允许2个突发,有大量请求时,超过频次限制的请求,会允许2个访问,注意:burst指定的请求数量,不会马上进行处理,而是按照rate指定的值,以固定的速率进行处理。nodelay
只是对放到burst队列中的请求立即处理,但处理完成后队列并不立即清空,队列清空的速度仍然按原来的速度每秒一个清空,所以当再有请求过来时,并不会马上又有两个burst请求被处理。
安装压力测试,以每秒处理1个请求的速率做限制
limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
# centos sudo yum install -y httpd-tools # ubuntu sudo apt-get install -y apache2-utils
测试1
location / { root /usr/share/nginx/html; index index.html index.htm; limit_req zone=req_zone; }
测试1重启nginx后执行ab
vagrant@swarm3:/etc/nginx$ ab -n 10 -c 10 http://192.168.56.3/ Concurrency Level: 10 Time taken for tests: 0.002 seconds Complete requests: 10 Failed requests: 9 (Connect: 0, Receive: 0, Length: 9, Exceptions: 0)
- 只有一个成功,有9个请求失败,时长是0.002 seconds,同一个ip地址在每秒内只能访问1次
测试2
location / { root /usr/share/nginx/html; index index.html index.htm; limit_req zone=req_zone burst=2; }
测试2重启nginx后执行ab
vagrant@swarm3:/etc/nginx$ ab -n 10 -c 10 http://192.168.56.3/ Concurrency Level: 10 Time taken for tests: 2.001 seconds Complete requests: 10 Failed requests: 7 (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
- 有7个请求失败,注意时间变成了2.001 seconds,burst=2允许2个突发, 有大量请求时,超过频次限制的请求,会允许2个访问,burst指定的请求数量, 不会马上进行处理, 而是按照rate指定的值,以固定的速率进行处理。
测试3
location / { root /usr/share/nginx/html; index index.html index.htm; limit_req zone=req_zone burst=2 nodelay; }
测试3重启nginx后执行ab
vagrant@swarm3:/etc/nginx$ ab -n 10 -c 10 http://192.168.56.3/ Concurrency Level: 10 Time taken for tests: 0.002 seconds Complete requests: 10 Failed requests: 7 (Connect: 0, Receive: 0, Length: 7, Exceptions: 0)
- 有7个请求失败,注意时间:这次是0.002 seconds,burst的队列虽然可以处理用户的需求,但需要用户按照处理时间等待, 对用户不够友好, nodelay参数允许请求在排队的时候就立即被处理, 这里有一点要注意:因为nodelay允许立即处理,也就是有并发请求时,事实上已经超过了rate设置的处理速率了, 所以要根据机器的实际情况设置这个值
Nginx连接限制
- Nginx连接限制类似于Nginx请求限制,这里不再过多介绍,需要了解使用请移步ngx_http_limit_req_module 连接限制模块文档
连接限制没有请求限制有效?
- 多个请求可以建⽴在⼀次的TCP连接之上, 那么我们对请求的精度限制,当然⽐对⼀个连接的限制会更加的有效。
- 因为同⼀时刻只允许⼀个连接请求进⼊,但是同⼀时刻多个请求可以通过⼀个连接进⼊,所以请求限制才是⽐较优的解决⽅案。
Nginx访问控制
文档地址
基于IP的访问控制
配置拒绝某⼀个IP, 其他全部允许
location / { deny 192.168.56.1; allow all; }
只允许某⼀个⽹段访问,其它全部拒绝
location / { allow 192.168.56.0/24; deny all; }
缺陷
- 当真实客户端直接访问目标服务器被deny拒绝之后,真实客户端通过多层代理服务器访问目标服务器仍然是可以访问的。
解决方法
采用别的http头信息访问控制,如HTTP_X_FORWARDED_FOR。
- 多层代理服务器以及目标服务开启
http_x_forwarded_for
,这个局限性很大,因为代理服务器可能不遵循开启http_x_forwarded_for
,这是一个协议要求的,并不是所有的cdn和代理厂商它会按照要求来做,甚至x_forwarded_for存在被修改的可能,因为只是一个头信息,所以最终还是不真实。 http_x_forwarded_for
也是Nginx的http头变量的一个常用的变量,它和remote_addr
是有区别的。不同的是,x_forwarded_for
是http协议中规定头中要携带的,所以在客户端访问中间件,再访问服务端的时候,那么服务端通过Nginx会记录真实IP和中间件的IP。- 格式为
http_x_forwarded_for = 客户端ip,第一台代理ip,第二台代理ip,第N台代理ip
,所以http_x_forwarded_for
是由一连串以逗号分隔的ip组成的。 192.168.56.1(客户端) -> 192.168.56.2(代理机) -> 192.168.56.3(代理机) -> 192.168.56.5(目标机器)
# 192.168.56.2 location ^~ /proxy1/ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://192.168.56.3:80; proxy_redirect off; } # 192.168.56.3 location ^~ /proxy1/ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://192.168.56.5:80; proxy_redirect off; } # 192.168.56.5 location / { root /usr/share/nginx/html; index index.php index.html index.htm; } location ~ \.php$ { root /usr/share/nginx/html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
- 多层代理服务器以及目标服务开启
- 结合geo模块 想了解的话可以移步到 使用Nginx+GeoIP获取IP信息
- 通过HTTP自定义变量传递
基于IP的访问控制(待完善)
Nginx虚拟主机
One comment
大于某个页面的id 代理到新机器
location ~ ^/(game|app|soft|azyx|azrj)/([0-9]+)\.html$ {
set $id $2;
set_by_lua $isProxy '
local id = tonumber(ngx.var.id)
if id >= 270000 then return "1" else return "0" end
';
if ($isProxy = 1) {
proxy_pass http://proxy.t4t8.cn;
}
}