Gateway篇
网关的功能作用
- 同一入口
- 负载均衡
- 流量控制
- 身份认证
- 协议转换
- 系统监控
- 安全防护
- 请求路由
访问流程
1、创建网关
由于网关不属于业务,属于架构,因此新建一个模块,然后添加依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
响应式Netty
2、网关配置
2.1、使用配置文件的方式配置路由规则
示例:
spring:
cloud:
gateway:
routes:
- id: order-route
# 负载均衡到指定的微服务
uri: lb://service-order
# 断言规则(判断规则)
predicates:
# 根据路径,只要是/api/order开头的请求地址都放行
- Path=/api/order/**
# 过滤器
# filters:
# 扩展配置
# metadata:
# 顺序,数字越小优先级越高
order: 0
3、基础原理
4、断言规则
长写法示例:
uri: https://cn.bing.com/
predicates:
- name: Path
args:
patterns: /search
- name: Query
args:
param: q
regexp: hhh
上述示例是访问必应的,但是并不是所有都能访问,必须是如下规则
http://localhost:gatewayPort/search?q=hhh
这样的才能访问必应进行搜索
因为断言中设置了两种规则,且必须同时满足才会放行
5、自定义断言规则
示例: 添加断言规则,名称为IsAdmin 用于判断是否是管理员,以下是自定义路由断言的规则
//需要注册到容器中
@Component
public class IsAdminRoutePredicateFactory extends AbstractRoutePredicateFactory<IsAdminRoutePredicateFactory.Config> {
// 构造函数
public IsAdminRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
// 使用lambda表达式
return (GatewayPredicate) serverWebExchange -> {
// 获取请求
ServerHttpRequest request = serverWebExchange.getRequest();
// 获取请求的参数对应的值
String value = request.getQueryParams().getFirst(config.key);
// 判断
if(StringUtils.hasText(value) && value.equals(config.value)){
return true;
}
return false;
};
// 使用非lambda方式
// return new GatewayPredicate() {
// @Override
// public boolean test(ServerWebExchange serverWebExchange) {
//// 获取请求
// ServerHttpRequest request = serverWebExchange.getRequest();
//// 获取请求的参数对应的值
// String value = request.getQueryParams().getFirst(config.key);
//// 判断
// if(StringUtils.hasText(value) && value.equals(config.value)){
// return true;
// }
// return false;
// }
// };
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("key","value");
}
// 使用内部类作为配置类
public static class Config {
@NotEmpty
private String key;
@NotEmpty
private String value;
public @NotEmpty String getKey() {
return key;
}
public void setKey(@NotEmpty String key) {
this.key = key;
}
public @NotEmpty String getValue() {
return value;
}
public void setValue(@NotEmpty String value) {
this.value = value;
}
}
}
在配置文件中:
predicates:
# 短写法
- IsAdmin=userType,admin
# 长写法
- name: IsAdmin
args:
key: userType
value: admin
# 访问携带参数的地址示例
`http://xxxx:xx/api/user/login?userType=admin`
命名规则,RoutePredicateFactory前面的IsAdmin为断言的名称,固定的,比如SearchRoutePredicateFactory,那么Search就是断言的名称。
6、过滤器
主要用于对请求的请求头、请求体、请求路径做一定的增删改。
以rewritePath为例:
filters:
# ? 表示没有或有,如果有,则api/order/xxx通过segment进行接收,然后替换为只剩下segment
# /$ 以/开头
- RewritePath: /api/order/?(?segment>.*),/$\{segment}
在没有设置之前,每个controller都需要添加上相应的/api/xxx
7、自定义过滤器
示例:
// 过滤器定义
@Component
public class AuthTypeGatewayFilterFactory extends AbstractGatewayFilterFactory<AuthTypeGatewayFilterFactory.Config> {
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> chain.filter(exchange).doFirst(() -> {
ServerHttpRequest request = exchange.getRequest();
request.getHeaders().add(config.key,config.value);
});
}
public static class Config {
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
配置文件中
filters:
- AuthType=admin,jwt
命名规则:名称与断言命名规则相同
文章的顺序根据spring cloud 快速开始 起始篇开始的顺序排序。