SpringCloud之Gateway统一网关 Gateway网关可以帮助处理一些校验的问题。并不是所有的请求都可以请求到资源路径,以及做一些身份验证等等。
看黑马的课程ppt都非常形象,摘录出来。我们的客户端访问访问我们的微服务的资源的时候需要通过这个网关。当然你要关闭其它的访问路径,让访问必须要经过这个网关。
网关对访问进行校验,校验通过后就可以访问到我们的微服务。当然网关内部是可以做很多的处理。我们下面说。微服务之间进行http客户端Feign提供的接口实现服务之间的相关访问调用。
这些都是·大概的浅显的介绍,我们大概了解到Gateway网关类似于门锁。
Gateway是SpringCloud提供的一种网关api,当然还有其它类型的api,zuul,Gateway这个性能还是比较好一些。
废话不多说,我们直接尝试去使用。
我们创建一个专门作为网关的模块。
代码语言:javascript复制<!-- 引入nacos的服务发现依赖-->
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 网关gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
然后我们还需要去配置一下相关的属性信息。
代码语言:javascript复制server:
port: 10010
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848 # nacos 地址
gateway:
routes:
- id: user-service # 路由唯一标识
uri: lb://userservice #路由的目标地址,lb是负载均衡 userservice是服务名
predicates: #路由断言,判断请求是否符合规则
- Path=/user/** #路径断言,判断路径是否以/user开头,如果符合就会分配到相应的路由
- id: order-service
uri: lb://orderservice
predicates:
- Path=/order/**
# - After=2023-01-20T17:42:47.789-07:00[Asia/Shanghai] #网关的时间的我路由规则
当然配置不止这些,我们举例出这个来说明一些属性。
一定要仔细分析图啊!客户端发来的请求,然后到达网关的路由,路由中会有一个路由断言。
断言我们可以认为它是一种判断规则,根据断言来分配到相应规则的路由目标地址。这里面的路由规则绝不是只有路径的匹配,还有相关的过滤规则等等。 分配搭配相应的目标地址后我们会调用相关的微服务,这里微服务会有一个负载均衡的过程,因为一个服务可能会纯在多个实例,这里会进行负载均衡。我们请求到对应的微服务实例后就可以访问或者说请求到数据。
这样的理解我认为是最简单的理解方式。
需要了解的就是这样的配置官方文档会给出详细的说明。
完全可以查阅去使用。 不要忘记去写一个启动类。因为网关本身也需要是一个服务。
看一些配置,断言工厂
这个断言工厂的断言工厂是比较容易理解的,包括对请求头,请求方式,cookies,等等的要求。 还有就是路由过滤器,这些可以去spring的路由过滤器工厂去找。它是对请求或者响应做出处理。
上面这个是路由过滤器,要想全局可以这样配,可以对所有路由生效。功能是全局,但是并不叫全局过滤器。
下面这个才叫全局过滤器
不过这个全局过滤器并不是通过配置文件,需要我们写一段代码。一定是需要去官方网站的文档中进行查看的。
官方文档给出了这个说明,总之我们需要实现一个接口,我们按照这个实现我们的逻辑就可以了。
代码语言:javascript复制package com.jgdabc.gateway;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Order(-1)//这个值指定的大小说明了该过滤器的优先级,值小优先级高
public class AuthorizeFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
String authorization = params.getFirst("Authorization");
if ("admin".equals(authorization))
{
return chain.filter(exchange);
}
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
return exchange.getResponse().setComplete();
// 获取参数中的authorization
// 判断然后给出处理逻辑
}
}
现在我们测试,注意我们从网关走
我们不加Authorization是通不过网关的。
加上Authorization并匹配正确值
这样我们就验证了。后面的逻辑其实都是基于这个开展的。
我们这边认识到了三个过滤器,来看执行顺序。
全局过滤器我们可以在注解中指定order的值,值小,优先级别高。
网关这边的知识还存在一个跨域的问题。主要是浏览器的同源策略。是一种安全措施。具体来看一点,我觉得文章写的挺不错的。 一文带你了解跨域原理与解决办法 我们后端服务处理这个问题的思路就是CORS方案。CORS是什么,上面链接文章有说明,就不赘述了。
由于同源策略的限制,AJAX请求是不允许进行跨域请求的,这是比较典型的。
spring官方文章有对此的的处理模板
你还可以设置其他的参数比如
这些都是浅显的介绍,就说这么多吧。