首页
Spring Cloud Gateway
1.Route(路由)
路由是构建网关的基础模块,它由ID,目标URI,包括一些列的断言和过滤器组成,如果断言为true则匹配该路由
2.Predicate(断言)
参考的是Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),请求与断言匹配则进行路由
3.Filter(过滤)
指的是Spring框架中GateWayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
三个核心点连起来:
用户发送请求到网关,如果断言生效则匹配某一个路由,从而转发到某一个目标url,前面都是配置文件可以实现,但是如果需要写代码就需要使用过滤器
1.引入依赖。在父项目当中引入依赖。
(基于自己项目的情况,如果不引入这种管理项目,单独引入gateway的依赖也完全没问题)
Hoxton.SR8
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud-gateway-varsion}
pom
import
2.在gateway那个服务也引入依赖,记得这个web的服务不能存在
org.springframework.cloud
spring-cloud-starter-gateway
3.引入配置文件。application.yml
server:
port: 80
spring:
application:
name: mall-gateway
cloud:
gateway:
routes:
- id: route1
# 最终地址
uri: http://wwww.baidu.com
# 断言规则 传输随便一个地址,有url参数,参数值是baidu
# 就会转发到百度首页
predicates:
- Query=url,baidu
到这里搭建就已经完成了,只要请求这个网关服务,并且在地址后添加上 ?url=baidu就可以将任何地址转发到百度首页了
配置路由除了,配置文件的方式,还有代码的方式也可以
略
server:
port: 80
spring:
application:
name: mall-gateway
cloud:
nacos:
server-addr: 192.168.15.132:8848
gateway:
discovery:
locator:
enabled: true #是否与服务发现组件进行结合,通过serviceId转发到具体的服务实例。默认为false,设为true便开启通过服务中心的自动根据 serviceId 创建路由的功能。并且这还有负载均衡的功能
# 举例 如果nacos当中有一个product服务
# 如果请求网关的路径是 http://localhost:80/product/A
# 最终请求地址就是http://localhost:9001/A
# 断言的优先级比这个自动的高
(这个路由地址应该是这样的,暂时没有验证)
server:
port: 80
spring:
application:
name: mall-gateway
cloud:
nacos:
server-addr: 192.168.15.132:8848
gateway:
routes: # 路由
- id: product #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: lb://product # 匹配提供服务的路由地址
predicates: # 断言
- Path=/lizhi/**
# 如果请求网关的路径是 http://localhost:80/lizhi/A
# 最终请求地址就是http://localhost:9001/lizhi/A 或者 http://localhost:9002/product/lizhi/A
(这个路由地址应该是这样的,暂时没有验证)
After:匹配在指定日期时间之后发生的请求。
Before:匹配在指定日期之前发生的请求。
Between:需要指定两个日期参数,设定一个时间区间,匹配此时间区间内的请求。
Cookie:需要指定两个参数,分别为name和regexp(正则表达式),也可以理解Key和Value,匹配具有给定名称且其值与正则表达式匹配的Cookie。
Header:需要两个参数header和regexp(正则表达式),也可以理解为Key和Value,匹配请求携带信息。
Host:匹配当前请求是否来自于设置的主机。
Method:可以设置一个或多个参数,匹配HTTP请求,比如GET、POST
Path:匹配指定路径下的请求,可以是多个用逗号分隔
Query:需要指定一个或者多个参数,一个必须参数和一个可选的正则表达式,匹配请求中是否包含第一个参数,如果有两个参数,则匹配请求中第一个参数的值是否符合正则表达式。
RemoteAddr:匹配指定IP或IP段,符合条件转发。
Weight:需要两个参数group和weight(int),实现了路由权重功能,按照路由权重选择同一个分组中的路由
过滤器的作用:
Filter在pre类型的过滤器可以做参数效验、权限效验、流量监控、日志输出、协议转换等
Filter在post类型的过滤器可以做响应内容、响应头的修改、日志输出、流量监控等
GateWay内置的Filter生命周期为两种:pre(业务逻辑之前)、post(业务逻辑之后)
GateWay本身自带的Filter分为两种: GateWayFilter(单一)、GlobalFilter(全局)
单一的有32种,全局的有9种
只用一个举例(StripPrefix)
server:
port: 80
spring:
application:
name: mall-gateway
cloud:
nacos:
server-addr: 192.168.15.132:8848
gateway:
routes: # 路由
- id: product #路由ID,没有固定要求,但是要保证唯一,建议配合服务名
uri: lb://product # 匹配提供服务的路由地址
predicates: # 断言
- Path=/lizhi/**
filters:
- StripPrefix=1 # 去掉地址中的第一部分
# 如果请求网关的路径是 http://localhost:80/lizhi/product/lizhi/A
# 最终请求地址就是http://localhost:9001/product/lizhi/A 或者 http://localhost:9002/product/lizhi/A
@Component
@Slf4j
public class MyFilter implements Ordered, GlobalFilter {
/**
* @param exchange 可以拿到对应的request和response
* @param chain 过滤器链
* @return 是否放行
*/
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String username = exchange.getRequest().getQueryParams().getFirst("username");
log.info("*************MyFilter:"+new Date());
if(username == null){
log.info("**********用户名为null,非法用户,请求被拒绝!");
//如果username为空,返回状态码为406,不可接受的请求
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 加载过滤器的顺序
* @return 整数数字越小优先级越高
*/
@Override
public int getOrder() {
return 0;
}
}
@Configuration
public class MallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
// corsConfiguration.addAllowedOrigin("*");
// SpringBoot 升级到 2.4.0 需要使用 如下配置
corsConfiguration.addAllowedOriginPattern("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}