nginx(四)高并发情况限流以及白名单配置

电商平台营销时候,经常会碰到的大流量问题,除了做流量分流处理,可能还要做用户黑白名单、信誉分析,进而根据用户ip信誉权重做相应的流量拦截、限制流量。

Nginx自身有的请求限制模块ngx_http_limit_req_module、流量限制模块ngx_stream_limit_conn_module基于令牌桶算法,可以方便的控制令牌速率,自定义调节限流,就能很好的限制请求数量,然而,nginx.conf问题还是在于无法热加载

在高并发访问情况如何解决网站的高访问量,有三大利器,缓存,降级,限流,这里介绍nginx如何限流的方法

主要配置

http {

limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;

server {

location /campaign/ {
                limit_req zone=perip burst=5 nodelay;
                
        }
}
}

配置说明

  • limit_conn是对某个KEY对应的总的网络连接数进行限流。可以按照IP来限制IP维度的总连接数,或者按照服务域名来限制某个域名的总连接数。但是记住不是每一个请求连接都会被计数器统计,只有那些被Nginx处理的且已经读取了整个请求头的请求连接才会被计数器统计
  • limit_conn_zone:用来配置限流KEY、及存放KEY对应信息的共享内存区域大小;此处的KEY是“$binary_remote_addr”其表示IP地址,也可以使用如$server_name作为KEY来限制域名级别的最大连接数;
  • limit_conn_status:配置被限流后返回的状态码,默认返回503;
  • limit_conn_log_level:配置记录被限流后的日志级别,默认error级别

 

Nginx限流配置

http {
    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    limit_req_zone $server_name zone=perserver:10m rate=10r/s;
    limit_req_log_level notice ;
    

    server {

        location /search/ {
            limit_req zone=perip burst=5 nodelay;
            limit_req zone=perserver burst=10;
        }
    }
}

范例详解

  • limit_req_zone [key] zone = [name]:[size] rate=[rate]
limit_req_zone  这个变量只能在HTTP中使用,limit_req_zone,用来限制请求的频率。
    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    每个IP的请求频率每秒不能超过1次且最大容量为10M.
    limit_req_zone $server_name zone=perserver:10m rate=10r/s;
    每个虚拟服务的请求频率每秒不能超过10次且最大容量为10M。
    key 表示限制的关键词 可以是 IP 或 虚拟服务
    zone的名称可以自定义,但不能重复,它代表一个存储 session 状态的容器,size 表示 容器的大小。以范例中的 perip 限制区域为例,大小为10M,按照 64-byte / session,约能存储 1.6W 个 session。
    rate 表示请求的频率,另外还有 r/m 表示每分钟的请求频率限制。
  • limit_req zone=[name] burst=[count] nodelay
limit_req 这个变量可以放在 server 中 或者 location 中,放在 server 中时表示对整个服务做限流,放在 location 中表示对特定请求做限流。
    参数说明:
    zone  选择的限流容器 name 限流容器名称
    burst 缓存的数量  count 最大请求缓存数
    nodelay 表示不延迟,即如果请求缓存超过 count 的值时马上返回 503 错误。
  • limit_req_log_level info | notice | warn | error
    限流日志级别 ,默认为 error

 

白名单配置

http {
 geo $whiteiplist  {
 default 1;
 127.0.0.1 0;
 10.0.0.0/8 0;
 121.207.242.0/24 0;
 }
 
 map $whiteiplist  $limit {
 1 $binary_remote_addr;
 0 "";
 }
 
 limit_conn_zone $limit zone=limit:10m;
 
 server {
        listen       8080;
        server_name  test.ttlsa.com;
 
        location ^~ /ttlsa.com/ {
                limit_conn limit 4;
                limit_rate 200k;
                alias /data/www.ttlsa.com/data/download/;
        }
 }
}

技术要点:
1. geo指令定义一个白名单$whiteiplist, 默认值为1, 所有都受限制。 如果客户端IP与白名单列出的IP相匹配,则$whiteiplist值为0也就是不受限制。
2. map指令是将$whiteiplist值为1的,也就是受限制的IP,映射为客户端IP。将$whiteiplist值为0的,也就是白名单IP,映射为空的字符串。
3. limit_conn_zone和limit_req_zone指令对于键为空值的将会被忽略,从而实现对于列出来的IP不做限制。

http{

   limit_req_zone $binary_remote_addr zone=allips:50m rate=10r/s;

   server{
     location /camp{
         limit_req zone=allips burst=50 nodelay;
     }
   }
}

 

nginx中gzip配置

gzip用于压缩网络中的image/js/css等静态文件

    gzip  on;
    gzip_min_length 1k;
    gzip_buffers 16 64k;
    gzip_http_version 1.1;
    gzip_comp_level 6;
    gzip_types text/plain application/javascript text/css application/xml;
    gzip_vary on;

测试是否gzip成功

curl -I -H "Accept-Encoding: gzip, deflate" http://www.gzip.com/test/campaign/123_init?state=1__20__1001&openId=009

nginx日志分析命令

统计IP访问量
awk '{print $1}' access.log | sort -n | uniq | wc -l

查看某一时间段的IP访问量(4-5点)
grep "07/Apr/2017:0[4-5]" access.log | awk '{print $1}' | sort | uniq -c| sort -nr | wc -l   

查看访问最频繁的前100个IP
awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 100

