概述:


一句话:

….

我们为什么选择 Gatway?



Zuul1.x 模型


GateWay 模型

路由的构建网关的基本模块,它由 ID ,目标 URI , 一系列的断言和过滤器组成,如果断言为 true 则匹配该路由
参考的是 java8 的 java.util.function.Predicate 开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求域断言相匹配则进行路由。
指的是 Spring 框架中 GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。



路由转发+执行过滤器链
新建 Module: cloud-gateway-gateway9527
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>clould</artifactId>
<groupId>com.oy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-gateway-gateway9527</artifactId>
<dependencies>
<!--新增 gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.oy</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>
</project>YML
server:
port: 9527
spring:
application:
name: cloud-gateway
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表中
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka业务类 (无)
主启动类
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GateWayMain9527.class, args);
}
}**9527 网关如何做路由映射那? ? ? **
YML 新增网关配置
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
uri: http://localhost:8001
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_route2
uri: http://localhost:8001
predicates: Path=/payment/lb/** #断言,路径相匹配的进行路由
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表中
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka测试
访问说明



YML 配置说明
Gateway 网关路由有两种配置方式
官网案例 :

自己写一个: 业 务 需 求 : 通 过 9527 网 关 访 问 到 外 网 的 百 度 新 闻 网 址 http://news.baidu.com/guoji

/**
* 配置网关
* @Author OY
* @Date 2020/10/18
*/
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_rote_oy", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
@Bean
public RouteLocator customRouteLocator2(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes.route("path_rote_oy2", r -> r.path("/guoji").uri("http://news.baidu.com/guoji")).build();
return routes.build();
}
}测试:

默认情况下 Gateway 会根据注册中心的服务列表,以注册中心上微服务名为路径路径创建动态路由创建动态路由进行转发,从而实现动态路由的功能
启动: 一个 eureka7001 + 两个服务提供者 8001/8002
POM

YML: uri: lb//cloud-payment-service
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名称j进行路由
routes:
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#匹配后提供服务的路由地址
#uri: http://localhost:8001
uri: lb//cloud-payment-service
predicates:
- Path=/payment/get/** # 断言,路径相匹配的进行路由
- id: payment_route2
#uri: http://localhost:8001
uri: lb//cloud-payment-service
predicates: Path=/payment/lb/** #断言,路径相匹配的进行路由
eureka:
instance:
hostname: cloud-gateway-service
client: #服务提供者provider注册进eureka服务列表中
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka需要注意的是uri 的协议为 lb ,表示启用 Gateway 负载均衡功能。
lb ://serviceName 是 spring cloud gateway 在微服务中自动为我们创建负载均衡 uri。
测试:
http://localhost:9527/payment/lb: 8001/8002 两个端口切换

启动我们的 gateway9527




After Route Predicate

问题一:上述这个 After 好懂,这个时间时间串串,有点不能理解。使用以下方式即可解开谜团。
@Test
public void test1(){
ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
System.out.println(zbj); // 2020-10-18T10:35:52.127+08:00[Asia/Shanghai]
ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/Denver"));// 用指定时区获取当前时间
System.out.println(zny); // 2020-10-17T20:38:37.693-06:00[America/Denver]
}
YML
- After=2020-10-18T10:38:37.692+08:00[Asia/Shanghai]
Before Route Predicate
YML
- After=2020-10-18T10:38:37.692+08:00[Asia/Shanghai]
- Before=2020-10-18T10:38:37.692+08:00[Asia/Shanghai]Between Route Predicate
YML
- Between=2020-10-18T10:38:37.692+08:00[Asia/Shanghai],2020-10-19T10:38:37.692+08:00[Asia/Shanghai]Cookie Route Predicate

1) 不带 cookies 访问

2) 带上 cookies 访问

加 入 curl 返 回 中 文 乱 码 :https://blog.csdn.net/leedee/article/details/82685636
curl http://localhost:9527/payment/lb --cookie "username=oy"3)YML
- Cookie=username,oy #并且Cookie是username=oy才能访问
Header Route Predicate

YML
- Header=X-Request-Id, \d+ #请求头中要有X-Request-Id属性并且值为整数的正则表达式

Host Route Predicate

YML
- Host=**.somehost.org,**.anotherhost.orgMethod Route Predicate

YML
- Method=GET,POSTPath Route Predicate
YML
- Path=/red/{segment},/blue/{segment}Query Route Predicate

YML
- Query=username, \d+ #要有参数名称并且是正整数才能路由
测试: http://localhost:9527/payment/lb?username=1

小总结
All

说白了,Predicate就是为了实现一组匹配规则, 让请求过来找到对应的Route进行处理

AddRequestParameter
YML

自定义全局 GlobalFilter
impiemerts GlobalFilter , Ordered@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("*********come in MyLogGateWayFilter: "+new Date());
String username = exchange.getRequest().getQueryParams().getFirst("username");
if(username == null){
log.info("*****用户名为 NUll 非法用户.(┬_┬)");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);// 给人家一个回应
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}测试
启动


