1、Spring Cloud Gateway是Spring官方提供的API网关
2、Gateway是基于Spring5和Spring Boot2开发的
3、Gateway是基于Netty开发的异步调用网关
org.springframework.boot
spring-boot-starter-webflux
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.boot
spring-boot-starter-webflux
#配置示例
spring:
cloud:
gateway:
routes:
- id: xxx-predicate
uri: "http://www.jd.com"
predicates:
- Path=/xxx/**
1、提供动态路由和限流等措施
2、易于编写的Predicate和Filter,提供了良好的扩展性
3、提供了Discovery和Hystrix的集成
#Hystrix Filter配置:
spring:
cloud:
gateway:
routes:
- id: xxx-predicate
uri: "http://www.jd.com"
predicates:
- Path=/xxx/**
filter:
- name: Hystrix
args:
name: ExampleHystrix
fallbackUri: forward:/fallback
1、Predicate是路由匹配规则,满足条件即可触发路由
2、Predicate可以进行自定义,满足个性化要求
#Path是断言的名字,等号后面是断言的值
spring:
cloud:
gateway:
routes:
- id: xxx-predicate
uri: "http://www.jd.com"
predicates:
- Path=/xxx/**
- After=2020-10-25
/**
* @author : zhenghaorui
* @program : com.springcloud.gatewaydemo.predicates
* @description : 日期路由自定义
**/
//注意:自定义类继承AbstractRoutePredicateFactory,并且命名必须以RoutePredicateFactory结尾,而RoutePredicateFactory前面自定义的名字是断言的名字
public class AfterRoutePredicateFactory extends AbstractRoutePredicateFactory {
public static final String AFTER_KEY = "datetime";
/**
* @Description: 传入配置信息
* @Param: []
* @return:
* @Author: zhenghaorui
*/
public JiangzhAfterRoutePredicateFactory() {
super(JiangzhAfterRoutePredicateFactory.Config.class);
}
/**
* @Description: 参数列表与Config属性之间的映射
* @Param: []
* @return: java.util.List
* @Author: zhenghaorui
*/
@Override
public List shortcutFieldOrder() {
return Collections.singletonList(AFTER_KEY);
}
/**
* @Description: 具体的路由匹配逻辑
* @Param: [config]
* @return: java.util.function.Predicate
* @Author: zhenghaorui
*/
@Override
public Predicate apply(Config config) {
System.out.println("JiangzhAfterRoutePredicateFactory -> config : "+config);
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
long nowTime = System.currentTimeMillis();
return (exchange) -> {
// 解析出配置定义的时间
long afterTime = 0;
try {
afterTime = format.parse(config.getDatetime()).getTime();
} catch (ParseException e) {
return false;
}
// 如果当前时间大于配置定义时间,则返回true
return nowTime > afterTime;
};
}
/**
* @Description: 用于承载断言传入的值
* @Param: 我们这里是判断输入的时间与真实时间之间的先后关系
* @Author: zhenghaorui
*/
public static class Config {
@NotEmpty
private String datetime;
public Config() {
}
public String getDatetime() {
return datetime;
}
public void setDatetime(String datetime) {
this.datetime = datetime;
}
}
}
@Configuration
public class GWConf {
@Bean
public AfterRoutePredicateFactory initAfterRoutePredicateFactory() {
return new AfterRoutePredicateFactory();
}
}
3、Spring Cloud Gateway预置了很多Predicate
1、Filter可以对Request进行请求过滤处理
2、Gateway的Filter分为全局和局部两种
1)自定义全局Filter:
/**
* @author : zhenghaorui
* @program : com.springcloud.gatewaydemo.Filters
* @description : 自定义全局Filter
**/
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
/**
* @Description : 业务处理逻辑
* @Param : [exchange, chain]
* @return : reactor.core.publisher.Mono
* @Author : zhenghaorui
**/
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
long beginTime = System.currentTimeMillis();
log.info("filter start ----> beginTime:{}", beginTime);
return chain.filter(exchange).then(Mono.fromRunnable(()->{
long endTime = System.currentTimeMillis();
log.info("filter end ----> endTime{}, cost:{}",endTime , endTime-beginTime);
}));
}
/**
* @Description : 判断Filter顺序
* @Param : []
* @return : int
* @Author : zhenghaorui
**/
@Override
public int getOrder() {
return 0;
}
}
@Configuration
public class GWConf {
@Bean
public AfterRoutePredicateFactory initAfterRoutePredicateFactory() {
return new AfterRoutePredicateFactory();
}
@Bean
public MyGlobalFilter initMyGlobalFilter() {
return new MyGlobalFilter();
}
}
2)自定义局部Filter:
#配置示例
spring:
cloud:
gateway:
routes:
- id: xxx-predicate
uri: "http://www.jd.com"
predicates:
- Path=/xxx/**
- After=2020-10-25
filter:
- Example=paramName,paramValue
/**
* @author : zhenghaorui
* @program : com.springcloud.gatewaydemo.Filters.factorys
* @description :
**/
@Slf4j
@Component
public class ExampleGatewayFilterFactory extends AbstractGatewayFilterFactory {
private static String PARAM_NAME="paramName";
private static String PARAM_VALUE="paramValue";
public JiangzhGatewayFilterFactory(){
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
Set keys = exchange.getRequest().getQueryParams().keySet();
for(String key : keys){
log.info("key:{} , value:{}", key, exchange.getRequest().getHeaders().get(key));
}
List headNames = exchange.getRequest().getQueryParams().get(config.getParamName());
if(headNames!=null && headNames.size()>0){
log.info("PARAM_NAME:{},PARAM_VALUE:{}, headNames:{}",config.getParamName(),config.getParamValue(),headNames);
if(config.getParamValue().equalsIgnoreCase(headNames.get(0))){
return chain.filter(exchange);
}
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
}else{
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
}
return exchange.getResponse().setComplete();
});
}
@Override
public List shortcutFieldOrder() {
return Arrays.asList(PARAM_NAME,PARAM_VALUE);
}
@Data
public static class Config{
private String paramName;
private String paramValue;
public String getParamName() {
return paramName;
}
public void setParamName(String paramName) {
this.paramName = paramName;
}
public String getParamValue() {
return paramValue;
}
public void setParamValue(String paramValue) {
this.paramValue = paramValue;
}
}
}
3)预定义全局Filter:
4)预定义局部Filter:
3、Filter除了过滤还可以对请求内容进行增强处理