内容目录

nginx常用模块

nginx目录索引

ngx_http_index_module模块找不到索引文件,通常会将请求传递给ngx_http_autoindex_module模块。
ngx_http_autoindex_module模块处理以斜杠字符('/')结尾的请求,并生成目录文件

配置语法
# 启用或禁用目录列表输出,on开启,off关闭
syntax:autoindex on | off;
default:autoindex off;
context:http,server,location
# 指定是否在目录列表中输出确切的文件大小,on显示字节,off显示大概单位
syntax:autoindex_exact_size on | off;
default:autoindex_exact_size on;
context:http,server,location
# 指定目录列表中的时间是应以本地时区还是UTC输出。on本地时区,off UTC时间。
syntax:autoindex_localtime on | off;
default:autoindex_localtime off;
context:http,server,location
配置示例
cat /etc/nginx/conf.d/wordpress.conf
server {
    listen 80;
    server_name mirror.xxx.net;
    charset utf-8;  # 设定字符集,防止中文字符乱码显示
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
    location / {
        root /code/;
    }
}

nginx访问控制

ngx_http_access_module模块运行限制对某些客户端地址的访问。

配置语法

# 允许配置语法
syntax:allow address | CIDR | unix: | all;
default:-
context:http,server,location,
limit_except
# 拒绝配置语法
syntax:deny address | CIDR | unix: | all;
default:-
context:http,server,location,
limit_except

配置示例

  • 只允许指定的来源ip能访问/centos,其他网段全部拒绝

    location /centos {
    allow 127.0.0.1;
    allow 10.0.0.1/32;  # 允许地址或地址段
    deny all;  # 拒绝所有人
    }
  • 拒绝指定的ip访问该网站的/centos,其他ip全部允许访问

    location /centos {
    deny 10.0.0.1/32;  # 拒绝指定的地址或地址段
    allow all;  # 允许所有的地址
    }

注意:deny和allow的顺序是有影响的
默认情况下,从第一条规则进行匹配
如果匹配成功,则不继续匹配下面的内容
如果匹配不成功,则继续往下寻找能匹配成功的内容

nginx基础认证

ngx_http_auth_basic_module模块运行使用http基本身份验证,验证用户名和密码来限制对资源的访问

配置语法

# 使用http基本身份验证协议启用用户名和密码验证
syntax:auth_basic string | off;
default:auth_basic off;
context:http,server,location,
limit_except
# 指定保存用户名和密码的文件
syntax:auth_basic_user_file file;
default:-
context:http,server,location,
limit_except

指定保存用户名和密码的文件,格式如下:

# 可以使用htpasswd程序或"openssl passwd"命令生成对应的密码;
name1:passwd1
name2:passwd2
# 使用htpasswd创建新的密码文件,-c 创建新文件 -b 允许命令行输入密码
yum install httpd-tools
htpasswd -b -c /etc/nginx/auth_conf xxx 123456

配置示例

location /centos {
    auth_basic "Auth access Blog Input your Passwd!";
    auth_basic_user_file /etc/nginx/auth_conf;
}

nginx限流限速

为什么要限速

限制某个用户在一定时间内能够产生的http请求。或者说限制某个用户的下载速度。
503:过载保护

限速应用场景

下载限速:限制用户下载资源的速度
ngx_http_core_module
请求限制:限制用户单位时间内所产生的http请求数
ngx_http_limit_req_module
连接限制:限制同一时间的连接数,即并发数限制
ngx_http_limit_conn_module

请求频率限速原理

水(请求)从上方倒入水桶,从水桶下方流出(被处理)
如果说谁(请求)流入的过快,水桶流出(被处理)的过慢,来不及流出的水存在水桶中(缓存),然后以固定速率流出,水桶满后则水溢出(丢弃)。
简单来说就是:当处理速度,达不到请求的速度,则会将请求放置缓存,然后持续处理。当缓存被占满,如果还有大量的请求,则会被丢弃

