一.为什么需要网关
在某些情况下,部分接口需要权限分级。若是在每个微服务模块都配置一套权限框架的话,代价实在太大。所以,我们需要一个中心,来统一处理这样的请求控制。这就需要网关的作用:
网关的作用不仅只是身份认证和权限控制,还有以下作用
- 身份验证和权限管理
- 限流
- 负载均衡
- ................
二.网关的使用
(一).前置处理
网关作为一个模块,也要注册到nacos注册中心里面,所以需要在父工程创建一个模块叫Gateway,测试其启动无误,并且成功注册到nacos中心。
1.启动类
package org.white;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class,args);
}
}
2.applicaiton.yml
server:
port: 6532
spring:
application:
name: Gateway
cloud:
nacos:
server-addr: http://127.0.0.1:8848
3.依赖
<dependencies>
//这里千万别导成web了,会报错的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
</dependencies>
启动成功后即可进入下一步
(二).引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
(三).编写路由配置
server:
port: 6532
spring:
application:
name: Gateway
cloud:
nacos:
server-addr: http://127.0.0.1
gateway:
routes:
- id: ServiceB //路由ID,随便起,不重名即可
uri: lb://ServiceB //地址,lb://表示负载均衡
predicates: //路由断言
- Path=/serviceB/** //断言规则,匹配/serviceB开头的所有URI,由断言工厂处理
- id: ServiceA
uri: lb://ServiceA
predicates:
- Path=/serviceA/**
重启后访问网关的地址就可以进入相应的服务了。
三.断言工厂
上面的路由断言我们仅仅只是使用了字符串便可以让Gateway识别到我们采用的是哪一种匹配规则。其实都是依托于PathRoutePredicateFactory这个类来处理的。
例如允许某个时间点后才可以访问:
gateway:
routes:
- id: ServiceB //路由ID,随便起,不重名即可
uri: lb://ServiceB //地址,lb://表示负载均衡
predicates: //路由断言
- Path=/serviceB/** //断言规则,匹配/serviceB开头的所有URI,由断言工厂处理
- After=2025-05-28+08:00[Asia/Shanghai] //断言规则,2025年5月28日后可以进入
断言工厂还有好十多种种规则:
详情也可以进入Spring官网查看:
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
四.过滤器
过滤器可以让我们在处理发送和接受微服务请求时做出调整:
然而,Spring官方给出的过滤器高达30多种,具体可以前往Spring官网查看:
Gateway过滤器:
这里对AddRequestParameter这个过滤器进行一个测试:
(一).局部过滤器:
1.在gateway的application.yml添加filters节点
gateway:
routes:
- id: ServiceB
uri: lb://ServiceB
predicates:
- Path=/serviceB/**
- id: ServiceA
uri: lb://ServiceA
predicates:
- Path=/serviceA/**
filters:
- AddRequestParameter=pm, 666 //","前面的是参数名,后面是值
2.改造serviceA的Controller
@GetMapping("test")
public String ServiceATest(@RequestParam String pm){
String result = serviceB.serviceB(pm);
return "ServiceA Working and " + result;
}
3.查看结果
想要给所有路由都添加过滤器的话,可以使用default-filter:
gateway:
routes:
- id: ServiceB
uri: lb://ServiceB
predicates:
- Path=/serviceB/**
- id: ServiceA
uri: lb://ServiceA
predicates:
- Path=/serviceA/**
filters:
- AddRequestParameter=pm, 666 //只对ServiceA生效
default-filters: //对所有路由生效
- AddRequestParameter=pm, 666
(二).全局过滤器:
这个全局过滤器,从名字听起来,和上面的default-filters有点功能重复了的意思。其实这个全局过滤器叫它自定义过滤器更合适。上面我们添加的过滤器毕竟是Spring定义好了给我们的,但是如果我们想要实现更复杂的功能的话必须要手动定义过滤器。
public interface GlobalFilter {
Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}
exchange代表上文,chain可以放行
比如,我们想获取请求参数Auth的值是否为admin,如果是则放行:
@Component
@Order(-1)
public class AuthFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> queryParams = request.getQueryParams();
String auth = queryParams.getFirst("auth");
if ("auth".equals(auth)) {
return chain.filter(exchange);
}
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
exchange.getResponse().setComplete();
return chain.filter(exchange);
}
}
(三).过滤器顺序
- 当存在orde值的时候,order越小越先执行
- 当order值一样的时候,执行顺序是:DefaultFilter>局部过滤器>GlobalFilter
五.跨域配置
Gateway也自带了跨域配置,我们在网关配置跨域配置后,在微服务上就不用单独配置跨域了:
gateway:
routes:
- id: ServiceB
uri: lb://ServiceB
predicates:
- Path=/serviceB/**
- id: ServiceA
uri: lb://ServiceA
predicates:
- Path=/serviceA/**
filters:
- AddRequestParameter=pm, 666
globalcors:
add-to-simple-url-handler-mapping: true //允许Options
cors-configurations: //跨域配置
'[/**]':
allowedOrigins:
- "http://127.0.0.1:8080" //允许跨域的地址
allowedMethods: //允许跨域的请求
- GET
- POST
- DELETE
- PUT
- OPTIONS
allowCredentials: true //允许携带Cookie
maxAge: 36000 //允许跨域的有效期
以上就是gateway的全部内容