Nginx&SpringCloudGateway进行请求限流
一、Nginx限流
1、请求数进行限流
http {
    limit_req_zone $server_name zone=mylimit:10m rate=1000r/s;
    server {
        listen       8881;
        server_name  localhost;
        limit_req zone=mylimit burst=500 nodelay; 
        location /mytest/ {
            proxy_pass http://localhost:8080/mytest/;
            proxy_connect_timeout 30;
            proxy_http_version 1.1;
            proxy_send_timeout 300;
            proxy_read_timeout 300;
            proxy_set_header 		Host $host:$server_port;
            proxy_redirect      off;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
    }
}
 
说明
####limit_req_zone $server_name zone=mylimit:10m rate=1000r/s; 
zone=mylimit: zone的名称,随便流,后面的引用会用到。
$server_name:服务器级别的限流,可替换成IP级别的限流
$binary_remote_addr zone: ip级别的限流
rate=1000r/s:  1秒1000次
####limit_req zone=mylimit burst=2 nodelay; 
zone后面的mylimit引用前面的配置的名称
burst: 突发的大量请求到来时的缓存处理大小,比如500
nodelay: 缓存的请求是否直接能处理,还是等下一轮,比如1r/m,一分钟执行一次,设置了burst=2,那burst中的记录,如果没有设置nodelay,则会在一分钟后才会进行处理。
##配置可以放在http, server,也可以放location部分
 
2、连接数进行限流
http {
    limit_conn_zone $binary_remote_addr zone=myip:10m;
    limit_conn_zone $server_name zone=myserver:10m;
    server {
        listen       8881;
        server_name  localhost;
        limit_conn myserver 100;
        limit_conn myip 1;
        location /mytest/ {
            proxy_pass http://localhost:8080/mytest/;
            proxy_connect_timeout 30;
            proxy_http_version 1.1;
            proxy_send_timeout 300;
            proxy_read_timeout 300;
            proxy_set_header 		Host $host:$server_port;
            proxy_redirect      off;
            proxy_set_header    X-Real-IP        $remote_addr;
            proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
    }
}
 
说明
limit_conn myserver 100; 每个服务器最多保持100个连接
limit_conn perip 1; ##每个Ip至多保持1个连接
##配置可以放http, server,也可以放location
 
二、Spring cloud Gateway限流
1.redis引入
redis引入,spring-boot-starter-data-redis或spring-boot-starter-data-redis-reactive,我用的是spring-boot-starter-data-redis,网上大部分资料是另一个,这个无关紧要
		<!-- redis start-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<!-- redis依赖commons-pool 这个依赖一定要添加 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-pool2</artifactId>
		</dependency>
		<!-- redis end-->
 
2. 网关加上配置
全局配置的话直接default-filters中配置
spring:
  cloud:
    gateway:
      default-filters: 
        - name: RequestRateLimiter
          args: 
            key-resolver: "#{@myResolver}"
            redis-rate-limiter:
              replenishRate: 1
              burstCapacity: 1
              requestedTokens: 1
 
也可针对对应的router进行配置
spring:
  cloud:
    gateway:
      routes:
        - id: mytest
          uri: "http://localhost:8080"
          predicates: 
            - Path=${server.context-path}/**
          filters: 
          - name: RequestRateLimiter
            args: 
              key-resolver: "#{@myResolver}"
              redis-rate-limiter:
                replenishRate: 1
                burstCapacity: 1
                requestedTokens: 1
 
name:  必须是RequestRateLimiter。
redis-rate-limiter.replenishRate:允许用户每秒处理多少个请求。
redis-rate-limiter.burstCapacity:令牌桶的容量,replenishRate使用完后的缓冲量请求数。
key-resolver:SpEL引用 bean的名称。
requestedTokens: 每个请求需要多少个令牌
 
3.Bean的配置
	@Bean
	KeyResolver myResolver() {
		return exchange -> Mono.just(exchange.getRequest().getPath().value());//URL接口限流
		//return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));//用户限流
		//return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());//IP限流
	}










