一、Gateway介绍
Spring Cloud Gateway是Spring Cloud的一个全新项目,基于Spring 5,Spring Boot 2和 Project Reactor等技术开发的网关,它旨在为微服务框架提供一种简单有效的统一的API路由管理方式,以及基于Filter方式提供一些强大的过滤功能,例如:熔断、限流、重试等
Spring Cloud Gateway作为spring Cloud 生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本Zuul 2.0以上最新高性能版本进行集成,仍然还是Zuul 1.x非Reactor模式的老版本,而为了提升网关的性能,Spring Cloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway功能:
1、基于Spring Framework 5,Project Reactor和Spring Boot 2.0构建
2、能够匹配任何请求属性上的路由。
3、断言和过滤器特定于路由。
4、Hystrix断路器集成。
5、Spring Cloud DiscoveryClient集成
6、易于编写的断言和过滤器
7、请求速率限制
8、路径改写
Spring Cloud 架构图
由此可以知道网关在整个SpringCloud 中的位置
二、Gateway工作流程
工作流程图
客户端向Spring Cloud Gateway发出请求。如果网关处理程序(Gateway Handler Mapping)映射确定请求与路由匹配,则将其发送到网关Web处理程序(Gateway Web Handler.)。该处理程序通过特定于请求的过滤器链来运行请求。过滤器由虚线分隔的原因是,过滤器可以在发送代理请求之前和之后运行逻辑。所有“pre”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“post”过滤器逻辑。
Filter,在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出、流量监控等,有非常重要的作用
三、搭建项目
-
pom.xml
<dependencies> <!--gateway 该依赖与spring-boot-starter-web冲突--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--进行排除--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <scope>test</scope><!--定义scope为test,打包则不会出现--> </dependency> <!--eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
-
application.yml
server:
port: 9009 #端口号
spring:
application:
name: microServiceCloudGateway #服务注册中心注册的服务名
security:
user:
name: root
password: root
cloud:
gateway: #网关路由配置
discovery:
locator:
enabled: true #默认值为 true,即默认开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
#将 micro-service-cloud-provider-dept-8001 提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址 9009
- id: provider_dept_list_routh #路由 id,没有固定规则,但唯一,建议与服务名对应
uri: http://localhost:8001 #动态路由,使用服务名代替上面的具体带端口
predicates:
#以下是断言条件,必须全部符合条件(可以写多个predicate)
- Path=/payment/** #断言,路径匹配 注意:Path 中 P 为大写
- Weight=group1, 8 #这条路线会将大约80%的流量转发到http://localhost:8001,将大约20%的流量转发到http://localhost:9001
#- Method=GET #只能时 GET 请求时,才能访问
#- After=2020-01-01T00:00:00.308+08:00[Asia/Shanghai] #符合2020年01月01日00:00时区时间(上海)之后的任何请求。
#- Before=2030-01-01T23:59:59.308+08:00[Asia/Shanghai] #符合2030年01月01日23:59时区时间(上海)之后的任何请求。
#- Between=2020-04-20T23:57:57.308+08:00[Asia/Shanghai], 2020-04-21T23:57:57.308+08:00[Asia/Shanghai] #……
#- Cookie=username, wangshuo #此路由匹配具有名称为username与wangshuo正则表达式匹配的cookie的请求。
#- Header=X-Request-Id, \d+ #请求具有名为X-Request-Id其值与\d+正则表达式匹配的标头(即,其值为一个或多个数字),则此路由匹配。#测试请求命令:curl http://localhost:9009/payment/get/1 -H "X-Request-Id:123"
#- Host=**.x.com #请求具有这种路由匹配Host用的头值**.x.com
#- Query=green #请求包含green查询参数,则前面的路由匹配。 #测试请求命令:curl http://localhost:9527/payment/get/1?green=1
- id: weight_low
uri: http://localhost:9001
predicates:
- Weight=group1, 2 #这条路线会将大约80%的流量转发到http://localhost:8001,将大约20%的流量转发到http://localhost:9001
eureka:
instance:
instance-id: micro-service-cloud-gateway-9527
hostname: micro-service-cloud-gateway
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@eureka1.com:8887/eureka
-
App
1 package com.sdkj; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 7 /** 8 * @Author wangshuo 9 * @Date 2022/5/24, 22:03 10 * Please add a comment 11 */ 12 @EnableEurekaClient 13 @SpringBootApplication 14 public class App { 15 16 public static void main(String[] args) { 17 SpringApplication.run(App.class, args); 18 } 19 }
四、通过配置类来配置路由
-
MyGateWayFilter(指定访问参数)
1 package com.sdkj.config; 2 3 import org.springframework.cloud.gateway.filter.GatewayFilterChain; 4 import org.springframework.cloud.gateway.filter.GlobalFilter; 5 import org.springframework.core.Ordered; 6 import org.springframework.stereotype.Component; 7 import org.springframework.web.server.ServerWebExchange; 8 import reactor.core.publisher.Mono; 9 10 /** 11 * @Author wangshuo 12 * @Date 2022/5/25, 10:10 13 * Please add a comment 14 */ 15 @Component 16 public class MyGateWayFilter implements GlobalFilter, Ordered { 17 @Override 18 public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { 19 String uname = exchange.getRequest().getQueryParams().getFirst("uname"); 20 if (uname == null) { 21 System.out.println("非法访问"); 22 throw new RuntimeException("非法访问,请输入用户名"); 23 } 24 // 成功 25 return chain.filter(exchange); 26 } 27 28 @Override 29 public int getOrder() { 30 return 0; 31 } 32 }
-
GatewayConfig(配置路由转发)
1 package com.sdkj.config; 2 3 import org.springframework.cloud.gateway.route.RouteLocator; 4 import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.context.annotation.Configuration; 7 8 /** 9 * @Author wangshuo 10 * @Date 2022/5/25, 8:29 11 * Please add a comment 12 */ 13 @Configuration 14 public class GatewayConfig { 15 16 @Bean 17 public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){ 18 // 路由构造器 19 RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes(); 20 // 设置路径 21 routes.route("baidu_news_guonei_routh", r -> { 22 return r.path("/guonei").uri("http://news.baidu.com/guonei"); 23 }); 24 routes.route("baidu_news_guoji_routh", r -> { 25 return r.path("/guoji").uri("http://news.baidu.com/guoji"); 26 }); 27 28 return routes.build(); 29 } 30 }
本文来自博客园,作者:荣慕平,转载请注明原文链接:https://www.cnblogs.com/rongmuping/articles/16308446.html