SpringCloud之gateway

SpringCloud之gateway

简介

Gateway(网关)是一种用于构建微服务架构的重要组件,它充当了系统的入口点,将外部请求转发到相应的微服务中。

  1. 路由转发:Gateway 扮演着请求转发的角色,根据请求的路径和规则将请求转发到相应的微服务实例上。它可以对请求进行动态路由、负载均衡、熔断处理等。
  2. 安全与认证:Gateway 可以集成认证和授权机制,例如 OAuth、JWT 等,用于保护微服务的安全性。它可以拦截请求并验证用户身份、权限等。
  3. 流量控制:Gateway 可以通过限流和配额设置来控制流量,防止过多的请求超过各个微服务的处理能力。它可以根据服务实例的负载情况进行智能的流量分发和控制。
  4. 协议转换:Gateway 可以将外部请求的协议转换为微服务所需要的协议,例如将 HTTP 请求转换为 gRPC 请求,从而使不同协议的微服务能够无缝协同工作。
  5. 日志与监控:Gateway 可以在请求转发过程中记录日志,并提供监控和指标数据,帮助开发人员和运维人员了解系统的运行情况、故障排查等。
  6. 灰度发布:Gateway 可以实现服务的灰度发布,将部分请求流量引导到新版本的微服务上,以验证新功能或修复的问题,同时保持旧版本的稳定运行。

集成gateway

导入Maven依赖

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

gateway的使用

路由转发
spring:
  cloud:
    gateway:
      routes:
        # 路由id
        - id: test_gateway
          # 路由转发的url,这样的配置可以通过nacos进行访问
          uri: lb://service-A
          # 路由匹配条件
          predicates:
            # 匹配hello的所有请求
            - Path=/hello/**
            # 匹配主机名以example.com结尾的主机名
            - Host=**.example.com
            # 匹配请求的方法为GET的请求
            - Method=GET
            # 匹配header中X-Request-Id参数,且数据为数字,\d+表示匹配多个数字
            - Header=X-Request-Id, \d+
            # 匹配id为12345的请求
            - Query=id,12345
            # 匹配访问的ip地址结尾从0-255
            - RemoteAddr=192.168.1.0/24
          filters:
            # 向请求添加请求头, key为X-Request-Foo,value为Bar
            - AddRequestHeader=X-Request-Foo, Bar
            # 向响应体加请求头,key为X-Response-Foo,value为Bar
            - AddResponseHeader=X-Response-Foo, Bar
            # 重写路径将segment.*,url写成segment
            - RewritePath=/foo/(?<segment>.*), /${segment}
            # 使用熔断处理
            - name: Hystrix
              args:
                name: myCommand
            # 移除一个前缀
            - StripPrefix=1
            # 重试机制
            - name: Retry
              args:
                retries: 3
                statuses: BAD_GATEWAY, GATEWAY_TIMEOUT
                methods: GET, POST

lb:// 是 Spring Cloud Gateway 用于负载均衡的 URI 标识符,它会使用 Spring Cloud LoadBalancer 来寻找服务实例。

自定义 GlobalFilter
public class TestFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 编写逻辑,进入下一个过滤器
        if (true){
            return chain.filter(exchange);
        }
        // 不满足要求进行处理
        throw new RuntimeException("错误");
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
自定义GatewayFilter
public class TestGatewayFilter extends AbstractGatewayFilterFactory<TestGatewayFilter.Config> {

    @Override
    public GatewayFilter apply(Config config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // 执行逻辑
                if (true){
                    return chain.filter(exchange);
                }
                throw new RuntimeException("错误");
            }
        };
    }

    public static class Config {

        private String businessAttributes;

        public String getBusinessAttributes() {
            return businessAttributes;
        }

        public void setBusinessAttributes(String businessAttributes) {
            this.businessAttributes = businessAttributes;
        }
    }
}
GlobalFilter与GatewayFilter的区别

GlobalFilter是全局的,意为对全部的请求进行修改

GatewayFilter是局部的,只有经过该过滤器的请求才会进行修改

安全与认证

可以在全局过滤器中进行token的校验,校验token是否可被解析。

流量控制
spring:
  cloud:
    gateway:
      default-filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10
            redis-rate-limiter.burstCapacity: 20

配置bean

@Configuration
public class RateLimiterConfig {

    @Bean
    public RequestRateLimiterGatewayFilterFactory rateLimiter() {
        return new RequestRateLimiterGatewayFilterFactory();
    }
}
协议切换
spring:
  cloud:
    gateway:
      routes:
        # 路由id
        - id: test_gateway
          uri: lb://service-A
          # 路由匹配条件
          filters:
            # 向请求添加请求头, key为X-Request-Foo,value为Bar
            - AddRequestHeader=X-Request-Foo, Bar

编写controller

@RestController
@RequestMapping("/test")
public class TestController {

    @GetMapping("/hello")
    public String getHello(@RequestHeader("X-Request-Foo")String header){
        return "Received header: " + header;
    }

}

当uri为service-A时会在请求的header中添加Bar,这样就会将请求请求到下级服务中

日志与监控

可以通过yaml中配置Prometheus 监控服务器进行监控。

灰度发布

灰度发布就是在当前版本中发布最新版本,一种逐步将新版本的服务引入生产环境的方法。

server:
  port: 8080

spring:
  cloud:
    gateway:
      routes:
        - id: service-v1
          uri: http://localhost:8081
          predicates:
            - Path=/api/**
          filters:
            - name: GrayReleaseFilter
              args:
                weight: 50 # 表示 50% 的流量

        - id: service-v2
          uri: http://localhost:8082
          predicates:
            - Path=/api/**
          filters:
            - name: GrayReleaseFilter
              args:
                weight: 50 # 表示 50% 的流量

编写gatewayFilter

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;

import java.util.Random;

@Component
public class GrayReleaseFilter extends AbstractGatewayFilterFactory<GrayReleaseFilter.Config> {

    public static class Config {
        private int weight;

        public int getWeight() {
            return weight;
        }

        public void setWeight(int weight) {
            this.weight = weight;
        }
    }

    public GrayReleaseFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            // 使用随机数来决定请求分配到哪个版本
            Random random = new Random();
            if (random.nextInt(100) < config.getWeight()) {
                // 将请求分配到新的版本
                return chain.filter(exchange.mutate().request(request.mutate().header("Gray-Version", "v2").build()).build());
            } else {
                // 将请求分配到旧的版本
                return chain.filter(exchange.mutate().request(request.mutate().header("Gray-Version", "v1").build()).build());
            }
        };
    }
}

原理分析

gateway通过配置的形式映射到Java类上,而映射的实例是GatewayProperties
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

globalFilter

该过滤器是gateway中的全局过滤器,拦截所有http请求,根据predicate过滤得到满足条件的uri

GatewayFilter

由开发人员操作,可以对predicate过滤后满足条件的uri,进行属性的添加,比如:在header加上参数之类的。

综上所述,gateway的执行流程如下:

1.将yaml配置转化为JavaBean -> 2.加载routeDefinitionLocator -> 3.执行全局过滤器GlobalFilter -> 4.加载RouteDefinition、predicates、filters参数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值