令牌桶算法限流
1.導入依賴
org.springframework.boot
spring-boot-starter-data-redis-reactive
2.1.3.RELEASE
2.在springboot的啓動類中配置bean
@Bean
public KeyResolver ipKeyResolver(){
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
};
}
3.字application.yml配置文件中配置過濾限流
配置訪問路勁跨域
spring:
application:
name: sysgateway
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]': #匹配所以請求
allowedOrigins: "*" #跨域請求,允許所有的域
allowedMethods: #支持的方法
- GET
- POST
- PUT
- DELETE
配置令牌桶限流
spring:
application:
name: sysgateway
cloud:
gateway:
routes: #路由規則
- id: goods #路由規則名稱,可以自定義
uri: lb://goods #負載均衡,直接寫服務名
predicates:
- Path=/goods/**
filters:
- StripPrefix=1
- name: RequestRateLimiter #請求數限流 名字不能隨便寫
args:
key-resolver: "#{@ipKeyResolver}" #ipKeyResolver必須與啓動類中的bean的名稱一致
redis-rate-limiter.replenishRate: 1 #令牌桶每秒填充平均速率
redis-rate-limiter.burstCapacity: 1 #令牌桶總容量
JWT鑑權
配置過濾器實現鑑權,生成一個令牌返回給客戶端,下次訪問的時候帶着該令牌,再次進入該過濾器的時候就帶着令牌來了然後放行,第一次進來需要登錄直接放行
package com.changgou.system.filter;
import com.changgou.system.util.JwtUtil;
import io.jsonwebtoken.Jwt;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.net.URI;
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//獲取請求對象
ServerHttpRequest request = exchange.getRequest();
//獲取相應對象
ServerHttpResponse response = exchange.getResponse();
//判斷當前請求是否爲登錄請求,是,直接放行
URI uri = request.getURI();
if (uri.getPath().contains("/admin/login")){
//登錄直接放行
return chain.filter(exchange);
}
//獲取當期請求頭信心
HttpHeaders headers = request.getHeaders();
//獲取jwt令牌
String JwtToken = headers.getFirst("token");
//判斷令牌是否存在
if (StringUtils.isEmpty(JwtToken)){
response.setStatusCode( HttpStatus.MULTI_STATUS);
return response.setComplete();
}
//解析令牌,判斷是否一致
try{
JwtUtil.parseJWT(JwtToken);
}catch (Exception e){
e.printStackTrace();
//解析失敗
response.setStatusCode( HttpStatus.MULTI_STATUS);
return response.setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}