Springcloud-Gateway部分学习笔记


视频学习地址:https://www.bilibili.com/video/BV18E411x7eT
源码地址:https://gitee.com/zhu_xinmiao/springcloud
spring cloud版本:H版

Gateway网关实际上就是在微服务前套了一层包装,使微服务的端口不会直接暴露给使用者,提高了安全性。

类似于网关端口9527,服务端端口8001,在设置网关后,对于8001端口方法的使用不会在去访问8001端口,而是访问localhost:9527。

三大核心概念

  • 路由 route
  • 断言 predicate
  • 过滤器 filter
    在这里插入图片描述

搭建

  1. 写pom,主要是引入以下依赖,此外gateway不需要web依赖

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

    server:
      port: 9527
    
    spring:
      application:
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            - id: payment_routh
              uri: http://localhost:8001
              predicates:
                - Path=/payment/get/**
            - id: payment_routh2
              uri: http://localhost:8001
              predicates:
                - Path=/payment/lb/**
    
    eureka:
      instance:
        hostname: cloud-gateway-service
      client:
        service-url:
          register-with-eureka: true
          fetch-registry: true
          defaultZone: http://eureka7001.com:7001/eureka
    

    路由部分解释如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YF1KqFfn-1596241133211)(image-20200731151600957.png)]

  3. 写主启动类

    @SpringBootApplication
    @EnableEurekaClient
    

除了用yml配置路由外,还可通过写config文件配置路由。

@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator CustomRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes(); //类似于yml中的routes
        /**
         * path_route_zxm"相当于yml中routes下的id
         * r -> r.path("/guonei")
         *        .uri("http://news.baidu.com/guonei")).build();
         *  表示你访问9527/guonei,会转发到
         *  http://news.baidu.com/guonei
         */
        routes.route("path_route_zxm",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }
}

配置动态路由

对yml中路由的配置进行修改

cloud:
  gateway:
    discovery:
      locator:
        enabled: true  #开启注册中心路由功能
    routes:
      - id: payment_routh
        #          uri: http://localhost:8001
        uri: lb://cloud-payment-service #此处如果有问题,请注意依赖spring-cloud-starter-netflix-eureka-client依赖不能错
        predicates:
          - Path=/payment/get/**
      - id: payment_routh2
        #          uri: http://localhost:8001
        uri: lb://cloud-payment-service
        predicates:
          - Path=/payment/lb/**

测试http://localhost:9527/payment/lb时会在8001/8002两个端口间切换,实现负载均衡。

这里我出现了一个问题,8001和8002注册不进eureka,查到以下解决方法https://www.cnblogs.com/sxdcgaq8080/p/9843912.html

一条一条排查后,发觉唯一可能出错的地方应该是eureka的地址有问题,排查8001和8002的yml发现eureka的路径都为集群模式defaultZone: http://localhost:7001/eureka ,http://eureka7002.com:7002/eureka

改为单机模式defaultZone: http://localhost:7001/eureka后成功注册进eureka

常用的Predicate

  1. Path

    - Path=/payment/lb/**
    

    表示判断的路径,路径符合路由就会跳转到这个路径

  2. - After=2020-07-31T19:50:32.545+08:00[Asia/Shanghai]
    

    表示判断的时间,只有时间在这个之后路由才会跳转到这个页面否则会报404错误。实际应用时,类似于秒杀系统定好时间,只有到点了才能进入抢票环节。

    这里重要的是如何得到对应的时区时间,这里写了一个测试类来演示获取时区的方法。

    public static void main(String[] args) {
        ZonedDateTime zbj = ZonedDateTime.now();
        System.out.println(zbj);
    }
    
  3. - Cookie=cookiename, zxm
    

    表示需要带上cookie访问,不带的话会报404错误,curl测试如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SZpWkwDr-1596241133215)(image-20200801071935366.png)]

其他属性类似,具体可看https://blog.csdn.net/u012367513/article/details/86356708这篇博客中的介绍。

Filter

Route filters可以通过一些方式修改HTTP请求的输入和输出,针对某些特殊的场景,Spring Cloud Gateway已经内置了很多不同功能的GatewayFilter Factories。

可以通过官方文档进行查询,也可通过该网址进行学习。

这里主要讲讲自定义的filter。

@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
    /**
     * 简单过滤了用户名为空的非法用户
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("*****come in MyLogGatewayFilter: " + new Date());
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null){
            log.info("*****用户名为null,非法用户");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange); //放行
    }

    /**
     * 表示加载过滤器的顺序,一般越小越优先
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

这里简单过滤了用户名为空的非法用户,但在测试时出现了问题,输入正常用户名,返回的也是404,经过测试发现并没有进过滤方法。

经过仔细排查后,发现是之前写的断言没有注释,断言中要求有cookie才能正常访问,注释掉后即可正常运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值