技术/杨33
一、Gateway是什么
为微服务提供一种简单有效的统一的API路由管理方式。
Gateway是基于WebFlux框架实现的,而WebFlux框架底层使用了高性能的Reactor模式通讯框架Netty。
二、Gateway的三大核心概念
Route路由、Predicate断言、Filter过滤。
- Route路由
路由是构建网关的基本模块,它由ID、目标URL、一系列的断言和过滤器组成,如果断言为true,则匹配该路由。
- Predicate断言
开发人员可以匹配HTTP请求中的所有内容,例如:请求头或请求参数,如果请求与断言相匹配,则进行路由。
- Filter过滤
指的是Spring中的GatewayFilter的实例,使用过滤器,可以在请求被路由前或之后对请求进行修改。
三、网关Gateway的工作流程
客户端向Spring Cloud Gateway发出请求,然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway Web Handler。Handler再通过指定的过滤器链,将请求发送到我们实际的服务执行业务逻辑,然后返回。
四、Java代码编码体验
1、pom.xml文件依赖包配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
2、application.yml配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: paymentRoute1 #路由的id,没有固定的规则,但要求唯一
uri: http://localhost:8001 #匹配后提供服务的路由地址
predicates:
- Path=/payment/getPayment/** #断言,路径相匹配的进行路由
eureka:
client:
register-with-eureka: true #true表示向注册中心注册自己
fetch-registry: true #是否从EurekaServer抓取已有的注册信息
service-url:
#defaultZone: http://localhost:7001/eureka/ #单机服务注册中心的地址
defaultZone: http://eureka7001.com:7001/eureka/ #集群服务
3、添加主启动类
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class, args);
}
}
4、分别启动服务注册中心服务cloud-eureka-server7001、服务提供者服务cloud-provider-payment8001、网关服务cloud-gateway-gateway9527
访问接口:

5、网关gateway通过注册中心的微服务名称,动态路由服务提供者的接口
修改application.yml配置文件
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: paymentRoute1 #路由的id,没有固定的规则,但要求唯一
uri: lb://cloud-provider-payment #微服务名称
predicates:
- Path=/payment/getPayment/** #断言,路径相匹配的进行路由
eureka:
client:
register-with-eureka: true #true表示向注册中心注册自己
fetch-registry: true #是否从EurekaServer抓取已有的注册信息
service-url:
#defaultZone: http://localhost:7001/eureka/ #单机服务注册中心的地址
defaultZone: http://eureka7001.com:7001/eureka/ #集群服务
五、gateway的核心之一:Predicate断言,常用类型
官网上可以看到所有的类型:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#gateway-request-predicates-factories

- After=2017-01-20T17:42:47.789-07:00[America/Denver]
这样的时间串生成方式:
ZonedDateTime zonedDateTime = ZonedDateTime.now();
System.out.println(zonedDateTime);
六、gateway的核心之一:Filter过滤
- gatewayfilter-factories
官网上可以看到所有的类型:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#gatewayfilter-factories
包含30种类型:

- global-filters
官网上可以看到所有的类型:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#global-filters

七、自定义过滤器Filter,实际工作用这个比较多
新建Java类,需实现接口GlobalFilter, Ordered
package com.cloud.filter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @author 杨33
* @date 2020/5/1 20:56
*/
@Component
public class MyGatewayFilter implements GlobalFilter, Ordered {
/**
* 过滤方法
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String serial = exchange.getRequest().getQueryParams().getFirst("serial");
if (serial == null) {
System.out.println("serial名是非法的");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
这样的代码,就可以过滤掉请求参数只要不是serial,那么不能完成正确的请求。
作者:杨33,北京互联网公司在职Java开发,专注分享写作干货。欢迎关注我,期待你的点赞评论。