标签:before min ali 属性 增加 override tst omv his
<!--
Spring Cloud Gateway使用的web框架是webflux,和SpringMVC不兼容。引入的限流组件是Hystrix。Redis底层不再使用jedis,而是lettuce。
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api_gateway_server7007</artifactId>
<dependencies>
<!--
Spring Cloud Gateway使用的web框架是webflux,和SpringMVC不兼容。引入的限流组件是Hystrix。Redis底层不再使用jedis,而是lettuce。
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>
package com.sunxiaping.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author 许大仙
* @version 1.0
* @since 2020-10-05 19:22
*/
@SpringBootApplication
public class Gateway7007Application {
public static void main(String[] args) {
SpringApplication.run(Gateway7007Application.class, args);
}
}
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Path=/product/**
上面配置的意思是,配置了一个id为product-service的路由规则,当访问网关请求地址以product开头时,会自动转发到http://localhost:9004这个地址。启动项目后,如果访问的路径是http://localhost:7007/product/findById/1,就会自动转发到http://localhost:9004/product/findById/1这个地址。
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Before=2020-11-11T00:00:00+08:00[Asia/Shanghai] # 在2020-11-11T00:00:00之前允许访问
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- After=2020-11-11T00:00:00+08:00[Asia/Shanghai] # 在2020-11-11T00:00:00之后允许访问
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Between=2018-11-11T00:00:00+08:00[Asia/Shanghai],2020-11-11T00:00:00+08:00[Asia/Shanghai]
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
# 如果cookie的名称是abc,cookie的值是根据下面的正则表达式匹配
- Cookie=abc,admin # Cookie的name,正则表达式
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Header=X-Request-Id, \d+ # Header头名称,正则表达式
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Host=**.jd.com # http://surveys.jd.com/和http://passport.jd.com/等都可以匹配
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Method=GET #GET请求匹配
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Path=/foo/{segment} # http://localhost:7007/foo/a等都可匹配
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Query=smile # http://localhost:7007?simle=abc,只要请求中包含smile参数即可
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- Query=smile,abc # http://localhost:7007?simle=abc,请求中包含smile参数且smile的参数值是abc
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
uri: http://localhost:9004 # 路由到微服务的uri
predicates: # 断言(判断条件)
- RemoteAddr=192.168.1.1/24
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api_gateway_server7007</artifactId>
<dependencies>
<!--
Spring Cloud Gateway使用的web框架是webflux,和SpringMVC不兼容。引入的限流组件是Hystrix。Redis底层不再使用jedis,而是lettuce。
-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
package com.sunxiaping.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* @author 许大仙
* @version 1.0
* @since 2020-10-05 19:22
*/
@SpringBootApplication
@EnableEurekaClient
public class Gateway7007Application {
public static void main(String[] args) {
SpringApplication.run(Gateway7007Application.class, args);
}
}
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
# uri: http://localhost:9004
uri: lb://service-product # 路由到微服务的uri。 lb://xxx,lb代表从注册中心获取服务列表,xxx代表需要转发的微服务的名称
predicates: # 断言(判断条件)
- Path=/product/**
# 配置 eureka
eureka:
instance:
# 主机名称:服务名称修改,其实就是向eureka server中注册的实例id
instance-id: api-gateway-server:${server.port}
# 显示IP信息
prefer-ip-address: true
client:
service-url: # 此处修改为 Eureka Server的集群地址
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
在Spring Cloud Gateway中,路由转发是直接将匹配的路由Path直接拼接到映射路径URI之后,那么在微服务开发中往往并不方便。这里可以使用RewritePath机制来进行路径重写。
示例:
1??修改application.yml,将匹配路径改为/product-service/**
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
# uri: http://localhost:9004
uri: lb://service-product # 路由到微服务的uri。 lb://xxx,lb代表从注册中心获取服务列表,xxx代表需要转发的微服务的名称
predicates: # 断言(判断条件)
# - Path=/product/**
- Path:/product-service/**
重启网关,我们在浏览器中访问http://localhost:7007/product-service/product/findById/1,会抛出404。这是因为路由转发规则默认转发的路径是http://localhost:9004/product-service/product/findById/1,商品微服务中没有对应的路径。
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
# uri: http://localhost:9004
uri: lb://service-product # 路由到微服务的uri。 lb://xxx,lb代表从注册中心获取服务列表,xxx代表需要转发的微服务的名称
predicates: # 断言(判断条件)
# - Path=/product/**
- Path=/product-service/**
filters: # 配置路由过滤器 http://localhost:7007/product-service/product/findById/1 --> http://localhost:7007/product/findById/1
- RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路径重写的过滤器
此时我们访问http://localhost:7007/product-service/product/findById/1,会自动转发到http://localhost:9004/product/findById/1。
Spring Cloud Gateway支持根据微服务名称进行自动转发。只需要修改application.yml配置文件即可(需要和Eureka整合)。
示例:
1??修改部分:
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
lower-case-service-id: true # 微服务名称以小写形式呈现
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
lower-case-service-id: true # 微服务名称以小写形式呈现
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
# uri: http://localhost:9004
uri: lb://service-product # 路由到微服务的uri。 lb://xxx,lb代表从注册中心获取服务列表,xxx代表需要转发的微服务的名称
predicates: # 断言(判断条件)
# - Path=/product/**
- Path=/product-service/**
filters: # 配置路由过滤器 http://localhost:7007/product-service/product/findById/1 --> http://localhost:7007/product/findById/1
- RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路径重写的过滤器
# 配置 eureka
eureka:
instance:
# 主机名称:服务名称修改,其实就是向eureka server中注册的实例id
instance-id: api-gateway-server:${server.port}
# 显示IP信息
prefer-ip-address: true
client:
service-url: # 此处修改为 Eureka Server的集群地址
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
logging:
level:
org.springframework.cloud.gateway: trace
org.springframework.http.server.reactive: debug
org.springframework.web.reactive: debug
reactor.ipc.netty: debug
过滤器工厂 | 作用 | 参数 |
---|---|---|
AddRequestHeader | 为原始请求添加Header | Header的名称及值 |
AddRequestParameter | 为原始请求添加请求参数 | 参数名称及值 |
AddResponseHeader | 为原始响应添加Header | Header的名称及值 |
DedupeResponseHeader | 剔除响应头中重复的值 | 需要去重的Header名 称及去重策略 |
Hystrix | 为路由引入Hystrix的断路器保护 | HystrixCommand的名 称 |
FallbackHeaders | 为fallbackUri的请求头中添加具 体的异常信息 | Header的名称 |
PrefixPath | 为原始请求路径添加前缀 | 前缀路径 |
PreserveHostHeader | 为请求添加一个 preserveHostHeader=true的属 性,路由过滤器会检查该属性以 决定是否要发送原始的Host | 无 |
RequestRateLimiter | 用于对请求限流,限流算法为令 牌桶 | keyResolver、 rateLimiter、 statusCode、 denyEmptyKey、 emptyKeyStatus |
RedirectTo | 将原始请求重定向到指定的URL | http状态码及重定向的 url |
RemoveHopByHopHeadersFilter | 为原始请求删除IETF组织规定的 一系列Header | 默认就会启用,可以通 过配置指定仅删除哪些 Header |
RemoveRequestHeader | 为原始请求删除某个Header | Header名称 |
RemoveResponseHeader | 为原始响应删除某个Header | Header名称 |
RewritePath | 重写原始的请求路径 | 原始路径正则表达式以 及重写后路径的正则表 达式 |
RewriteResponseHeader | 重写原始响应中的某个Header | Header名称,值的正 则表达式,重写后的值 |
SaveSession | 在转发请求之前,强制执行 WebSession::save操作 | 无 |
secureHeaders | 为原始响应添加一系列起安全作 用的响应头 | 无,支持修改这些安全 响应头的值 |
SetPath | 修改原始的请求路径 | 修改后的路径 |
SetResponseHeader | 修改原始响应中某个Header的值 | Header名称,修改后 的值 |
SetStatus | 修改原始响应的状态码 | HTTP 状态码,可以是 数字,也可以是字符串 |
StripPrefix | 用于截断原始请求的路径 | 使用数字表示要截断的 路径的数量 |
Retry | 针对不同的响应进行重试 | retries、statuses、 methods、series |
RequestSize | 设置允许接收最大请求包的大 小。如果请求包大小超过设置的 值,则返回 413 Payload Too Large | 请求包大小,单位为字 节,默认值为5M |
ModifyRequestBody | 在转发请求之前修改原始请求体内容 | 修改后的请求体内容 |
ModifyResponseBody | 修改原始响应体的内容 | 修改后的响应体内容 |
每个过滤器工厂都对应一个实体类,并且这些类的名称必须以GatewayFilterFactory结尾,这是Spring Cloud Gateway的一个约定,例如AddRequestHeader对一个的实体类为AddRequestHeaderGatewayFilterFactory。
package com.sunxiaping.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* 自定义全局过滤器
*
* @author 许大仙
* @version 1.0
* @since 2020-10-06 20:24
*/
@Component
public class LoginFilter implements GlobalFilter, Ordered {
/**
* 执行过滤器中的业务逻辑
* 对请求参数中的access-token进行判断,如果存在,则代表认证成功,否则,认证失败。
*
* @param exchange 相当于请求和响应的上下文对象
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String token = request.getHeaders().getFirst("access-token");
if (StringUtils.isEmpty(token)) {
//设置Http的状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//请求结束
return exchange.getResponse().setComplete();
}
//如果存在,继续执行
return chain.filter(exchange);
}
/**
* 指定过滤器的执行顺序,返回值越小,优先级越高
*
* @return
*/
@Override
public int getOrder() {
return 1;
}
}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api_gateway_server7007</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
</dependencies>
</project>
server:
port: 7007
spring:
application:
name: api-gateway-server
# ----------修改部分------------
redis:
host: 192.168.1.57
port: 6379
database: 1
# ----------修改部分------------
# 配置 Spring Cloud Gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
lower-case-service-id: true # 微服务名称以小写形式呈现
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
# uri: http://localhost:9004
uri: lb://service-product # 路由到微服务的uri。 lb://xxx,lb代表从注册中心获取服务列表,xxx代表需要转发的微服务的名称
predicates: # 断言(判断条件)
# - Path=/product/**
- Path=/product-service/**
filters: # 配置路由过滤器
# ----------修改部分------------
- name: RequestRateLimiter # 使用的限流过滤器是Spring Cloud Gateway提供的
args:
# 使用SpEL从容器中获取对象
key-resolver: ‘#{@pathKeyResolver}‘
# 令牌桶每秒填充平均速率
redis-rate-limiter.replenishRate: 1
# 令牌桶的上限
redis-rate-limiter.burstCapacity: 3
# ----------修改部分------------
- RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路径重写的过滤器
# 配置 eureka
eureka:
instance:
# 主机名称:服务名称修改,其实就是向eureka server中注册的实例id
instance-id: api-gateway-server:${server.port}
# 显示IP信息
prefer-ip-address: true
client:
service-url: # 此处修改为 Eureka Server的集群地址
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
package com.sunxiaping.gateway.config;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
/**
* 配置Redis中Key的解析器
*
* @author 许大仙
* @version 1.0
* @since 2020-10-22 09:53
*/
@Configuration
public class KeyResolverConfig {
/**
* 基于请求路径的限流
*
* @return
*/
//@Bean
public KeyResolver pathKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getPath().toString());
}
/**
* 基于请求参数的限流
* 请求/abc?userId=1
*
* @return
*/
//@Bean
public KeyResolver useKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}
/**
* 基于请求IP地址的限流
*
* @return
*/
@Bean
public KeyResolver ipKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getHeaders().getFirst("x-Forwarded-For"));
}
}
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring_cloud_demo</artifactId>
<groupId>org.sunxiaping</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>api_gateway_server7007</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
</dependencies>
</project>
server:
port: 7007
spring:
application:
name: api-gateway-server
# 配置 Spring Cloud Gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
lower-case-service-id: true # 微服务名称以小写形式呈现
routes:
# 配置路由: 路由id,路由到微服务的uri,断言(判断条件)
- id: product-service # 路由id
# uri: http://localhost:9004
uri: lb://service-product # 路由到微服务的uri。 lb://xxx,lb代表从注册中心获取服务列表,xxx代表需要转发的微服务的名称
predicates: # 断言(判断条件)
# - Path=/product/**
- Path=/product-service/**
filters: # 配置路由过滤器
- RewritePath=/product-service/(?<segment>.*), /$\{segment} # 路径重写的过滤器
# 配置 eureka
eureka:
instance:
# 主机名称:服务名称修改,其实就是向eureka server中注册的实例id
instance-id: api-gateway-server:${server.port}
# 显示IP信息
prefer-ip-address: true
client:
service-url: # 此处修改为 Eureka Server的集群地址
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
package com.sunxiaping.gateway.config;
import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.ViewResolver;
import javax.annotation.PostConstruct;
import java.util.*;
/**
* Sentinel限流的配置
*/
@Configuration
public class GatewayConfig {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfig(ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
/**
* 配置限流的异常处理器:SentinelGatewayBlockExceptionHandler
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
return new SentinelGatewayBlockExceptionHandler(this.viewResolvers, this.serverCodecConfigurer);
}
/**
* 配置限流过滤器
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
/**
* 配置初始化的限流参数
* 用于指定资源的限流规则:
* 1.资源名称(路由id)
* 2.配置统计时间窗口
* 3.配置限流阈值
*/
@PostConstruct
public void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("product-service") //资源名称
.setCount(1) // 限流阈值
.setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
);
//配置自定义API分组
rules.add(new GatewayFlowRule("product_api").setCount(1).setIntervalSec(1));
rules.add(new GatewayFlowRule("order_api").setCount(1).setIntervalSec(1));
GatewayRuleManager.loadRules(rules);
}
/**
* 自定义异常提示
*/
@PostConstruct
public void initBlockHandlers() {
BlockRequestHandler blockRequestHandler = (serverWebExchange, throwable) -> {
Map<String, Object> map = new HashMap<>();
map.put("code", "001");
map.put("message", "对不起,接口限流了");
return ServerResponse
.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(map));
};
GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
/**
* 自定义API限流分组
* 1.定义分组
* 2.对小组配置限流规则
*/
@PostConstruct
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("product_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
this.add(new ApiPathPredicateItem().setPattern("/product-service/product/**").
setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition api2 = new ApiDefinition("order_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
this.add(new ApiPathPredicateItem().setPattern("/order-service/order"));
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
}
标签:before min ali 属性 增加 override tst omv his
原文地址:https://www.cnblogs.com/xuweiweiwoaini/p/13858898.html