微服务之Springcloud 从零基础到入门——Gateway篇
一. 网关简介
在微服务中,网关是不可缺少的组件,其在微服务中的作用是相当大的。第一,它为全部微服务提供唯一入口点,网关起到内部和外部隔离,保障了后台服务的安全性。第二,可以识别每个请求的权限,拒绝不符合要求的请求;第三,动态的将请求路由到不同的后端集群中。第四,减少客户端与服务的耦合,服务可以独立发展。通过网关层来做映射。
二. 背景简介
在gateway出现之前,一直流行使用的网关是Zuul,但相对来说性能并不是很高。Zuul构建于 Servlet 2.5,兼容 3.x,使用的是阻塞式的 API,不支持长连接,比如 websockets。Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成,开发体验相对来说十分不错。Netflix本来要出zuul2来替代zuul,但是因为时间周期过于长,所以spring cloud便出了gateway,并且gateway的效率要比zuul高。
三. Gateway简介
- 路由
这是网关的基本构建模块,作用就是url的映射。其包括路由id,一个目标url,一组断言,一组过滤器。一个网关中可以包含多个路由,其配置方式可以是在yml中,也可以是在代码中。 - 断言
路由转发的判断条件,目前SpringCloud Gateway支持多种方式,可以理解为满足这种方式才会被转发,一个路由可以包含多个断言
断言种类 | 作用 |
Before | 在某时间前 |
After | 在某时间后 |
Between | 在某段时间内 |
Cookie | 表示访问时必须带某个cookie,格式为kv键值对 |
Header | 必须携带某请求头,格式为kv |
Host | 必须携带主机名列表,格式为kv |
Method | 设置请求的方式为post或者get等 |
Path | 设置请求路径 |
Query | 必须携带参数和相应的值 |
- 过滤器
此处的过滤器和web过滤器的作用相似,都是对请求和响应进行修改处理。包括全局过滤器(Gateway自带10个)、单一过滤器(Gateway自带31个)。也可以自己定义过滤器。
四. 配置路由的两种方式
- 配置文件。
该处可以配置多个route。以下表示访问地址1时会路由到地址2。
地址1:http://localhost:9527/payment/findById/2
地址2:http://localhost:8501/payment/findById/2
spring:
cloud:
gateway:
routes:
- id: payment_route1
uri: http://localhost:8501
predicates:
- Path=/payment/findById/**
- 编写配置类
该处也可以配置多个route。该处表示访问地址1会路由到地址2。
地址1:http://localhost:9527/guonei
地址2:http://news.baidu.com/guonei
@Configuration
public class GateWayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/guonei")
.uri("http://news.baidu.com/guonei"))
.route("path_route2", r -> r.path("/guoji")
.uri("http://news.baidu.com/guoji")).build();
}
}
五. 动态路由
- 开启动态路由
spring.cloud.gateway.locator.enabled=true开启动态路由 - 配置路由条件
通过配置uri来实现动态路由和负载均衡,其中CLOUD-PAYMENT-SERVICE是两个注册到Eureka集群的服务提供者,实现负载均衡的写法为lb://服务名,所以表示请求地址1时路由到地址2
地址1:http://localhost:9527/payment/lb/
地址2:http://CLOUD-PAYMENT-SERVICE/payment/lb/
spring:
cloud:
gateway:
discovery:
locator:
enabled: true #开启动态路由
routes:
- id: payment_route2
uri: lb://CLOUD-PAYMENT-SERVICE
predicates:
- Path=/payment/lb/**
六. 配置过滤器
Gateway自带的全局过滤器和单一过滤器的使用可以在官网找到,本文只讲如何自己编写过滤器。该过滤器的作用是访问地址必须要包含参数uname,否则会到错误页面并返回响应的状态码。
@Component
@Slf4j
public class MyFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("开始过滤");
String uname=exchange.getRequest().getQueryParams().getFirst("uname");
if (uname==null){
log.info("非法");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override //用来配置启动的顺序,越小顺序越早
public int getOrder() {
return 0;
}
}
七. 环境搭建
首先会使用之前的环境,详细信息可以参考
- 服务注册中心。本例使用的是之前搭建的eureka集群,端口分别为7001和7002。
- 服务提供者。本例使用的端口为8501
其次,新建springboot项目,搭建Gateway环境
- 添加依赖(主要部分)
该处注意不能引入springboot的web依赖,否则会产生错误
<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>
- 修改application.yml文件
此处的配置主要用于配置Gateway的路由和断言,过滤器也可以在该处配置,但一般写在代码中。其次,网关也需要注册到服务注册中心eureka集群中
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启动态路由
routes:
- id: payment_route1
uri: http://localhost:8501
predicates:
- Path=/payment/findById/**
- id: payment_route2
uri: lb://CLOUD-PAYMENT-SERVICE
predicates:
- Path=/payment/lb/**
eureka:
client:
# 是否入驻进服务端
register-with-eureka: true
# 是否从server端抓取已有注册信息
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
- 主启动类
@SpringBootApplication
@EnableEurekaClient
public class GateWay9527Application {
public static void main(String[] args) {
SpringApplication.run(GateWay9527Application.class,args);
}
}
八. 下一篇介绍
本文对Gateway简答的做了介绍,详细的信息见官网。下一章主要介绍Spring Cloud Config +Spring Cloud Bus,用于配置管理和动态刷新配置。