• 用nginx实现分布式限流


    1.前言

    一般对外暴露的系统,在促销或者黑客攻击时会涌来大量的请求,为了保护系统不被瞬间到来的高并发流量给打垮, 就需要限流 . 

    本文主要阐述如何用nginx 来实现限流. 听说 Hystrix 也可以, 各位有兴趣可以去研究哈 .

    2. 首先部署一个对外暴露接口的程序

     我这里部署的是一个spring boot 项目 里面暴露了如下接口, 很简单

    package com.anuo.app.controller;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/test")
    public class TestController {
    
        Logger logger = LoggerFactory.getLogger(TestController.class);
    
    
    
        @RequestMapping(value = "/show/message", method = RequestMethod.GET)
        public String test() {
            return  "hello world ";
        }
    
    
    }

    暴露了一个 get 请求返回 hello world 的restful 接口.

    将此程序部署到 linux 服务器上. 部署步奏不再赘述, 自行百度 spring boot 部署 即可. 

     

    3.创建一个名称为 nginx.conf 的 nginx 配置文件

    创建一个 名叫 nginx.conf 的配置文件, 完整内容如下

    user  nginx;
    worker_processes  1;
    
    error_log  /var/log/nginx/error.log warn;
    pid        /var/run/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       /etc/nginx/mime.types;
        default_type  application/octet-stream;
    
        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;
    
        sendfile        on;
        #tcp_nopush     on;
    
        keepalive_timeout  65;
    
        #gzip  on;
    
       
    	#限流配置
    	limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    	 
    	
    	#负载均衡配置
    	upstream myserver {
    		server 192.168.10.253:8090;
    		
    	}
    	server {
    		listen 80;
    		 
    		location / {
    			limit_req zone=perip;
    			proxy_pass http://myserver;
    			
    		}
    	}
    }
    

      


    配置文件中限流部分解释:

    如上, nginx 的限流配置 , 只有两行代码.

     第一行: 

    
    
    #限流配置
    limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
    

      

    limit_req_zone : 是限流声明.

    $binary_remote_addr: 表示根据客户端 ip 来 限流, 比如 上面的限流配置 限制每个客户端ip的请求频率为一秒一次, 你如果耍流氓一秒两次, 就会被限流 会返回一个http 503 错误给你. 

    zone=perip: 表示 用 perip 这个 名称 来标识 这行限流配置, 待会 会通过 perip 这个名称来引用这行限流配置(也就是说限流配置是可以定义为多个的)

    10m: 表示存储客户端ip的空间为10MB, 1MB 大概存储1万多ip , 10 MB 大概 10多万Ip , 参考解释:  http://www.ttlsa.com/nginx/nginx-limiting-the-number-of-requests-ngx_http_limit_req_module-module/  在这篇文章中搜索 binary_remote_addr 即可定位相关解释. 

     rate=1r/s: 表示频率是 一秒一个请求. 

     第二行:

    location / {
                limit_req zone=perip;
                proxy_pass http://myserver;
                
            }
    即这行: 
    limit_req zone=perip;

    表示在 myserver 这个集群上, 使用 名称为 perip 的限流配置

    4.用docker 部署 nginx 

    将上一步创建的 nginx.conf 配置文件, 拷贝到linux 目录 , /root/nginx/ 下 (目录可以任意), 然后 一个docker 命令部署好 nginx 环境

    docker run --name nginx -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf:ro -p 8080:80 -d nginx
    

      

    这里暴露的是 8080 端口, 通过 8080 端口可以访问到 nginx 配置中的负载均衡节点, 即 192.168.10.253:8090  ip端口, 这个 ip端口对应的就是 , 第一步创建部署的 hello world 程序. 

    5. 用代码访问 第一步定义的 helloworld 接口

    package com.anuo.study.studydistributed;
    
    import com.anuo.app.common.util.HttpUtil;
    
    public class StudyNginx {
        public static void main(String[] args) throws InterruptedException {
            while (true) {
                Thread.sleep(100);
                String s= HttpUtil.sendGet("http://192.168.10.253:8080/test/show/message");
                System.out.println(s);
            }
        }
    }
    

      

    我这里是 一秒 执行 10次 get 请求, 已经大于了 nginx中配置的 rate=1r/s  一秒一次的请求, 所以会看到 503 报错, 如下. 

    如果改哈代码, 改为一秒执行一次get 请求, 就不会报错, 各位可以去试一下

    至此 nginx 的限流 已实现. 

    参考的优质文章:
    http://www.ttlsa.com/nginx/nginx-limiting-the-number-of-requests-ngx_http_limit_req_module-module/
    http://www.ttlsa.com/nginx/nginx-limited-connection-number-ngx_http_limit_conn_module-module/#comments
    官方文档:
    http://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_log_level
    https://www.nginx.com/blog/rate-limiting-nginx/

  • 相关阅读:
    Codeforces 1065C Make It Equal
    Codeforces 1065B Vasya and Isolated Vertices
    Codeforces 1065A Vasya and Chocolate
    Luogu P2467 [SDOI2010]地精部落
    Codeforces 1042C Array Product
    Codeforces 1041C Coffee Break
    JMeter安装和环境变量搭建
    Jenkins
    Jenkins介绍
    Docker
  • 原文地址:https://www.cnblogs.com/Gkey55/p/9039364.html
Copyright © 2020-2023  润新知