主页 > 互联网  > 

【SpringCloud】Gateway

【SpringCloud】Gateway

目录

一、网关路由

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.添加配置到Nacos

dataId格式:[服务名]-[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