限制请求并发数

  1. 指令

    syntax:limit_req_zone key zone=name:size rate=rate;
    default:-
    context:http
    syntax:limit_req zone number [burst=number][nodelay];
    default:-
    context:http,server,location
  2. 基于来源ip对下载速率限制,限制每秒处理1次请求,但可以突发超过5个请求放入缓存区

    # http标签段定义请求限制,rate限制速率,限制一秒钟最多一个IP请求
    http {
    limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
    }
    server {
    listen 80;
    server_name xxx.net;
    # 请求超过1r/s,剩下的将被延迟处理,请求数超过burst定义的数量,则返回503
    limit_req zone=req_one burst=3 nodelay;
    location / {
        root /code;
        index index.html;
    }
    }
    limit_req_zone $binary_remote_addr zone=req_one:10m rate=1r/s;
    # 第一个参数:$binary_remote_addr表示通过这个标识来做限制,限制同一客户端ip地址
    # 第二个参数:zone-req_one:10m表示生成一个大小为10M,名为req_one的内存区域,用来存储访问的频次信息
    # 第三个参数:rate-1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次
    limit_req zone=req_one burst=3 nodelay;
    # 第一个参数:zone=req_one 设置使用哪个区域赖做限制,与上面limit_req_zone里的name对应
    # 第二个参数:burst=3,设置一个大小为3的缓冲区,当有大量请求过来时,超过了访问频次限制的请求可以先放到这个缓冲区内
    # 第三个参数:nodelay,超过访问频次并且缓冲区也满了的时会,则会返回503,如果没有设置,则所有请求会等待排队。

限制并发连接数

  1. 指令

    syntax:limit_conn_zone key zone=name:size;
    default:-
    context:http
    syntax:limit_conn zone number;
    default:-
    context:http,server,location
  2. 设置共享内存区域和给定键值的最大允许连接数。超过此限制时,服务器将返回503错误以回复请求

    limit_conn_zone $binary_remote_addr zone=conn_od:10m;
    server {
    limit_conn conn_od 2;
    }

限制下载速度

server {
    limit_rate_after 100m;  # 达到100m开始限速
    limit_rate 100k;
}

综合场景实践

  1. 限制web服务器请求数处理为1秒一个,触发值为5,限制用户仅可同时下载一个文件
  2. 当下载超过100M则限制下载速度为500K
  3. 如果同时下载超过2个视频,则返回提示“请联系管理员进行会员重置” | 跳转到其他页面
limit_req_zone $binary_remote_addr zone=req_od:10m rate=1r/s;
limit_conn_zone $binary_remote_addr zone=conn_od:10m;
server {
    listen 80;
    server_name xxx.net;
    limit_req zone=req_od burst=5 nodelay;
    lilmit_conn conn_od 1;
    limit_rate_after 100m;
    limit_rate 500k;
    error_page 503 @errpage;
    location @errpage {
        defalt_type text/html;
        return 200 '提示-->请联系管理员进行会议充值';
        return 302 https://www.qq.com;
    }
    location / {
        index index.html;
    }
}

nginx状态监控

ngx_http_stub_status_module模块提供对基本状态信息的访问
默认情况下不记仇该模块,需要使用--with-http_stub_status_module集成

配置语法

syntax:stub_status;
default:-
context:server,location

配置示例

server {
    listen 80;
    server_name xxx.net;
    access_log off;
    location /nginx_status {
        stub_status;
    }
}

页面状态

Active connections:291
server accepts handled requests
200 200 301
reading:6 writing:179 waiting:106
# active connections:当前活跃连接数,包括waiting等待连接数
# accepts:已接收的总tcp连接数量
# handled:已处理的tcp连接数量
# requests:当前总http请求数量
# reading:当前读取的请求头数量
# writing:当前响应的请求头数量
# waiting:当前等待请求的空闲客户端连接数
  • 如何理解reading、writing、waiting
  • 假设现在有两条船分别为C、S。C船需要S船的1个物品,那么此时C船就要给S船发送一个消息
    • S船收到这个消息时就是reading
    • S船将物资发送给C船,这个时候就是writing
    • 如果C船需要S船很多物品,那么需要C船和S船建立起一个物资传送管道,不断的传送物资。这个管道建立起来的时候,就是waiting状态了

