天天看点

Gateway-源码分析

工作原理

Gateway-源码分析

客户端向 Spring Cloud Gateway 发出请求。 如果网关处理程序映射确定请求与路由匹配,则将其发送到网关 Web 处理程序。 此处理程序通过特定于请求的过滤器链运行请求。 过滤器用虚线划分的原因是过滤器可以在发送代理请求之前和之后运行逻辑。 执行所有“预”过滤器逻辑。 然后发出代理请求。 发出代理请求后,将运行“发布”过滤器逻辑。

配置类分析

jar包中加载的配置类,会注入到IOC容器中。

Gateway-源码分析

1、GatewayClassPathWarningAutoConfiguration 检查是否有正确的配置webflux

检查是否有

org.springframework.web.servlet.DispatcherServlet

类,也就是是否引入了springweb的依赖。

Gateway-源码分析

2、GatewayAutoConfiguration 核心配置类

配置了很多bean,加载了gateway 需要注入的类。

Gateway-源码分析

配置了很多谓词想的的bean

Gateway-源码分析

3、GatewayLoadBalancerClientAutoConfiguration 网关需要使用的负载均衡

Gateway-源码分析

该过滤器实现了负载均衡的功能,通过责任链的设计模式。

Gateway-源码分析

4、GatewayRedisAutoConfiguration 网关整合Redis整合Lua实现限流

Gateway-源码分析

5、GatewayDiscoveryClientAutoConfiguration 把网关服务注册到注册中心中去,服务注册与发现功能

路由模式源码分析

网关的请求入口在 DispatcherHandler类里面的 handler 方法。

Gateway-源码分析

查找handler方法中,子类会查找路由策略,循环查找路由策略,第一个匹配的策略会返回了。

Gateway-源码分析

执行的handler

Gateway-源码分析

webHandler去执行

Gateway-源码分析

执行的是 filter 的 handler,gateway 默认有7个filter,分别实现了不同的功能:负载均衡、请求转发等功能。各个filter通过责任链模式循环执行。

Gateway-源码分析

解决前后端的跨域问题

微服务中跨域的问题,不属于前端解决 jsonp ,只能支持get请求。

核心点就是在我们后端。

解决跨域的问题

  1. HttpClient转发
  2. 使用过滤器允许接口可以跨域 响应头设置
  3. Jsonp 不支持我们的post 属于前端解决
  4. Nginx解决跨域的问题保持我们域名和端口一致性
  5. Nginx也是通过配置文件解决跨域的问题
  6. 基于微服务网关解决跨域问题,需要保持域名和端口一致性
  7. 使用网关代码允许所有的服务可以跨域的问题
  8. 使用SpringBoot注解形式@CrossOrigin

gateway解决跨域问题:增加过滤器,给请求头增加参数。

@Component
public class CrossOriginFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
        return chain.filter(exchange);

    }
}