网关:用户和微服务的桥梁
网关的核心是一组过滤器,按照先后顺序执行过滤操作。
Spring Cloud Gateway是基于webFlux框架实现,而webFlux框架底层则使用了高性能的Reactor模式通信框架的Netty
Spring Cloud Gateway是Spring Cloud生态系统中的一个API网关,它基于Spring Framework 5,Spring Boot 2和Project Reactor等技术栈构建。它提供了一种简单而有效的方式来路由请求,以及对请求进行过滤和转换。
Spring Cloud Gateway的主要特点包括:
轻量级:Spring Cloud Gateway是一个轻量级的API网关,它可以快速启动和部署。
动态路由:Spring Cloud Gateway支持动态路由,可以根据请求的路径和参数将请求路由到不同的服务实例。
过滤器:Spring Cloud Gateway提供了一系列的过滤器,可以对请求进行过滤和转换,例如添加请求头、修改请求路径等。
集成性:Spring Cloud Gateway可以与Spring Cloud Config、Spring Cloud Discovery等组件集成,可以实现动态配置和服务发现。
响应式编程:Spring Cloud Gateway基于Project Reactor实现,可以实现响应式编程,提高系统的吞吐量和性能。
Spring Cloud Gateway中的Filter分为两种类型的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理。
Gateway Filter针对某一个路由filter对某一个接口做限流
Global Filter 针对全局的filter token ip黑名单
Spring Cloud Gateway快速入门
login-service
application.yml
server:port: 8081
spring:application:name: login-serviceeureka:client:service-url: #指定server注册地址defaultZone: http://localhost:8761/eurekaregister-with-eureka: truefetch-registry: trueregistry-fetch-interval-seconds: 5instance:hostname: localhostinstance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} #主机名+应用名+端口号
gateway-service
application.yml
server:port: 8089 #网关
spring:application:name: gateway-servicecloud:inetutils:ignored-interfaces: 'VMware Virtual Ethernet Adapter for VMnet1,VMware Virtual Ethernet Adapter for VMnet8'gateway:enabled: true #默认tureroutes:- id: login_service_routeuri: http://localhost:8081predicates:- Path=/doLogin #匹配规则
eureka:client:service-url: #指定server注册地址defaultZone: http://localhost:8761/eurekaregister-with-eureka: truefetch-registry: trueregistry-fetch-interval-seconds: 5instance:hostname: localhostinstance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} #主机名+应用名+端口号
Gateway路由配置方式
eureka、gateway、configserver auth-server
静态路由
配置文件路由
官方提供代码配置
https://spring.io/projects/spring-cloud-gateway
@Configuration
public class GatewayConfig {@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes().route("login", r -> r.path("/doLogin").uri("http://localhost:8081")).route("bili", r -> r.path("/guochuang").uri("https://www.bilibili.com/")).build();}}
动态路由
需要添加eureka-client依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.yml添加如下内容
discovery:locator:enabled: true #开启动态路由 通过应用名称 找到服务功能lower-case-service-id: true #开启服务名小写
login-service添加eureka-client
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Gateway过滤器
过滤器生命周期分类
Pre在业务逻辑之前
Post在业务逻辑之后
过滤器种类分类
GatewayFilter 需要配置路由,才能过滤。如果需要使用全局路由,需要配置Default Filters
作用:1、记录接口访问次数 2.限流操作
globalFilter 针对全局 针对每个路由
作用:1、黑名单校验 2、全局token校验 3、参数校验
@Component
public class MGlobalFilter implements GlobalFilter, Ordered {
/**
* 过滤方法
*
* @param exchange
* @param chain 放行
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取请求响应,header url 参数
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
HttpHeaders headers = request.getHeaders();
System.out.println("路径:"+path+" 请求头:"+headers);
String name = request.getMethod().name();
System.out.println(name);
request.getRemoteAddress().getAddress();
request.getRemoteAddress().getHostName();
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().set("content-type","application/json;charset=utf-8");
HashMap<String,Object> map =new HashMap<>(4);
map.put("code", HttpStatus.UNAUTHORIZED.value());
map.put("msg", "未授权登入");
ObjectMapper objectMapper =new ObjectMapper();
//把map转成字节
byte[] bytes = new byte[0];
try {
bytes = objectMapper.writeValueAsBytes(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
//通过buffer工资将字节数组包装成一个数据包
DataBuffer wrap = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(wrap));
//放行到下一个过滤器
//return chain.filter(exchange);
}
/**
* 指定顺序的方法
* 越小优先级越大
* @return
*/
@Override
public int getOrder() {
return 0;
}
}