4.Gateway

什么是Gateway

SpringCloud Gateway 是 Spring Cloud的一个全新项目,基于Spring5.0+SpringBoot2.0和ProjectReactor等技术开发的网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。
SpringCloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Zuul。为了提升网关性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架的底层是使用了高性能的Reactor模式通信框架Netty。
SpringCloud Gateway的目标提供统一的路由方式且基于Filter链的方式提供了网关的基本功能,例如:安全,监控和限流。

既然已经有Zuul为什么要选择Gateway

1.因为Zuul1.0已经进入维护阶段,虽然Netflix发布了Zuul2.x但是SpringCloud貌似没有整合计划。而Gateway是SpringCloud团队研发的,基于异步非阻塞模型,性能方面不需要担心
2.Zuul1.x是基于Servlet2.5使用阻塞式框架,它不支持任何长连接(如WebSocket)Zuul的设计模式和Nginx比较像,每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,而Zuul是用Java实现,而JVM本身会有第一次加载较慢的情况,使得Zuul的性能相对较差。
SpringCloud Gateway建立在SpringFramework5、ProjectReactor和SpringBoot2之上,并且使用非阻塞API而且还支持WebSocket,与Spring紧密集成拥有更好的开发体验。

Zuul模型和GateWay模型

SpringCloud 集成的Zuul是基于传统的Servlet IO处理模型。当请求到达时Servlet容器会分配一个线程去调用service,而这种模型是阻塞的。Zuul1.x是基于Servlet之上的一个阻塞式处理模型,既spring实现了处理所有request请求的一个servlet (DispatcherServlet)并由该servlet阻塞式处理请求。所以SpringCloud Zuul无法摆脱Servlet模型的弊端。
在这里插入图片描述
传统的Web框架,比如struts2,springMvc等都是基于ServletAPI与Servlet容器基础之上运行的。但是在Servlet3.1之后有了异步非阻塞的支持。而WebFlux是一个典型的异步非阻塞的框架,它的核心是基于Reactor的相关API实现的。相对于传统的Web框架,它可以运行在比如Netty,Undertow及支持Servlet3.1的容器上。是SpringFramework5引入的新的响应式框架,区别与Spring MVC,它不需要依赖ServletApi完全是异步非阻塞的,并且基于Reactor来实现响应式流规范。而SpringCloud Gateway是基于WebFlux实现的,是异步非阻塞的

Gateway

Gateway由以下三大模块组成:
路由(Route):是构建网关的基本模块,由ID、目标URI、一系列的断言和过滤器组成,如果断言是true则匹配该路由
断言(Predicate):和HTTP请求中的所有内容(如请求头或请求参数)进行匹配,如果请求与断言相匹配则进行路由
过滤器(Filter):Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者后对请求进行修改

客户端向Gateway发起请求。然后在Gateway Handler Mapping中找到与请求对应的路由,将其发送到Gateway Web Handler。Handler再通过滤链条发送到实际的服务执行业务逻辑,之后返回。Gateway的核心逻辑就是路由转发和执行过滤链
在这里插入图片描述

路由

1.添加对应依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

2.配置路由(除了以下配置路由方式,还可以通过数据库、缓存等配置路由)

2.1. 通过yml文件配置路由

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh #路由的id,没有固定规则但是要求唯一
          uri: http://localhost:8001 #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/** #断言,路径相匹配的进行路由

2.2. 通过代码配置

@Configuration
public class GatewayConfig {

    /**
     * 通过访问http://localhost:9527/guonei 转发到 https://news.baidu.com/guonei
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator config(RouteLocatorBuilder builder){
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("gateway_1",
                r->r.path("/guonei")
                        .uri("https://news.baidu.com/guonei")).build();
        return routes.build();
    }
}

在这里插入图片描述
2.3也可以通过注册中心的服务名进行配置 并且可以进行负载均衡。默认情况下Gateway会根据注册中心的服务列表,以注册中心的服务名为路径创建动态路由进行转发,从而实现动态路由功能
注意:uri的协议为lb,表示启用gateway的负载均衡

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启从注册中心创建路由的功能 利用微服务名进行路由
      routes:
        - id: payment_routh #路由的id,没有固定规则但是要求唯一
          #uri: http://localhost:8001 #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service
          predicates:
            - Path=/payment/get/** #断言,路径相匹配的进行路由

断言

在上述的配置中的path 还有以下配置,具体的可以看官网
Gateway官网地址
在这里插入图片描述

过滤器

官网给出了过滤器,分单一和全局两种,可以根据配置添加。但是实际使用中基本都使用自己写的过滤器

自定义全局过滤器

通过实现 GlobalFilter和Ordered

@Component
@Log4j
public class MyLogGetwayFilter implements GlobalFilter, Ordered {
    /**
     * 过滤逻辑
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("******MyLogGetwayFilter: "+new Date());
        //获取请求
        String name = exchange.getRequest().getQueryParams().getFirst("username");
        if (StringUtils.isEmpty(name)){
            log.info("******MyLogGetwayFilter: 用户名为空");
            exchange.getResponse().setStatusCode(HttpStatus.ACCEPTED);
            return exchange.getResponse().setComplete();
        }

        // 继续下一个过滤器
        return chain.filter(exchange);
    }

    /**
     * 优先级
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Spring Cloud Gateway的跨域问题,你可以通过以下步骤解决: 1. 在你的Spring Cloud Gateway项目中,创建一个全局的跨域配置类,比如命名为CorsConfig。 2. 在CorsConfig类上添加注解`@Configuration`,使其成为一个配置类。 3. 在CorsConfig类中添加一个方法来配置跨域规则,比如命名为addCorsMappings。 4. 在addCorsMappings方法上添加注解`@Bean`,使其成为一个Bean。 5. 在addCorsMappings方法中使用CorsRegistry对象来配置跨域规则。例如: ```java @Configuration public class CorsConfig { @Bean public WebFluxConfigurer corsConfigurer() { return new WebFluxConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*") .exposedHeaders("Authorization") .allowCredentials(true) .maxAge(3600); } }; } } ``` 在上述示例中,通过调用CorsRegistry对象的addMapping方法来添加跨域规则。其中,allowedOrigins设置允许的源(域)地址,allowedMethods设置允许的HTTP方法,allowedHeaders设置允许的请求头,exposedHeaders设置允许暴露的响应头,allowCredentials设置是否允许发送cookie信息,maxAge设置预检请求的缓存时间。 这样配置后,Spring Cloud Gateway就会支持跨域请求了。注意,如果你使用的是WebFlux框架,需要返回WebFluxConfigurer对象并重写addCorsMappings方法;如果使用的是WebMvc框架,则需要返回WebMvcConfigurer对象并重写addCorsMappings方法。 希望以上信息对你有所帮助!如有更多问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值