nginx资源缓存

  • 浏览器缓存设置用于提高网站性能,尤其是新闻网站,图片一旦发布,改动的可能是非常小的。所以我们希望能否用户访问一次后,图片缓存在用户的浏览器长时间缓存。
  • 浏览器是有自己的缓存机制,它是基于http协议缓存机制来实现的,在http协议中有很多头(Headers)信息,那么实现浏览器的缓存就需要以来特殊的头信息来与服务器进行特殊的验证,如:Expires(http/1.0),Cache-control(http/1.1)

    浏览器无缓存

    浏览器有缓存

    缓存过期校验

  • 浏览器缓存过期校验检查机制,说明如下:
    • 浏览器请求服务器会先进行expires、cache-control的检查,检查缓存是否过期,如果没有过期则直接从缓存文件中读取
    • 如果缓存过期,首先检查是否存在etag,如果存在则客户端会向web服务器请求if-none-match,与etag值进行比对,由服务器决策返回200还是304
    • 如果etag不存在,则进行last-modified检查,客户端会向web服务器请求if-modified-since,与last-modified进行对比,由服务器决策返回200还是304

nginx资源压缩

nginx将发送至客户端之前的数据进行压缩,然后传输,这能够有效地节约带宽,并提高响应速度;
图片:不高;文本:比较高

配置语法

# 1.启用或关闭gzip压缩
syntax:gzip on | off;
default:gzip off;
context:http,server,location,if in location
# 2.gzip支持的压缩类型
syntax:gzip_types mime-type ...;
default:gzip_types text/html;
context:http,server,location
# 3.gzip压缩比率,压缩率越高,cpu消耗越大
syntax:gzip_comp_level level;
default:gzip_comp_level 1;
context:http,server,location
# 4.gzip压缩的最小文件,小于设置的值文件将不会被压缩(由“context-length”响应头字段确定)
syntax:gzip_min_length length;
default:gzip_min_length 20;
context:http,server,location
# 5.gzip压缩支持的协议版本
syntax:gzip_http_version 1.0 | 1.1;
default:gzip_http_version 1.1;
context:http,server,location
# 6.启用压缩,是否在响应报文首部插入"vary:accept-encoding"
syntax:gzip_vary on | off
default:gzip_vary off;
context:http,server,location

图片压缩案例

server {
    listen 80;
    server_name xxx.net;
    root /code/images;
    location ~* .*\.(jpg|gif|png)$ {
        gzip on;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_min_length 10k;
        gzip_types image/jpeg image/gif image/png;
        gzip_vary on;
    }
}

文件压缩案例

server {
    listen 80;
    server_name xxx.net;
    root /code/doc;
    location ~* .*\.(txt|pdf)$ {
        gzip on;
        gzip_http_version 1.1;
        gzip_comp_level 2;
        gzip_min_length 1k;
        gzip_types text/plain application/pdf;
        gzip_vary on;
    }
}

Nginx Location

什么是Location

location用来控制访问网站的uri路径

location语法示例

location [ = | ~ | ~* | ^~] uri { ... }
location @name { ... }
/api/xxx/dadas/dsadsa
/apiv1/dsa/dsaxx/sadsa/
# 匹配符 匹配规则                   优先级
# =     精确匹配                     1
# ^~    以某个字符串开头              2
# ~     区分大小写的正则匹配          3
# ~*    不区分大小写的正则匹配        4
# /     通用匹配,任何请求都会匹配到   5

location优先级示例

server {
     listen 80;
     server_name xxx.net;
     location = / {
         default_type text/html;
         return 200 'location = /';
     }
     location / {
         default_type text/html;
         return 200 'location /';
     }
     location /documents/ {
         default_type text/html;
         return 200 'location /documents/';
     }
     location ^~ /images/ {
         default_type text/html;
         return 200 'location ^~ /images/';
     }
     location ~* \.(gif|jpg|jpeg)$ {
         default_type text/html;
         return 200 'location ~* \.(gif|jpg|jpeg)';
     }
}
# 测试结果如下(建议是curl测试)
1.请求 http://xxx.net/
会被 location =/ 匹配
2.请求 http://xxx.net/index.html
会被 location / 匹配
3.请求 http://xxx.net/documents/1.html
会被 location /documents/ 匹配
4.请求 http://xxx.net/images/1.gif
会被 location ^~ /images/ 匹配
5.请求 http://xxx.net/documents/1.jpg
会被 location ~* \.(gif|jpg|jpeg)$ 匹配

location应用场景

