目录
⼀、⽹关介绍
1.1 微服务拆分之后遇到的问题?
1.2 什么是API⽹关?
1.3 ⽹关可以⼲什么?
1.4 常⽤的⽹关
⼆、使⽤Nginx实现⽹关服务
三、使⽤Gateway实现⽹关服务
3.1 搭建gateway服务器
3.2 配置路由规则
四、Gateway⼯作原理
4.1 名词解释
4.2 Gateway⼯作流程图
五、Predicate断⾔
5.1 Path
5.2 Query
5.3 Header
六、过滤器
6.1 Gateway内置⽹关过滤器
6.2 ⾃定义服务过滤器
6.2.1 创建⽹关过滤器 - 实现GatewayFilter
6.2.2 创建⽹关过滤器 - 继承AbstractNameValueGatewayFilterFactory
6.3 全局过滤器
七、Gateway动态路由配置
7.1 Gateway服务器添加eureka-server依赖
7.2 配置⽹关路由
⼋、⽹关限流
8.1 ⽹关限流介绍
8.2 ⽹关限流的常⻅算法
8.2.1 计数器算法
8.2.2 漏桶算法
8.2.3 令牌桶算法
8.3 Gateway⽹关限流
8.3.1 添加依赖
8.3.2 配置keyResolver
8.3.3 配置服务的限流规则
server :port : 9999spring :application :name : gateway-servercloud :gateway :routes :# 配置 api-service1 路由规则- id : api-service1uri : http : //localhost : 8001predicates :- Path=/product/**# 配置 api-service2 路由规则- id : api-service2uri : http : //localhost : 8002predicates :- Path=/order/**
spring :application :name : gateway-servercloud :gateway :routes :- id : aaauri : http : //localhost : 8001predicates :- Path=/product/**- id : bbburi : http : //localhost : 8002predicates :- Path=/order/**
spring :application :name : gateway-servercloud :gateway :routes :- id : aaauri : http : //localhost : 8001predicates :# 如果请求 url 中带有 name 参数 ---> http://localhost:8001- Query=name- id : bbburi : http : //localhost : 8002predicates :# 如果请求 url 中带有 pwd 参数 ---> http://localhost:8002- Query=pwd
spring :application :name : gateway-servercloud :gateway :routes :- id : aaauri : http : //localhost : 8001predicates :- Header=token- id : bbburi : http : //localhost : 8002predicates :- Header=aa,haha
spring :application :name : gateway-servercloud :gateway :routes :- id : aaauri : http : //localhost : 8001predicates :- Path=/red/aaa/product/**filters :- AddRequestHeader=token,wahahaawahaha- AddRequestParameter=username, ergou- SetStatus=404# - RewritePath=/red(?/?.*), $\{segment} - StripPrefix=2
public class MyFilter01 implements GatewayFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
System.out.println("---------------⾃定义过滤器");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
public class MyFilter01 implements GatewayFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
System.out.println("---------------⾃定义过滤器");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
/**
* 创建⼀个类继承AbstractNameValueGatewayFilterFactory,类名必须以
GatewayFilterFactory结尾,类名前⾯的部分即为当前⾃定义⽹关过滤器的 名字
* 添加@Component注解,注册到Spring容器
*/
@Component
public class MyFilterGatewayFilterFactory extends
AbstractNameValueGatewayFilterFactory {
@Override
public GatewayFilter apply(NameValueConfig config) {
System.out.println("name:"+config.getName());
System.out.println("value:"+config.getValue());
//创建⾃定义⽹关过滤器并返回
GatewayFilter gatewayFilter = new GatewayFilter() {
@Override
public Mono filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⾃
定义⽹关过滤器");
return chain.filter(exchange);
}
};
return gatewayFilter;
}
}
配置:
spring :application :name : gateway-servercloud :gateway :routes :- id : bbburi : http : //localhost : 8002predicates :- Path=/order/**filters :- MyFilter=aa,bb
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
System.out.println("-------------------------------------------
---MyGlobalFilter");
List list =
exchange.getRequest().getHeaders().get("token");
if (list != null && list.size()>0){
String token = list.get(0);
System.out.println("token:"+token);
return chain.filter(exchange);
}else{
//如果没有token,或者token过期
ServerHttpResponse response = exchange.getResponse();
//设置响应头
response.getHeaders().add("ContentType","application/json;charset=utf-8");
//设置状态码
response.setStatusCode(HttpStatus.UNAUTHORIZED);
// 封装响应数据
String str = "";
DataBuffer dataBuffer =
response.bufferFactory().wrap(str.getBytes());
return response.writeWith(Mono.just(dataBuffer));
}
}
@Override
public int getOrder() {
return 0;
}
}
org.springframework.cloud spring-cloud-starter-netflix-eureka-server
server :port : 9999spring :application :name : gateway-servermain :web-application-type : reactivecloud :gateway :routes :- id : aaauri : lb : //api-service1predicates :- Path=/product/**- id : bbburi : lb : //api-service2predicates :- Path=/order/**eureka :client :service-url :defaultZone : http : //localhost : 8761/eureka
org.springframework.boot spring-boot-starter-data-redis-reactive org.apache.commons commons-pool2 2.9.0
@Configurationpublic class AppConfig {@Beanpublic KeyResolver keyResolver () {//http://localhost:9999/order/query?user=1// 使⽤请求中的 user 参数的值作为令牌桶的 key//return exchange ->Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));return exchange ->Mono . just ( exchange . getRequest (). getURI (). getPath ());}}
server :port : 9999spring :application :name : gateway-servermain :web-application-type : reactivecloud :gateway :routes :- id : aaauri : lb : //api-service1predicates :- Path=/product/**- id : bbburi : lb : //api-service2predicates :- Path=/order/**filters :- name : RequestRateLimiterargs :redis-rate-limiter.replenishRate : 1 # 令牌桶每 s 的填充速度redis-rate-limiter.burstCapacity : 2 # 令牌桶容量redis-rate-limiter.requestedTokens : 1key-resolver : "#{@keyResolver}"redis :host : 47.96.11.185port : 7001password : qfedu123database : 0lettuce :pool :max-active : 10max-wait : 1000max-idle : 5min-idle : 3eureka :client :service-url :defaultZone : http : //localhost : 8761/eureka