Gateway
1、多个服务
如果开发中有多个服务,怎么让前端或移动端调⽤⼀套接⼝?
2、Gateway是什么
Gateway就是微服务项⽬提供⼀种简单有效的统⼀的 API 路由管理⽅式并且可以对请求进⾏过滤处理。
优点
性能强劲,是Zuul的1.6倍 功能强⼤,内置了很多实⽤的功能,例如转发、监控、限流等设计优雅,容
易扩展
缺点
依赖Netty与WebFlux,不是传统的Servlet编程模型,有⼀定的学习成本不能在Servlet容器下⼯作,也
不能构建成WAR包,即不能将其部署在Tomcat、Jetty等Servlet容器⾥,只能打成jar包执⾏ 不⽀持Spring Boot 1.x, 需2.0及更⾼的版本
3、Gateway解决什么问题
4、Gateway实现服务匹配
Getway核⼼的作⽤:
1.服务路由匹配
2.pom.xml
xml
<dependencies>
<!-- 注册-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2021.1</version>
</dependency>
<!-- -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- 公告 -->
<dependency>
<groupId>com.kou</groupId>
<artifactId>SpringCommon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies>
3.application.yml
yaml
server:
port: 8888
spring:
application:
name: gateway #先注册 注册名字 不然gateway会找不到
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #nocas
#配置gateway 网关
gateway:
routes:
- id: user #唯一
uri: lb://userapi #对应要匹配的服务名称,lb的意思,就是从注册中心获取,后面才可以跟服务的名称
predicates:
- Path=/user/** #外界的访问路径
filters:
- StripPrefix=1 #过滤器,去除访问的1个路径
- id: oss #唯一
uri: lb://ossapi #lb的意思,就是从注册中心获取,后面才可以跟服务的名称
predicates:
- Path=/oss/**
filters:
- StripPrefix=1
5、Gateway实现请求过滤
Gateway提供了对请求过滤处理的接⼝,⼀个叫全局过滤器,所有请求都会触发,另⼀个局部过滤器,只有某个服务才会触发
1.全局过滤器(GlobalFilter)
凡是请求,都会触发的过滤器,⼀般写的都是全局过滤器
2.局部过滤器(GatewayFilter)
和服务绑定,只有请求某⼀个服务的时候,才会触发,⼀般不推荐使⽤,建议有这种在对应的服务上
直接写过滤器
全局过滤器实现步骤:
1.filter
java
package com.kou.gatewat.filter;
import com.alibaba.fastjson.JSON;
import com.kou.common.vo.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Objects;
/**
* @author kz
* @date 2022/10/8
*/
@Component//gateWay全局过滤
public class VersionFilter implements GlobalFilter {
private Logger logger=LoggerFactory.getLogger(VersionFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//实现对接口请求.do结尾 需要携带请求消息头。版本号 version,如果没有拦截
//1.获取请求对象和响应对象
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
//2.获取请求路径
String url = request.getPath().value();
logger.error("请求路径:"+url);
//3.验证码是否为.do类型的请求
if (url.contains(".do")){
//4.获取请求的消息头
List<String> list = request.getHeaders().get("version");
if (Objects.nonNull(list) && list.size()>0){
String version=list.get(0);
logger.error("版本号:"+version);
//5.验证版本号是否为空,空拦截
if (Objects.nonNull(version) && version.length()>0){
//有效 放行
return chain.filter(exchange);
}
}
//拦截
R r = R.fail("请传递接口版本号");
//设置请求消息头
response.getHeaders().add("Content-Type","application/json;charset=UTF-8");
//拦截并返回自定义内容
return response.writeWith(
Mono.just(response.bufferFactory().
wrap(JSON.toJSONString(r).getBytes())));
}
return chain.filter(exchange);
}
}
6、Gateway总结
Gateway⽹关,主要解决多个服务,可以把多个服务聚合到⼀起,外界只需要访问⽹关就可以了。
外界访问-⽹关-⽹关根据访问路径匹配对应的服务-执⾏对应。
Gateway的核⼼作⽤:
1.聚合服务,对外统⼀提供接⼝
2.请求全局过滤
实际开发中,多个服务,需要配置⽹关中⼼
也会写⼀些全局过滤器,⽐如:令牌续命,接⼝版本号兼容,请求接⼝频率限制,访问⿊⽩名单、反爬
⾍限制接⼝、ip限定等等