SpringCloud服务网关之【Gateway】

在这里插入图片描述

理论

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 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

gateway之所以性能好,因为底层使用WebFlux,而webFlux底层使用netty通信(NIO)

三大核心

路由

路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由,说白了就是根据某些规则,将请求发送到指定服务上

实现

  1. 建模块cloud_gateway_9527
  2. 导依赖
<!--gateway-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 添加yml文件
server:
  port: 9527
spring:
  application:
    name: cloud-gateway

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka  # 注册地址和端口
  instance:
    hostname: cloud-gateway-service
  1. 主启动类,添加@EnableEurekaClient@EnableDiscoveryClient注解
  2. 我们目前不想暴露cloud-provider-payment8001服务的8001端口,希望在8001端口外面套一层9527,添加配置,为8001服务的访问地址做了路由匹配
spring:
  cloud:
    gateway:
      routes:
        - id: payment_routh                 #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001        #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**          #断言,路径相匹配的进行路由

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

表示当访问localhost:9527/payment/get/1时,路由到localhost:8001/payment/get/1
6. 启动测试
在这里插入图片描述

重构

上面的实现将访问地址和端口写死了,接下来实现路由侧的动态路由负载均衡
修改GateWay服务的yml配置文件,注释掉之前的配置的uri路由地址,改为服务名uri: lb://cloud-payment-service
官网文档:Spring Cloud Netflix Ribbon会在定义lb前缀的目标URI上实现负载均衡

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

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

启动cloud-provider-payment8001和cloud-provider-payment8002服务,启动网关服务,访问http://localhost:9527/payment/lb,测试是否实现了根据服务名完成了动态路由,以及是否实现了负载均衡。

断言

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

之前在配置文件中配置了断言,这个-Path断言表示,如果外部访问路径是指定路径,就路由到指定微服务上

断言类型

在这里插入图片描述
其中有时间相关的断言,时区时间格式可由ZoneDateTime这个类获得

public static void main(string[] args){
	ZonedDateTime time = ZonedDateTime.now();//默认时区
	System.out.println(time);
}

断言就是实现一组匹配规则,让请求过来找到对应的Route进行处理

过滤器

指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用,Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFactory的工厂类来产生。
过滤器生命周期:在请求进入路由之前,和处理请求完成,再次到达路由之前

自定义过滤器

在网关服务中定义一个过滤器类,实现 GlobalFilterOrdered 这两个接口

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("***********************come in MyLogGateWayFilter"+ new Date());
        // 要求请求必须带上uname的查询参数
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if(uname == null){
            log.info("**********用户名为null***********滚");
            // 设置相应状态为NOT_ACCEPTABLE
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        // 如果通过,则跳到下一个过滤链
        return chain.filter(exchange);
    }

    // 表示加载过滤器的优先级,数字越小优先级越高
    @Override
    public int getOrder() {
        return 0;
    }

重启网关服务,访问测试:http://localhost:9527/payment/lb?uname=kzj成功,若不带上uname参数则测试失败

扩展:curl命令

curl + 微服务地址 + 参数
curl http://localhost:9527/payment/lb 这是一个get请求
curl http://localhost:9527/payment/lb --cookie "username=kzj" 带上cookie

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值