查看访问100次以上的IP
awk '{print $1}' access.log | sort -n |uniq -c |awk '{if($1 >100) print $0}'|sort -rn

查询某个IP的详细访问情况,按访问频率排序
grep '104.217.108.66' access.log |awk '{print $7}'|sort |uniq -c |sort -rn |head -n 100   

页面访问统计
查看访问最频的页面(TOP100)
awk '{print $7}' access.log | sort |uniq -c | sort -rn | head -n 100

查看访问最频的页面([排除php页面】(TOP100)
grep -v ".php"  access.log | awk '{print $7}' | sort |uniq -c | sort -rn | head -n 100          

查看页面访问次数超过100次的页面
cat access.log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print $0}' | less

查看最近1000条记录,访问量最高的页面
tail -1000 access.log |awk '{print $7}'|sort|uniq -c|sort -nr|less

每秒请求量统计
统计每秒的请求数,top100的时间点(精确到秒)
awk '{print $4}' access.log |cut -c 14-21|sort|uniq -c|sort -nr|head -n 100

每分钟请求量统计
统计每分钟的请求数,top100的时间点(精确到分钟)
awk '{print $4}' access.log |cut -c 14-18|sort|uniq -c|sort -nr|head -n 100

每小时请求量统计
统计每小时的请求数,top100的时间点(精确到小时)
awk '{print $4}' access.log |cut -c 14-15|sort|uniq -c|sort -nr|head -n 100

性能分析
在nginx log中最后一个字段加入$request_time

列出传输时间超过 3 秒的页面,显示前20条

cat access.log|awk '($NF > 3){print $7}'|sort -n|uniq -c|sort -nr|head -20
列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条

cat access.log|awk '($NF > 1 &&  $7~/\.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100
蜘蛛抓取统计
统计蜘蛛抓取次数

grep 'Baiduspider' access.log |wc -l
统计蜘蛛抓取404的次数

grep 'Baiduspider' access.log |grep '404' | wc -l

TCP连接统计
查看当前TCP连接数
netstat -tan | grep "ESTABLISHED" | grep ":80" | wc -l

用tcpdump嗅探80端口的访问看看谁最高
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr

 

awk '{print $1}' $logpath |sort -n|uniq|wc -l

echo "=====系统正在统计某一个时间段IP访问量为=====" 
#grep "16/Jun/2017:1[8:9]" $logpath |awk '{print $1}'|sort|uniq -c|sort -nr|wc -l
#sed -n "16/Jun/2017:18:00:00/,16/Jun/2017:21:30:00/"p $logpath|awk '{print $1}'|sort|uniq -c|sort -nr|wc -l
#sed -n '/16\/Jun\/2017:18:00:00/,/16\/Jun\/2017:21:00:00/p' $logpath|awk '{print $1}'|sort|uniq -c|sort -nr|wc -l
#sed -n '/16\/Jun\/2017:1[9]/,/16\/Jun\/2017:2[1]/p' /usr/local/nginx/logs/access.log |wc -l
sed -n '/22\/Jun\/2017:1[5]/,/22\/Jun\/2017:1[6]/p' $logpath|awk '{print $1}'|sort -n|uniq|wc -l


echo "=====访问100次以上的IP====="
awk '{print $1}' $logpath|sort -n|uniq -c|awk '{if($1>100) print $0}'|sort -rn

echo "=====访问最频繁的请求(TOP50)====="
awk '{print $7}' $logpath |sort |uniq -c|sort -rn |head -n 50

echo "=====统计每秒的请求数(TOP50)======"
awk '{print $4}' $logpath|cut -c 14-21|sort |uniq -c|sort -nr|head -n 50

echo "=====统计每分钟的请求数(TOP50)====="
awk '{print $4}' $logpath|cut -c 14-18|sort|uniq -c|sort -nr|head -n 50

echo "=====统计每小时请求数(TOP50)====="
awk '{print $4}' $logpath|cut -c 14-15|sort|uniq -c|sort -nr|head -n 50

echo "=====传输时间超过1秒的请求(TOP20)====="
cat $logpath|awk '($NF > 1){print $7}'|sort -n|uniq -c|sort -nr|head -20

 

 

1.nginx 配置新旧域名过渡,把访问域名www.taobao.com的转发到新域名 www.tb.com上

配置方式如下
server{
   server_name www.taobao.com;
 #方式1  rewrite  ^/(.*)$  http://www.tb.com/$1 permanent;

 # 方式2 
    if($host != ‘www.tb.com’){
    rewrite ^/(.*)$  http://www.tb.com/$1 permanent;
}
}

2.nginx 实现ip访问控制

location /{
   deny 192.168.66.80;
   allow 192.168.66.0/24;
   allow 192.16.88.0/16;
   deny all;
}

3.nginx要禁止访问*.txt,*.doc配置如下:
location ~*  \.(txt|doc)${
   root /data/index;
  deny all;
}

https://www.zzxworld.com/blogs/limit-rate-and-connection-in-nginx.html

https://www.idaima.com/article/11977

参考文章

1.http://www.wangjingfeng.com/730.html

2.http://blog.csdn.net/soar_away/article/details/51980247

3.https://www.zzxworld.com/posts/limit-rate-and-connection-in-nginx.html

4.https://www.idaima.com/article/11977

5.https://www.zzxworld.com/blogs/limit-rate-and-connection-in-nginx.html

 

 

转载于:https://my.oschina.net/chenxiaobian/blog/888196

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值