Gateway 服务网关
快速开始
@Configuration
public class GatewayRoutes {
@Autowired
private DefaultInit defaultInit;
@Autowired
private MyGatewayFilter myGatewayFilter;
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("api",p -> p.path("/api/**").and().asyncPredicate(initMyRoutePredicateFactory().applyAsync(config -> config.setHeaderName("Authorization"))).filters(f -> f.filter(myGatewayFilter).hystrix(config -> config
.setName("some")
.setFallbackUri("forward:/fallback"))).uri("https://www.baidu.com/")).build();
}
@Bean
public MyRoutePredicateFactory initMyRoutePredicateFactory(){
return new MyRoutePredicateFactory(MyRoutePredicateFactory.Config.class);
}
}
可通过自定义filter控制跳转路径或者权限控制 也可以通过自定义断言PredicateFactory控制自定义权限
filter 这里实现了自定义跳转路径及执行时间打印
public class MyGatewayFilter implements GatewayFilter ,Ordered{
private static final Logger logger = LoggerFactory.getLogger(BaseController.class);
private static final String TIME = "TIME";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
exchange.getAttributes().put(TIME, System.currentTimeMillis());
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
String rawPath = exchange.getRequest().getURI().getRawPath();
rawPath = rawPath.substring(rawPath.indexOf(route.getUri().getPath())+route.getUri().getPath().length());
//重定义路由
Route newRoute = Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters()).id(route.getId()).order(route.getOrder())
.uri(route.getUri().toString()+rawPath).build();
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR, newRoute);
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
Long start = exchange.getAttribute(TIME);
if (start != null) {
logger.info("请求路径:{}, 响应时长:{} ms",exchange.getRequest().getURI(),(System.currentTimeMillis() - start) );
}
}));
}
@Override
public int getOrder() {
return 0;
}
}
MyRoutePredicateFactory 这里实现简单token判断
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {
/**
* @param configClass
*/
public MyRoutePredicateFactory(Class<Config> configClass) {
super(configClass);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
//判断header里有放token
HttpHeaders headers = exchange.getRequest().getHeaders();
List<String> header = headers.get(config.getHeaderName());
//TODO token逻辑判断
return header!=null&&header.size() > 0;
};
}
public static class Config {
private String headerName;
public String getHeaderName() {
return headerName;
}
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
}
}
fallback
@RestController
public class FallbackController {
private static final Logger logger = LoggerFactory.getLogger(FallbackController .class);
@RequestMapping("/fallback")
public Mono<String> fallback(ServerWebExchange exchange) {
return Mono.just("该服务暂时不可用");
}
}