server {
    listen 80;
    server_name xxx.net;
    # 通用匹配,任何请求都会匹配到
    location / {
        root html;
        index index.html;
    }
    # 精确匹配,必须请求的uri是/nginx_status
    location = /nginx_status {
        stub_status;
    }
    # 严格区分大小写,匹配以.php结尾的都走这个location
    location ~ \.php$ {
        default_type text/html;
        return 200 'php访问成功';
    }
    # 严格区分大小写,匹配以.jsp结尾的都走这个location
    location ~ \.jsp$ {
        default_type text/html;
        return 200 'jsp访问成功';
    }
    # 不区分大小写,只要用户访问.jpg,gif,pnp,js,css 都走这个location
    location {
        # return 403;
        expires 3d;
    }
    # 不区分大小写匹配
    location ~* \.(sql|bak|tgz|tar.gz|git)$ {
        deny all;
    }
}

location @重定向

  • location @name这样的location不用于常规请求处理,而是用于请求重定向
    server {
    # 如果出现异常,则重新定向到@error_404这个location上
    error_page 404 @error_404;
    location @error_404 {
        default_type text/html;
        return 200 '你可能是不小心走丢了。';
    }
    }

Nginx日志模块

nginx的日志记录非常灵活,可以通过log_format来定义格式

nginx日志格式

log_format定义日志格式语法

# 配置语法:包括 error.log access.log
syntax:log_format name
[escape=default|json] string ...;
default:log_format combined "...";
context:http
# 默认nginx定义语法格式如下
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
/var/log/nginx/access.log main;

nginx日志格式中常用的变量

$remote_addr          # 记录客户端ip地址
$remote_user          # 记录客户端用户名
$time_local           # 记录通用的本地时间
$time_iso8601         # 记录ISO8601标准格式下的本地时间
$request              # 记录请求的方法以及请求的http协议
$status               # 记录请求状态码(用于定位错误信息)
$body_bytes_sent      # 发送给客户端的资源字节数,不包括响应头的大小
$bytes_sent           # 发送给客户端的总字节数
$msec                 # 日志写入时间,单位为秒,精度是毫秒
$http_referer         # 记录从哪个页面链接访问过来的
$http_user_agnet      # 记录客户端浏览器相关信息
$http_x_forwarded_for # 记录客户端ip地址
$request_length       # 请求的长度(包括请求行,请求头和请求正文)
$request_time         # 请求花费的时间,单位为秒,精度是毫秒
# 注:如果nginx位于负载均衡器,nginx反向代理之后,web服务器无法直接获取到客户端真实的ip地址
# $remote_addr获取的是反向代理的ip地址,反向代理服务器在转发请求的http头信息中
# 增加x-forwarded-for信息,用来记录客户端ip地址和客户端请求的服务器地址

nginx访问日志

  1. web服务器的访问日志是非常重要的,我们可以通过访问日志来分析用户的访问情况,也可以通过访问日志发现一些异常访问。access_log日志配置语法

    syntax:access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
    access log off;
    default:access_log logs/access.log combined;
    context:http,server,location,if in location,limit_except
    http {
    access_log /var/log/nginx/access.log main;
    server{
        access_log /var/log/nginx/xxx.net.log main;
    }
    }
  2. nginx访问日志配置示例

    server {
    listen 80;
    server_name log.xxx.net;
    # 将当前的server网站的访问日志记录至对应的目录,使用main格式
    access_log /var/log/nginx/log.xxx.net.log main;
    }

nginx错误日志

nginx常见的错误日志级别有debug | info | notice | warn | error | crit | alert | emerg级别越高记录的信息越少,如果不定义,默认级别为warn,它可以配置在main、http、server、location段里
nginx错误日志示例

error_log /var/log/nginx/error.log warn;
# 关闭错误日志
error_log /dev/null;

nginx日志过滤

一个网站包含很多元素,尤其是有大量的images、js、css等静态资源。这样的请求可以不用记录日志

# 请求favicon.ico时,不记录日志
location /favicon.ico {
    access_log off;
    return 200;
}
# 当有人访问gif、png等资源时,将日志丢入空
location ~* .*\.(gif|jpg|png|css|js)$ {
    access_log /dev/null;
}
最后修改日期: 2024年3月30日

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。