【SpringCloud】Gateway
- 互联网
- 2025-09-17 02:18:02

目录
一、网关路由
1.1.认识网关
1.2.快速入门?
1.2.1.引入依赖
1.2.2.配置路由
二、网关登录校验
2.1.Gateway工作原理
?2.2.自定义过滤器
2.3.登录校验
2.4.微服务获取用户
2.4.1.保存用户信息到请求头
2.4.2.拦截器获取用户?
?2.5.OpenFeign传递用户
三、配置管理
3.1.配置共享
?3.2.拉取配置共享
3.2.1.引入依赖
3.2.2.创建bootstrap.yaml
3.3.配置热更新
3.3.1.添加配置到Nacos
?编辑?3.3.2.配置热更新
3.4.动态路由
四、总结
一、网关路由 1.1.认识网关
网关就是网络的关口。数据在网络间传输,从一个网络传输到另一网络时就需要经过网关来做数据的路由****和转发以及数据安全的校验。前端请求不能直接访问微服务,而是要请求网关:
网关可以做安全控制,也就是登录身份校验,校验通过才放行
通过认证后,网关再根据请求判断应该访问哪个微服务,将请求转发过去
1.2.快速入门 1.2.1.引入依赖 <!--网关--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--nacos discovery--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--负载均衡--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> 1.2.2.配置路由 server: port: 8080 spring: application: name: gateway cloud: nacos: server-addr: 192.168.150.101:8848 gateway: routes: - id: item-service # 路由规则id,自定义,唯一 uri: lb://item-service # 路由的目标服务,lb代表负载均衡,会从注册中心拉取服务列表 predicates: # 路由断言,判断当前请求是否符合当前规则,符合则路由到目标服务 - Path=/items/**,/search/** # 这里是以请求路径作为判断规则 - id: cart-service uri: lb://cart-service predicates: - Path=/carts/**id:建议和微服务名保持一致
uri:路由目标
lb:负载均衡://服务名称
predicates:路由断言
- Path:以路径做匹配
二、网关登录校验 2.1.Gateway工作原理客户端请求进入网关后由HandlerMapping对请求做判断,找到与当前请求匹配的路由规则(Route),然后将请求交给WebHandler去处理。
WebHandler则会加载当前路由下需要执行的过滤器链(Filter chain),然后按照顺序逐一执行过滤器(后面称为Filter)。
图中Filter被虚线分为左右两部分,是因为Filter内部的逻辑分为pre和post两部分,分别会在请求路由到微服务之前和之后被执行。
只有所有Filter的pre逻辑都依次顺序执行通过后,请求才会被路由到微服务。
微服务返回结果后,再倒序执行Filter的post逻辑。
最终把响应结果返回。
2.2.自定义过滤器网关过滤器链中的过滤器有两种:
GatewayFilter:路由过滤器,作用范围比较灵活,可以是任意指定的路由Route.
GlobalFilter:全局过滤器,作用范围是所有路由,不可配置。
2.3.登录校验自定义GlobalFilter完成登录校验
自定义登录校验过滤器
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { //1、获取请求头 ServerHttpRequest request = exchange.getRequest(); //2.判断是否不需要拦截 if (isExclude(request.getPath().toString())) { return chain.filter(exchange); } //3.获取token List<String> headers = request.getHeaders().get("authorization"); String token = null; if (headers != null && !headers.isEmpty()) { token = headers.get(0); } //4.解析校验token Long userId = null; try { userId = jwtTool.parseToken(token); } catch (UnauthorizedException e) { //拦截,设置响应状态码 ServerHttpResponse response = exchange.getResponse(); response.setRawStatusCode(401); return response.setComplete(); } //System.out.println("userId = " + userId); //保存用户到请求头 String userInfo = userId.toString(); ServerWebExchange swe = exchange.mutate().//mutate 对下游请求做更改 request(builder -> builder.header("user-info", userInfo)) .build(); //6.放行 return chain.filter(swe); } 2.4.微服务获取用户 2.4.1.保存用户信息到请求头 //保存用户到请求头 String userInfo = userId.toString(); ServerWebExchange swe = exchange.mutate().//mutate 对下游请求做更改 request(builder -> builder.header("user-info", userInfo)) .build(); 2.4.2.拦截器获取用户 /** * 拦截器,获取用户保存到ThreadLocal */ public class UserInfoInterceptor implements HandlerInterceptor { //在controller执行之前运行 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { //1.获取用户信息 String userInfo = request.getHeader("user-info"); //2.将用户信息保存到ThreadLocal if (StrUtil.isNotBlank(userInfo)) { UserContext.setUser(Long.valueOf(userInfo)); } //3.放行,只获取用户信息,不做拦截 return true; } //清理用户 @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { UserContext.removeUser(); } }配置拦截器
@Configuration @ConditionalOnClass(DispatcherServlet.class) public class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new UserInfoInterceptor()); } }不过,需要注意的是,这个配置类默认是不会生效的,因为它所在的包是com.hmall mon.config,与其它微服务的扫描包不一致,无法被扫描到,因此无法生效。
基于SpringBoot的自动装配原理,我们要将其添加到resources目录下的META-INF/spring.factories文件中:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.hmall mon.config.MyBatisConfig, com.hmall mon.config.MvcConfig
2.5.OpenFeign传递用户利用RequestTemplate类来添加请求头,将用户信息保存到请求头中。这样以来,每次OpenFeign发起请求的时候都会调用该方法,传递用户信息。
@Bean public RequestInterceptor UserInfoRequestInterceptor() { return requestTemplate -> { Long userId = UserContext.getUser(); if (userId != null) { requestTemplate.header("user-info", userId.toString()); } }; } 三、配置管理 3.1.配置共享我们可以把微服务共享的配置抽取到Nacos中统一管理,这样就不需要每个微服务都重复配置了。分为两步:
在Nacos中添加共享配置
微服务拉取配置
3.2.拉取配置共享 3.2.1.引入依赖 <!--nacos配置管理--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--读取bootstrap文件--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> 3.2.2.创建bootstrap.yaml spring: application: name: cart-service # 服务名称 profiles: active: dev cloud: nacos: server-addr: 192.168.150.101 # nacos地址 config: file-extension: yaml # 文件后缀名 shared-configs: # 共享配置 - dataId: shared-jdbc.yaml # 共享mybatis配置 - dataId: shared-log.yaml # 共享日志配置 - dataId: shared-swagger.yaml # 共享日志配置 3.3.配置热更新 3.3.1.添加配置到NacosdataId格式:[服务名]-[spring.active.profile].[后缀名]
文件名称由三部分组成:
服务名:购物车服务,所以是cart-service
spring.active.profile:就是spring boot中的spring.active.profile,可以省略,则所有profile共享该配置
后缀名:例如yaml
3.3.2.配置热更新创建属性读取类
@Data @Component @ConfigurationProperties(prefix = "hm.cart") public class CartProperties { private Integer maxAmount; } 3.4.动态路由 四、总结【SpringCloud】Gateway由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【SpringCloud】Gateway”