七.SpringCloud Gateway
1.SpringCloud Gateway知识点
2.SpringCloud Gateway三大核心概念
①Router路由
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
②Predicate断言
参考的是Java8的java.util.function.Predicate 开发人员可以匹配HTTP请求中的所有内容(例如请求头或者请求参数),如果请求与断言相匹配则进行路由
③Filter过滤
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由之前或者之后对请求进行修改
3.SpringCloud Gateway工作流程
核心逻辑:路由转发+执行过滤器链
4.构建项目(路由)
①创建module
②编写pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud
</groupId>
<artifactId>spring-cloud-starter-gateway
</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud
</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client
</artifactId>
</dependency>
<dependency>
<groupId>com.hry.springcloud
</groupId>
<artifactId>cloud-api-commons
</artifactId>
<version>${project.version}
</version>
</dependency>
<dependency>
<groupId>org.springframework.boot
</groupId>
<artifactId>spring-boot-starter-actuator
</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot
</groupId>
<artifactId>spring-boot-devtools
</artifactId>
<scope>runtime
</scope>
<optional>true
</optional>
</dependency>
<dependency>
<groupId>org.projectlombok
</groupId>
<artifactId>lombok
</artifactId>
<optional>true
</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot
</groupId>
<artifactId>spring-boot-starter-test
</artifactId>
<scope>test
</scope>
</dependency>
</dependencies>
③修改yml文件
server:
port: 9527
spring:
application:
name: cloud
-gateway
cloud:
gateway:
routes:
- id: payment_routh1
uri: http
://localhost
:8001
predicates:
- Path=/payment/get/**
- id: payment_routh2
uri: http
://localhost
:8001
predicates:
- Path=/payment/lb/**
eureka:
instance:
hostname: cloud
-gateway
-service
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http
://eureka7001.com
:7001/eureka/
④创建主启动类
package com
.hry
.springcloud
;
import org
.springframework
.boot
.SpringApplication
;
import org
.springframework
.boot
.autoconfigure
.SpringBootApplication
;
import org
.springframework
.cloud
.netflix
.eureka
.EnableEurekaClient
;
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String
[] args
) {
SpringApplication
.run(GatewayMain9527
.class, args
);
}
}
⑤测试
依次启动7001,8001(注意是老的8001不是Hystrix那个8001)和9527 8001 9527 查看返回的端口号
⑥总结
Gateway的网关配置有两种除了前面的yml文件中通过数组配置外,还可以使用编码方式配置。 代码中注入RouteLocator的Bean
package com
.hry
.springcloud
.config
;
import org
.springframework
.cloud
.gateway
.route
.RouteLocator
;
import org
.springframework
.cloud
.gateway
.route
.builder
.RouteLocatorBuilder
;
import org
.springframework
.context
.annotation
.Bean
;
import org
.springframework
.context
.annotation
.Configuration
;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator
customRouteLocator(RouteLocatorBuilder routeLocatorBuilder
){
RouteLocatorBuilder
.Builder routes
= routeLocatorBuilder
.routes();
routes
.route("path_route_163", r
-> r
.path("/163").uri("http://www.163.com"));
return routes
.build();
}
}
5.配置动态路由
通过微服务名实现动态路由
①修改yml文件
添加与修改spring.cloud.gateway下面的内容 添加
discovery:
locator:
enabled: true
修改routes吓的uri
uri: lb
://cloud
-payment
-service
修改后的spring.cloud内容为
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: payment_routh1
uri: lb
://cloud
-payment
-service
predicates:
- Path=/payment/get/**
- id: payment_routh2
uri: lb
://cloud
-payment
-service
predicates:
- Path=/payment/lb/**
②测试
测试之前启动8002
6.断言
我们之前使用过path
(1)测试After
- After=2020
-07
-04T13
:00
:00.000+08
:00
[Asia/Shanghai
]
剩下的两个同理
(2)测试Cookie
- Cookie=username
,springcloud
使用curl测试 打开cmd 不带cookie时 带cookie
(3)测试Header
- Header=X
-Request
-Id
, \d+
(5)总结
偷懒了
7.过滤
①默认自带的过滤器
生命周期:
pre(业务之前)post(业务之后)
种类:
GatewayFilter(单一) 数量有31种之多GlobalFilter(全局) 10种 用法跟断言类似在yml中使用filter:
②自定义全局过滤器
需要 implements GlobalFilter,Ordered 两个接口
(1)创建过滤类
package com
.hry
.springcloud
.filter
;
import lombok
.extern
.slf4j
.Slf4j
;
import org
.springframework
.cloud
.gateway
.filter
.GatewayFilterChain
;
import org
.springframework
.cloud
.gateway
.filter
.GlobalFilter
;
import org
.springframework
.core
.Ordered
;
import org
.springframework
.http
.HttpStatus
;
import org
.springframework
.stereotype
.Component
;
import org
.springframework
.web
.server
.ServerWebExchange
;
import reactor
.core
.publisher
.Mono
;
import java
.util
.Date
;
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered
{
@Override
public Mono
<Void> filter(ServerWebExchange exchange
, GatewayFilterChain chain
) {
log
.info("MyLogGateWayFilter: "+new Date());
String uname
= exchange
.getRequest().getQueryParams().getFirst("uname");
if (uname
== null
){
log
.info("用户名为null,非法用户,想通过门都没有");
exchange
.getResponse().setStatusCode(HttpStatus
.NOT_ACCEPTABLE
);
return exchange
.getResponse().setComplete();
}
return chain
.filter(exchange
);
}
@Override
public int getOrder() {
return 0;
}
}
(2)测试