Nginx-12 实战
************ 如有侵权请提示删除 ***************
- 实例一 限制访问速率
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit;
}
}
上述规则限制了每个IP访问的速度为2r/s,并将该规则作用于根目录。如果单个IP在非常短的时间内并发发送多个请求,结果会怎样呢?
- 实例二 burst缓存处理
我们看到,我们短时间内发送了大量请求,Nginx按照毫秒级精度统计,超出限制的请求直接拒绝。这在实际场景中未免过于苛刻,真实网络环境中请求到来不是匀速的,很可能有请求“突发”的情况,也就是“一股子一股子”的。Nginx考虑到了这种情况,可以通过burst关键字开启对突发请求的缓存处理,而不是直接拒绝。
来看我们的配置:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4;
}
}
我们加入了burst=4,意思是每个key(此处是每个IP)最多允许4个突发请求的到来。如果单个IP在10ms内发送6个请求,结果会怎样呢?
相比实例一成功数增加了4个,这个我们设置的burst数目是一致的。具体处理流程是:1个请求被立即处理,4个请求被放到burst队列里,另外一个请求被拒绝。通过burst参数,我们使得Nginx限流具备了缓存处理突发流量的能力。
但是请注意:burst的作用是让多余的请求可以先放到队列里,慢慢处理。如果不加nodelay参数,队列里的请求不会立即处理,而是按照rate设置的速度,以毫秒级精确的速度慢慢处理。
- 实例三 nodelay降低排队时间
实例二中我们看到,通过设置burst参数,我们可以允许Nginx缓存处理一定程度的突发,多余的请求可以先放到队列里,慢慢处理,这起到了平滑流量的作用。但是如果队列设置的比较大,请求排队的时间就会比较长,用户角度看来就是RT变长了,这对用户很不友好。有什么解决办法呢?nodelay参数允许请求在排队的时候就立即被处理,也就是说只要请求能够进入burst队列,就会立即被后台worker处理,请注意,这意味着burst设置了nodelay时,系统瞬间的QPS可能会超过rate设置的阈值。nodelay参数要跟burst一起使用才有作用。
延续实例二的配置,我们加入nodelay选项:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server {
location / {
limit_req zone=mylimit burst=4 nodelay;
}
}
- 实例四 全站HTTP 跳转HTTPS协议
以http://www.a.com为例,要求全部访问该页面的请求全部跳转到https://www.a.com/,且请求的URI和参数$query_string要保留。
- 方案一:使用if进行判断------最差
这种情况下,多为把http和https写在同一个server中,配置如下:
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name www.a.com a.com *.a.com;
#证书
ssl_certificate "/data/nginx/ssl/nginx.crt";
ssl_certificate_key "/data/nginx/ssl/nginx.key";
root /data/nginx/a;
charset utf-8;
if( $scheme = http){
rewrite ^/(.*)$ https://www.a.com$1 permanent;
}
}
配置看着简洁,性能最差,每次访问都判断,生产上不建议使用,能少用if尽量不用
- rewrite 方法-----差
server{
listen 80 default_server;
server_name www.a.com a.com *.a.com;
#多了这个
rewrite ^/(.*)$ https://www.a.com$1 permanent;
}
server {
listen 443 ssl default_server;
server_name www.a.com a.com *.a.com;
ssl_certificate "/data/nginx/ssl/nginx.crt";
ssl_certificate_key "/data/nginx/ssl/nginx.key";
root /data/nginx/a;
charset utf-8;
}
- rewrite 方法2-----好一些
不用正则表达式,而用变量来提升性能
server{
listen 80 default_server;
server_name www.a.com a.com *.a.com;
#多了这个
rewrite ^ https://www.a.com$request_uri? permanent;
}
server {
listen 443 ssl default_server;
server_name www.a.com a.com *.a.com;
ssl_certificate "/data/nginx/ssl/nginx.crt";
ssl_certificate_key "/data/nginx/ssl/nginx.key";
root /data/nginx/a;
charset utf-8;
}
注意:#request_uri 已经包含了查询参数,所以要在其重写规则后面加上? ,以禁止再次传递参数,这种方法避免了 Nginx 内部处理正则的性能损坏,先比上一方法好很多
- 采用return ----最好
直接return ,避免正则和重写
server{
listen 80 default_server;
server_name www.a.com a.com *.a.com;
#换了这个
return 301 https://¥host$request_uri;
}
server {
listen 443 ssl default_server;
server_name www.a.com a.com *.a.com;
ssl_certificate "/data/nginx/ssl/nginx.crt";
ssl_certificate_key "/data/nginx/ssl/nginx.key";
root /data/nginx/a;
charset utf-8;
}