目录
概念
gateway提供统一请求入口,进行统一的逻辑处理,对后端微服务集群进行负载均衡和网络隔离
步骤
1.网关获取到请求地址,默认截取域名后面的部分请求路径 /product-serv/product/1
2.拿到路径信息和路由规则进行匹配,可以获取到对应的服务名product-service
3.拿到服务名在本地的缓存列表中找到对应的IP地址
4.进行URL地址拼接 http://192.168.10.110/product/1,进行网络的调用
网关自定义路由
spring:
cloud:
gateway:
routes:
- id: product_route
uri: lb://product-service
predicates:
- Path=/product-serv/**
filters:
- StripPrefix=1
- id: order_route
uri: lb://order-service
predicates:
- Path=/order-serv/**
filters:
- StripPrefix=1
过滤器
过滤器就是在请求的传递过程中,对请求和响应做⼀些手脚.
在Gateway中, Filter的生命周期只有两个:“pre” 和 “post”。
PRE: 这种过滤器在请求被路由之前调⽤。我们可利⽤这种过滤器实现身份验证、在集群中选择 请求的微服务、记录调试信息等。
POST:这种过滤器在路由到微服务以后执⾏。这种过滤器可⽤来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
在Gateway中,Filter的作用范围两种:
- GatewayFilter:应⽤到单个路由或者⼀个分组的路由上。
- GlobalFilter:应⽤到所有的路由上
局部过滤器
@Component
public class TimeGatewayFilterFactory extends
AbstractGatewayFilterFactory<TimeGatewayFilterFactory.Config>{
private static final String BEGIN_TIME = "beginTime";
//构造函数
public TimeGatewayFilterFactory() {
super(TimeGatewayFilterFactory.Config.class);
}
//读取配置⽂件中的参数 赋值到 配置类中
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("show");
}
@Override
public GatewayFilter apply(Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
if(!config.show){
return chain.filter(exchange);
}
exchange.getAttributes().put(BEGIN_TIME,
System.currentTimeMillis());
/**
* pre的逻辑
* chain.filter().then(Mono.fromRunable(()->{
* post的逻辑
* }))
*/
return chain.filter(exchange).then(Mono.fromRunnable(()->{
Long startTime = exchange.getAttribute(BEGIN_TIME);
if (startTime != null) {
System.out.println(exchange.getRequest().getURI() +
"请求耗时: " + (System.currentTimeMillis() - startTime) + "ms");
}
}));
}
};
}
@Setter
@Getter
static class Config{
private boolean show;
}
}
全局过滤器
全局过滤器作用于所有路由, 无需配置。通过全局过滤器可以实现对权限的统⼀校验,安全性验证等功能
@Component
public class AuthGlobalFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain
chain) {
String token =
exchange.getRequest().getQueryParams().getFirst("token");
if (StringUtils.isBlank(token)) {
System.out.println("鉴权失败");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
}
Sentinel实现网关流控
1.添加依赖
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> </dependency>
2.配置文件配置
spring: cloud: sentinel: transport: port: 9999 dashboard: localhost:8080
3.sentinel管控台设置
设置api分组,对对应的api分组进行流控