• 微服务-gateway【服务网关入门】


    在这里插入图片描述

    概述

    Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和 Project Reactor等技术。
    Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能, 例如:熔断、限流、重试等。

    SpringCloud Gateway 是 Spring Cloud 的一个全新项目,基于 Spring 5.0+Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

    SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

    Spring Cloud Gateway的目标提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

    通俗来说,SpringCloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架。

    作用

    1. 反向代理
    2. 鉴权
    3. 流量控制
    4. 熔断
    5. 日志监控

    如下所示,这边便是gateway的工作区域
    在这里插入图片描述

    gateway的三大核心概念

    路由

    路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由

    断言

    参考的是Java8的java.util.function.Predicate
    开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由

    过滤

    指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

    小结

    1. web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。
    2. predicate就是我们的匹配条件;
    3. 而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了

    在这里插入图片描述

    gateway路由基础使用示例

    操作步骤

    新建模块cloud-gateway-gateway9527

    在这里插入图片描述

    配置pom文件

    
    
        
            mscloud
            com.zsy.springcloud
            1.0-SNAPSHOT
        
        4.0.0
        com.zsy.springcloud
        cloud-gateway-gateway9527
        1.0-SNAPSHOT
        
            
            
                org.springframework.cloud
                spring-cloud-starter-gateway
            
            
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-client
            
            
            
                com.zsy.springcloud
                cloud-api-commins
                ${project.version}
            
            
            
                org.springframework.boot
                spring-boot-devtools
                runtime
                true
            
            
                org.projectlombok
                lombok
                true
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
        
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    yml编写gateway配置

    如下图所示,我们将服务注册的服务注册中心去,并且配置到达我们所需服务的路由,这样我们就可以通过gateway来完成路由转发功能了

    server:
      port: 9527
    
    • 1
    • 2

    spring:
    application:
    name: cloud-gateway
    cloud:
    gateway:
    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
    • 2
    • 3
    • 4

    eureka:
    instance:
    hostname: cloud-gateway-service
    client: #服务提供者provider注册进eureka服务列表内
    service-url:
    register-with-eureka: true
    fetch-registry: true

    eureka注册中心的地址

      defaultZone: http://127.0.0.1:7001/eureka
    
    • 1

    编写启动类

    package com.zsy.springclou;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    @SpringBootApplication
    @EnableEurekaClient
    public class GateWayMain9527 {
        public static void main(String[] args) {
            SpringApplication.run(GateWayMain9527.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    之后启动服务输入地址http://localhost:9527/payment/get/1 即可完成基于gateway访问8001端口的支付服务

    注意开启所有payment模块以及eureka服务注册中心,然后再开启gateway

    硬编码的方式实现路由

    如下图所示,在boot项目中增加这样一个配置类,将gateway地址转发到对应uri上即可。

    package com.zsy.springclou.config;
    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    public class GateWayConfig {
        @Bean
        public RouteLocator customRouterLocator(RouteLocatorBuilder builder) {
            RouteLocatorBuilder.Builder router = builder.routes();
            router.route("new_router", r -> r.path("/guonei").uri("http://news.baidu.com/guonei")).build();
            return router.build();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试也很简单,输入http://localhost:9527/guonei即可跳转到百度的国内新闻

    gateway实现动态路由

    配置步骤也很简单,只需要将eureka上做负载的的服务名配置到uri上即可
    在这里插入图片描述开启所有payment模块以及eureka服务注册中心,然后再开启gateway
    这时候通过地址http://localhost:9527/payment/lb即可访问payment模块,又有是负载所以访问是随机的

    gateway断言使用示例

    如下所示,笔者想让这个请求在指定时间后且cookie为指定内容生效只需按照如下处理即可
    具体也可以参照spring的官网示例
    https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories
    在这里插入图片描述使用开启所有payment模块以及eureka服务注册中心,然后再开启gateway
    上述配置完成后可用curl命令进行测试

    curl http://localhost:9527/payment/lb --cookie "uname=zsy"
    
    • 1

    gateway过滤使用示例

    package com.zsy.springclou.config;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.cloud.gateway.filter.GatewayFilterChain;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.core.Ordered;
    import org.springframework.http.HttpStatus;
    import org.springframework.stereotype.Component;
    import org.springframework.web.server.ServerWebExchange;
    import reactor.core.publisher.Mono;
    @Component
    @Slf4j
    public class MyGateFielter implements GlobalFilter, Ordered {
        @Override
        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            log.info("执行了全局过滤器");
            String uname = exchange.getRequest().getQueryParams().getFirst("uname");
            if (uname == null) {
                log.error("uname为空,请求将会被拦截");
    exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
                return exchange.getResponse().setComplete();
            }
            log.info("uname不为空,放行了,当前uname:" + uname);
            return chain.filter(exchange);
        }
        @Override
        public int getOrder() {
            return 0;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    测试
    使用开启所有payment模块以及eureka服务注册中心,然后再开启gateway
    测试命令

    curl http://localhost:9527/payment/lb?uname=zsy
    
    • 1

    在这里插入图片描述

  • 相关阅读:
    Java笔记:多线程基础
    插入记录的方式
    微软最热门的10款前端开源项目!
    springboot+jsp项目校园外卖配送系统
    深度学习必备Python基础知识充电3
    table的基本用法
    jdk8 | Function<T,R>实践应用
    多线程服务器端的实现
    详解AQS中的condition源码原理
    IS-IS 路由选择协议入门
  • 原文地址:https://blog.csdn.net/m0_51411338/article/details/126126597