发布时间:2024-01-19 09:00
gateway
与 zuul
gateway
是 springcloud
微服务平台的一个子项目,属于 spring
开源社区,依赖名叫:spring-cloud-starter-gateway
。官网:https://spring.io/projects/spring-cloud-gatewayzuul
是 netflix
公司的开源项目,springcloud
在 netflix
项目中也已经集成了 zuul
,依赖名叫:spring-cloud-starter-netflix-zuul
。官网:https://github.com/Netflix/zuulspringcloud gateway
基于 spring 5、projec treactor、springboot 2
,使用非阻塞式的 API
,内置限流过滤器,支持长连接(比如 websockets
),在高并发和后端服务响应慢的场景下比 zuul 1
的表现要好zuul
基于 servlet2.x
构建,使用阻塞的 API
,没有内置限流过滤器,不支持长连接springcloud gateway
简介springcloud gateway
是 springcloud
的一个全新项目,该项目是基于 spring 5.0,springboot 2.0
和 Project Reactor
等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API
路由管理方式springcloud gateway
作为 springcloud
生态系统中的网关,目标是替代 netflix zuul
,其不仅提供统一的路由方式,并且基于 Filter
链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流Route
(路由):这是网关的基本构建块。它由一个 ID
,一个目标 URI
,一组断言和一组过滤器定义。如果断言为真,则路由匹配Predicate
(断言):这是一个 Java 8
的 Predicate
。输入类型是一个 ServerWebExchange
。我们可以使用它来匹配来自 Http
请求的任何内容,例如 headers
或参数Filter
(过滤器):这是 org.springframework.cloud.gateway.filter.GatewayFilter
的实例,我们可以使用它修改请求和响应
客户端向 SpringCloud Gateway
发出请求。如果 Gateway Handler Mapping
中找到与请求相匹配的路由,将其发送到 Gateway Web Handler
。Handler
再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre
)或之后(post
)执行业务逻辑
Spring 5,Project Reactor
和 SpringBoot 2.0
Predicates
和 Filters
作用于特定路由Hystrix
SpringCloud
注册中心Predicates
和 Filters
继续依赖 上一篇 文章的项目结构,再新建服务网关项目如下
Maven
依赖eureka-client-gateway
服务网关添加依赖如下
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
application.properties
配置文件eureka-client-gateway
服务网关的配置文件
server.port=9000
spring.application.name=eureka-client-gateway
#我们自定义的路由ID,保持唯一
spring.cloud.gateway.routes[0].id=eureka-client-gateway
#目标,要路由的服务地址
spring.cloud.gateway.routes[0].uri=http://localhost:8080
#路由条件
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**
id
:我们自定义的路由 ID
,保持唯一uri
:目标,要路由的服务地址。在这里路由的是 eureka-client-producer
提供方地址predicates
:路由条件,Predicate
接受一个输入参数,返回一个布尔值结果filters
:过滤规则,本示例暂时没用/user/**
:以 user
开头的接口 url
,后面 *
是通配符上面这段配置的意思是:配置了一个 id
为 eureka-client-gateway
的路由规则,当访问地址 http://localhost:9000/user/**
时会自动转发路由到地址 http://localhost:8080/user/**
eureka-client-gateway
服务网关的启动类
@Slf4j
@SpringBootApplication
public class AppGateway {
public static void main(String[] args) {
SpringApplication.run(AppGateway.class, args);
log.info(\"------AppGateway Running------\");
}
}
eureka-client-producer
的 controller
它的端口是 8080
@Slf4j
@Controller
@RequestMapping(path = \"/user\")
public class UserController {
@Autowired
private UserService userService;
@GetMapping(path = \"/selectUserById\")
@ResponseBody
public ResultVo selectUserById(Integer id) {
return userService.selectOne(id);
}
}
分别启动项目 eureka-client-gateway
,eureka-client-producer
(不需要启动 eureka
服务端以及 config
服务端),访问接口 http://localhost:9000/user/selectUserById?id=1
,如下
说明 gateway
服务网关已经路由成功。在看看接口 http://localhost:8080/user/selectUserById?id=1
,也就是被路由转发的原服务地址的返回结果如下
gateway
网关路由的配置方式properties
或 yml
中配置(如上)@Bean
自定义 RouteLocator
,在启动主类 Application
中配置(如下)@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(\"path_route\", r -> r.path(\"/about\")
.uri(\"http://ityouknow.com\"))
.build();
}
}
id
为 path_route
的路由,当访问地址 http://localhost:8080/about
时会自动转发到地址:http://www.ityouknow.com/about
,只是这里转发的是以项目地址 /about
格式的请求地址gateway
网关的动态路由(通过注册中心获取路由服务实例)uri
是固定的;而往往在微服务环境中,一个服务可能是要有多个实例的,这时就要有一种动态的路由机制,实现一种类似于 ribbon
的负载均衡机制,让其路由到某个服务的不同实例上gateway
会根据注册中心注册的服务列表,以注册中心上服务名为路由创建动态路由进行转发,从而实现动态路由的功能Maven
依赖eureka-client-gateway
服务网关添加依赖如下
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
application.properties
配置文件eureka-client-gateway
服务网关的配置文件修改如下
server.port=9000
spring.application.name=eureka-client-gateway
eureka.client.service-url.defaultZone=http://eureka7001:8761/eureka/
eureka.instance.prefer-ip-address=true
#我们自定义的路由ID,保持唯一
spring.cloud.gateway.routes[0].id=eureka-client-producer-1
#目标,要路由的服务地址
spring.cloud.gateway.routes[0].uri=lb://eureka-client-producer
#路由条件
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**
#网关服务注册进eureka,开启根据serviceId创建路由的功能
spring.cloud.gateway.discovery.locator.enabled=true
id
:我们自定义的路由 ID
,保持唯一uri
:目标,要路由的服务地址。lb
是 LoadBalancer
负载均衡的意思,eureka-client-producer
是注册在服务中心的服务名predicates
:路由条件,Predicate
接受一个输入参数,返回一个布尔值结果/user/**
:以 user
开头的接口 url
,后面 *
是通配符eureka-client-gateway
服务网关的启动类
@Slf4j
@EnableEurekaClient
@SpringBootApplication
public class AppGateway {
public static void main(String[] args) {
SpringApplication.run(AppGateway.class, args);
log.info(\"------AppGateway Running------\");
}
}
eureka-client-one
,eureka-client-producer
,eureka-client-gateway
服务eureka-client-producer
启动两个实例,端口分别为 8080
与 8081
,用于测试 gateway
网关postman
向接口 http://localhost:9000/user/selectUserById?id=1
发送 5
次请求,查看控制台日志如下端口 8080
日志
gateway
网关成功路由到了服务 eureka-client-producer
的不同实例上了,并且默认使用了轮询的负载均衡策略gateway
网关的过滤器,熔断,限流可以参考文章:http://www.ityouknow.com/springcloud/2019/01/26/spring-cloud-gateway-limit.html