SpringCloud Gateway简单使用

Posted 踩踩踩从踩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud Gateway简单使用相关的知识,希望对你有一定的参考价值。

前言

SpringCloud Gateway是一个网关框架,也是现在流行的的一个网关框架,它包括了过滤器、限流、权限、基本路由、整合Eureka 断言predicates 等功能,也会介绍和zuul这个框架的一个对比, Spring Cloud 生态系统中的网关,得力于 Spring Cloud 生态环境,我相信公司用Spring Cloud 框架 一般都会用到这个网关路由框架,因此这个是跑不掉,本篇文章介绍的一部分,当然不可能全部介绍,其他部分可以去官网去查找学习。

 

什么是网关

网关是一个服务,是访问内部系统的唯一入口,提供内部服务的路由中转,额外还可以在此基础上提供如身份验证、监控、负载均衡、限流、降级与应用检测等功能。

而为什么要说zuul, SpringCloud Gateway 本身就是替换zuul , zuul 本身开始闭源了, 而且还zuul1.x与zuul2.x  ;zuul1.x 基于 servlet  ,zuul2.x  是基于 servlet 和netty 的开发的。 注定 选定 SpringCloud Gateway   并且 它开发的比较晚,技术选型更好。

 这些性能都不是太高,而性能高的还是nginx+lua ,因为涉及到netty  来说  业务线程 去处理,响应式的,也会消耗业务线程,也会消耗性能。都是具体问题具体分析来说,技术选型也需要选择不同的方式;对于普通来说也不是相差特别大。

控制流

Nignx+lua (openresty kong)

业务逻辑 上的  这个  语言上的差异 导致 这个  控制流 处理非常快。

业务网关 收到请求 需要找服务  通过注册中心连接,负载 网关 以及 服务的负载量。 放弃单点的情况,使用 集群的情况。保证一致性 ,限流  要用redis   记录日志等功能,都是系统需要考虑的功能,大系统一定要考虑到的。

 像一般的网关io  吞吐量,请求数据,过网关,但返回数据是否过网关,这个东西根据吞吐量,来说一般会过网关,然后获取到客户端数据,然后返回,想lvs 这些会把客户端数据带给服务端,然后不过网关返回客户端数据,这种根据自己的需要选择。各有各的优点和缺点。

Spring Cloud Gateway 与 Zuul 对比

 zuul1.x与zuul2.x

Zuul 1.x 基于同步 IO

 

zuul2.x

基于异步io

 

zuul1.x 对比 zuul2.x 性能提升

 SpringCloud Gateway 使用

断言 predicates

多个断言可以配合使用

通过匹配的方式,访问到具体的路由规则,服务上面。

 

 在服务中配置  对应的  配置打到具体的机器上,

 包括多层匹配 ,当上面的匹配到才会到下面的匹配方式

 

path断言

        predicates:
        - Path=/mg/**

Query断言

参数值可以写正则,也可以只写参数名

  predicates:
        - Query=foo,ba.

Method断言

 

     predicates:
        - Method=get

Host断言

predicates:
        - Host=mashibing.com

Cookie断言

```
        predicates:
        - Cookie=name,yiming
```

基础使用上,比较简单的,按照具体的规则,写就可以了。

另向路由的方式,会话保持。这是cookie 的保持

 

 

基本路由

依赖

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

配置文件

spring:
  cloud:
    gateway:
      routes:
      - id: xxooroute
        uri: http://localhost:8080  
        filters:
        - StripPrefix=2


server:
  port: 80

 

整合Eureka

依赖

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

配置

```
spring:
  cloud:
    gateway:
      discovery:
        locator:
        // 开启从eureka 拉取服务列表  并自动映射
          enabled: true

  application:
    name: myGateWay
eureka:
  client:
    service-url:
      defaultZone: http://euk1.com:7002/eureka/


server:
  port: 80
```

 负载均衡

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true



      routes:
      - id: mdb
        predicates:
        - Path=/mangodb/**
        uri: lb://MDB
        filters:
        - StripPrefix=1


  application:
    name: myGateWay




eureka:
  client:
    service-url:
      defaultZone: http://euk1.com:7002/eureka/


server:
  port: 80

做匹配的规则,

自定义负载均衡

配置

 在代码中做匹配规则,

 

MDB:
  ribbon:
    NFLoadBalancerRuleClassName: com.admin.MyRule

 

package com.admin;

import java.util.List;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;

public class MyRule extends AbstractLoadBalancerRule

    @Override
    public Server choose(Object key) 
        // TODO Auto-generated method stub
        List<Server> list = this.getLoadBalancer().getReachableServers();


        System.out.println(list);
        // 各种逻辑~~~~
        System.out.println("xxoo");
        return list.get(0);
    

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) 
        // TODO Auto-generated method stub

    

参与到整个过滤规则。

 自定义路由

    @Bean
    public RouteLocator routeLocator (RouteLocatorBuilder locatorBuilder) 

        return locatorBuilder.routes()
                .route(p -> 
                    p.path("/xxoo")
                    .filters(f -> f.stripPrefix(1))
                    .uri("http://ss.com")
                        )

                .route(p ->

                    p.path("/go")
                    .filters(f -> f.stripPrefix(1))
                    .uri("lb://MDB")
                        )

                .build();
    

自定义过滤器

package com.admin;

import java.util.List;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
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
public class MyFilter implements Ordered,GlobalFilter 

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) 

        ServerHttpRequest request = exchange.getRequest();

        MultiValueMap<String, String> queryParams = request.getQueryParams();
        List<String> list = queryParams.get("id");

        if (null == list || list.size() ==0) 

            // 非法请求


//            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
//            
//            return exchange.getResponse().setComplete();
            DataBuffer dataBuffer = exchange.getResponse().bufferFactory().wrap("xiake~!!".getBytes());

            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);

            return exchange.getResponse().writeWith(Mono.just(dataBuffer));

        

        return chain.filter(exchange);
    

    @Override
    public int getOrder() 
        // TODO Auto-generated method stub
        return 0;
    

 

以上是关于SpringCloud Gateway简单使用的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud Gateway

最简单 springcloud 项目实践

SpringCloud系列之网关gateway-4.路由功能详解

API网关:SpringCloud Gateway

SpringCloud Gateway

SpringCloud Gateway简单使用