SpringCloud微服务之服务网关-gateway的使用

SpringCloud微服务之服务网关-gateway的使用

  • 前言
  • 一、服务网关?
  • 二、springcloud gateway和zuul的区别
  • 三、使用步骤
    • 1.Route路由
      • 1.1 pom
      • 1.2 yml
      • 1.3 启动类
      • 1.4 测试
      • 1.5 路由配置方式
      • 1.6 动态路由
    • 2.Predicate断言
    • 3.Filter过滤器
  • 总结


前言

springcloud技术栈:
SpringCloud微服务之服务网关-gateway的使用_第1张图片


一、服务网关?

在计算机网络中,服务网关是一种连接不同网络的设备或程序。它提供了一个连接不同网络的桥梁,它可以将数据包从一个网络传递到另一个网络。它可以是硬件设备,也可以是软件程序。服务网关则是指在微服务架构中,负责将对外提供的API请求路由到相应的微服务上,并提供负载均衡、服务降级、故障恢复等功能。在实际应用中,Gateway可以使用开源框架如Nginx、Zuul、Kong等来实现。

二、springcloud gateway和zuul的区别

我们最常见的服务网关实现莫过于是springcloud gateway和zuul。而两者的区别是什么呢?
Spring Cloud Netflix Zuul是由Netflix开源的API网关,在微服务架构下,网关作为对外的门户,实现动态路由、监控、授权、安全、调度等功能。Zuul基于servlet 2.5(使用3.x),使用阻塞API。 它不支持任何长连接,如websockets。而Gateway建立在Spring Framework 5,Project Reactor和Spring Boot 2之上,使用非阻塞API。 比较完美地支持异步非阻塞编程,Gateway 中Websockets得到支持,并且它是spring开发,完美集成在spring中,使用起来体验感会更好,本文叙述的是gateway的使用方式。
Springcloud gateway有三大概念:Route(路由)、 Predicate(断言)和Filter(过滤器)。

三、使用步骤

本次配置是gateway微服务的模块配置,在启动和测试本模块之前,需要新建好注册中心模块和服务提供者微服务模块,不清楚的可以查看上几篇文章。

1.Route路由

1.1 pom

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

1.2 yml

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

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

1.3 启动类

@SpringBootApplication
@EnableEurekaClient
public class gatewayMain {
    public static void main(String[] args) {
        SpringApplication.run(gatewayMain.class, args);
    }
}

1.4 测试

没有配置服务网关之前,我们会直接访问服务方的接口,比如: http://localhost:8001/payment/get/1;当配置后,会根据配置文件的uri地址进行服务匹配,访问 http://localhost:9527/payment/get/1能够达到一样的效果。

1.5 路由配置方式

除了上述的这种yml配置方式,还有一种较为繁琐的bean方式。
新建配置文件gatewayconfig,启动访问可以达到一样的效果。

@Configuration
public class GateWayConfig {
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_atguigu", r -> r.path("/guoji").uri("http://news.baidu.com"))
                .build();
        return routes.build();
    }
}

1.6 动态路由

一般来说,路由配置基本很少去写死服务的端口号,所以gateway的动态路由使用是最为频繁的,也是最常用的。其实很简单,在上述的yml文件中修改uri的配置value值即可。
lb://cloud-payment-service:lb代表负载均衡,可以查看上本系列文章负载均衡实现方式,cloud-payment-service表示的是服务提供者的地址,这样无需关注端口。gateway会根据注册中心注册的服务列表,以注册中心上微服务为路径创建动态路由进行转发,实现动态路由功能。

 uri: lb://cloud-payment-service #匹配后提供服务的路由地址

2.Predicate断言

在上述的配置中,我们已经实现了断言的最基本的方法,更多方法在项目启动时打印的断言日志可以看到断言的所有配置项。
SpringCloud微服务之服务网关-gateway的使用_第2张图片
比如:After(在配置的时间之后触发)、Before(在配置的时间之前触发)、Between(在配置的时间之间触发)等。可以查看官网文档介绍,实现方式都很简单。

predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
           	- After=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
            - Before=2020-03-08T10:59:34.102+08:00[Asia/Shanghai]
            - Between=2020-03-08T10:59:34.102+08:00[Asia/Shanghai] ,  2020-03-08T10:59:34.102+08:00[Asia/Shanghai]

3.Filter过滤器

yml在routes下配置参数:filter参数,有由于太多种,推荐去官网可以查看具体的配置项。这里主要介绍自定义过滤器,因为这是最常用的的方式。
新建配置文件:启动后访问http://localhost:9527/payment/lb?name=111。文件中request.getQueryParams().getFirst(“name”)表示在访问接口时必须携带name参数,否则访问不到。

@Component
public class MyGateWayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("-------------MyGateWayFilter-----------" + new Date());
        ServerHttpRequest request = exchange.getRequest();
        String uname = request.getQueryParams().getFirst("name");
        if (uname == null) {
            System.out.println("name为空!参数非法!!!");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

总结

具体不清楚的可以查看本系列文章,或者评论留言。

你可能感兴趣的:(spring,cloud技术栈,spring,cloud,微服务,gateway)