Spring Cloud Gateway是Spring Cloud生态系统中的一种轻量级网关解决方案。它是基于Spring Framework 5、Spring Boot 2和Project Reactor等技术构建的,可用于构建高效、可扩展的微服务架构。
Spring Cloud Gateway的主要作用是对来自客户端的请求进行路由和转发,它可以根据请求的URL、请求头、请求参数等信息来判断请求的目标服务,并将请求转发给相应的服务。同时,Spring Cloud Gateway还提供了一些常用的过滤器,如路由、限流、重试、缓存等,这些过滤器可以帮助开发人员实现一些常见的功能,如访问控制、安全认证等。
Gateway和Zuul都是Spring Cloud提供的网关组件,它们之间的主要区别在于以下几个方面:
Route指定了请求应该如何被路由,它包括目标URL、路由规则和一些可选的过滤器。通过配置Route,可以将所有的请求映射到对应的微服务实例。
Predicate定义了一个逻辑条件,用于匹配来自客户端的请求。它可以基于请求的URL、请求头、请求参数等信息进行匹配,只有满足条件的请求才会被路由到对应的微服务。
Filter用于在路由请求之前或之后执行一些额外的逻辑,比如鉴权、流量控制、日志监控等。Gateway提供了很多内置的过滤器,还支持开发人员自定义过滤器。
Spring Cloud Gateway的工作流程可以简单地概括为:接收请求、匹配路由、执行过滤器、转发请求。具体来说,它的工作流程如下:
需要注意的是,Gateway的核心流程是异步非阻塞式的,它采用了基于Reactor的响应式编程模型,可以提供更高的并发性能和吞吐量。同时,Gateway还支持动态路由和限流等功能,可以满足不同场景下的需求。
新建Gateway的module cloud-gateway-gateway9527
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>com.atguigu.springcloudgroupId>
<artifactId>cloud-api-commonsartifactId>
<version>${project.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<scope>runtimescope>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
application.yml
主要关注gateway的配置,定义一个路由规则user_routh,可以通过网关访问user服务的接口:
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: user_routh #user_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://localhost:9001 #匹配后提供服务的路由地址
predicates:
- Path=/user/info/** # 断言,路径相匹配的进行路由
eureka:
instance:
# 配置eureka的状态显示
hostname: localhost
instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
client: #服务提供者provider注册进eureka服务列表内
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka7001.com:7001/eureka
启动类GateWayMain9527
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GateWayMain9527.class, args);
}
}
启动项目测试
直接访问9001端口
通过网关9527 访问,也可以跳转到9001上
举个栗子,新建一个配置类,配置路由到百度新闻。。。
@Configuration
public class GateWayConfig {
/**
* 配置了一个id为route-name的路由规则,
* 当访问地址 http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei
*
* @param builder
* @return
*/
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_atguigu",
r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei")).build();
return routes.build();
}
@Bean
public RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {
RouteLocatorBuilder.Builder routes = builder.routes();
routes.route("path_route_atguigu2",
r -> r.path("/guoji")
.uri("http://news.baidu.com/guoji")).build();
return routes.build();
}
}
之前我们的路由uri是写死的地址
下面我们改为服务名,当服务端有多个服务时可以负载均衡调用
需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能
更新后:
uri: lb://lf-user
测试:
9001和9011的两个端口服务轮询调用
在Spring Cloud Gateway中,Predicate是指用于匹配请求的逻辑条件,它是一个函数式接口,用于根据请求的URL、请求头、请求参数等信息判断是否要对当前请求进行处理。Predicate可以通过Gateway的路由规则配置,根据不同的请求条件匹配不同的Route。
在Spring Cloud Gateway中,Predicate可以根据请求的路径、请求参数、请求头、请求方法等信息进行匹配,它可以实现各种复杂的请求匹配逻辑,比如模糊匹配、正则表达式匹配、多个条件的组合匹配等。
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Query=userId,*
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Method=GET
这些Route Predicate可以组合使用,以实现更加复杂的请求匹配逻辑。同时,Spring Cloud Gateway还支持自定义Route Predicate,开发人员可以根据实际需求自行实现Predicate接口,以实现更加灵活和可定制的网关服务。
在Spring Cloud Gateway中,Filter是指用于在请求被路由到目标服务之前或之后对请求和响应进行修改或者处理的组件。它可以对请求进行修改、转换、增强或者根据需要拦截请求或者响应。
Filter是Spring Cloud Gateway的核心组件之一,它可以实现很多网关功能,比如路由转发、请求/响应日志记录、请求鉴权、请求限流、请求重试等。Filter是实现网关自定义功能的关键,可以根据实际需求自定义Filter,满足业务上的特定需求。
Filter接口定义了两个主要的方法:filter()和order()。其中,filter()方法是过滤器的具体实现逻辑,用于对请求进行处理;order()方法则是过滤器的执行顺序,值越小越先执行。
Spring Cloud Gateway内置了很多Filter,例如,RequestRateLimiterGatewayFilterFactory、RetryGatewayFilterFactory、AddRequestHeaderGatewayFilterFactory、HystrixGatewayFilterFactory等等。此外,开发人员也可以根据实际需求自定义Filter,通过实现GatewayFilter或GlobalFilter接口来实现。
自定义全局MyLogGateWayFilter
主要实现两个接口implements GlobalFilter, Ordered
具体代码:
@Component
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("time:" + new Date() + "\t 执行了自定义的全局过滤器: " + "MyLogGateWayFilter" + "hello");
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if (uname == null) {
System.out.println("****用户名为null,无法登录");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 这个返回的数值越小,上面的filter优先级就越高
*
* @return
*/
@Override
public int getOrder() {
return 0;
}
}