Gateway
为什么要使用网关
- 与前端对接时 因为不同的服务需要部署到不同的系统中 前端需要记住各服务的ip地址和端口号 服务太多 前端易错 若服务ip 端口更改后 还需要修改前端代码 不易于维护。
- 可以将各服务统一代码抽取到网关中 不用多次实现 易于维护
- 网关可以统一屏蔽恶意请求 如sql注入 ssl攻击
简单使用
导入依赖
org.springframework.cloud
spring-cloud-starter-gateway
首先gateway配置文件
id 为路由唯一标识符
uri 服务的路由地址
predicates 路由规则以制定条件匹配 若符合条件则路由到制定服务
filter 修改请求地址
例子: 当使用predicates成功地址为127.0.0.1:8003/provider-ser/sayLyra 路由转发后地址为127.0.0.1:8001/provider-ser/sayLyra
而原服务地址127.0.0.1:8003/sayLyra 这就导致路由匹配不上 可以使用 filter来修改路由地址 使其匹配
server:
port: 8003
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: provider-router
uri: http://127.0.0.1:8001
predicates:
- Path=/provider-ser/**
filters:
- StripPrefix=1
整合nacos
导依赖 写yaml添加注解没什么好说的
若提示503错误 查看是否导入负载均衡依赖
使用lb://服务名设置uri
gateway:
routes:
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
filters:
- StripPrefix=1
自动匹配uri
根据服务名称拼接转发服务
gateway:
discovery:
locator:
enabled: true
断言
After: 之后的时间才允许匹配 时间格式必须为ZonedDateTime
routes:
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
- After=2021-12-12T17:06:51.869229+08:00[Asia/Shanghai]
Before: 与after相反 之前时间允许匹配
routes:
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
- Before=2020-12-12T17:06:51.869229+08:00[Asia/Shanghai]
Between两个时间之间才允许匹配
routes:
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
- Between=2020-12-12T17:06:51.869229+08:00[Asia/Shanghai], 2021-12-12T17:06:51.869229+08:00[Asia/Shanghai]
Cookie: 根据cookie的key和value进行匹配
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
- Cookie=name, lyra
Header: 若header存在则匹配
routes:
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
- Header=User-Agen
Host: 根据host进行匹配
routes:
- id: provider-router
uri: lb://provider-service
predicates:
- Path=/provider-ser/**
- Host=www.imoocnews.com:8003
自定义断言
条件:
- 必须为bean对象
- 类名称必须以RoutePredicateFactory
- 必须有一个Config内部类用于yaml中传入的参数
- apply内部类中 有一个test方法 若这个方法返回true则运行通过 false为拦截
- shortcutFieldOrder中填写获取的参数key 必须与config内部类一致
@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory {
public MyRoutePredicateFactory() {
super(MyRoutePredicateFactory.Config.class);
}
// 必须与config内部类成员对象一致
@Override
public List shortcutFieldOrder() {
return Arrays.asList("name");
}
@Override
public Predicate apply(MyRoutePredicateFactory.Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
// 返回true则通过 返回false则拦截
return Objects.equals(config.getName(), "Lyra");
}
};
}
@Validated
public static class Config {
@NotEmpty
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}