栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Gateway 简单使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Gateway 简单使用

文章目录
        • 一、简介
        • 二、核心概念
          • 1、导入核心依赖
          • 2、Predicate 常用参数配置
          • 3、filter 配置
            • ①、Default Filters
            • ②、Global Filters
        • 三、sentinel + gateway 网关限流
          • 1、sentinel 添加网关流控项目
          • 2、route 维度
            • ①、yaml 配置
            • ②、代码配置
            • ③、sentinel 控制台
            • ④、添加 route 限流
          • 3、自定义 API 维度
            • ①、代码添加 API
            • ②、sentinel 控制台添加 API 分组
            • ③、sentinel 控制台
            • ④、添加 API 限流
        • 四、sentinel 网关限流处理逻辑
          • 1、yaml 配置使用默认处理逻辑
            • ①、response 响应模式
            • ②、redirect 响应模式
          • 2、自定义网关限流处理逻辑

一、简介
  • Spring Cloud Gateway 旨在提供一种简单而有效的方式来路由到 API,并为它们提供横切关注点,例如:安全性、监控/指标和弹性。
  • Spring Cloud GateWay 组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。
  • Spring Cloud GateWay 的核心功能过滤和路由。

官方文档地址:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/

中文文档(没有新版本):https://www.docs4dev.com/docs/zh/spring-cloud/Greenwich.RELEASE

Gateway 配置:https://docs.spring.io/spring-cloud-gateway/docs/2.2.9.RELEASE/reference/html/appendix.html

二、核心概念
  • Route :路由网关的基本构建块。它由 ID,目标 URI,谓词集合和 filte r集合定义。如果聚合谓词为 true,则匹配路由。

  • Predicate :Java 8 函数谓词。Importing 类型为 Spring Framework ServerWebExchange。这使开发人员可以匹配 HTTP 请求中的所有内容,例如 Headers 或参数。

  • filter :这些实例Spring Framework GatewayFilter 是使用特定工厂构造的。在此,可以在发送下游请求之前或之后修改请求和响应。

1、导入核心依赖
		
            org.springframework.cloud
            spring-cloud-starter-gateway
            2.2.9.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
            2.2.7.RELEASE
        
        
            com.alibaba.cloud
            spring-cloud-alibaba-sentinel-gateway
            2.2.7.RELEASE
        
2、Predicate 常用参数配置
spring:
  cloud:
    gateway:
      routes:
        - id: service1 # 设置路由id(理论上是可以随便写的)
          order: 0 # order 越小,优先级越高
          uri: lb://SPRING-CLOUD-SERVICE-OPENFEIGN     # 设置路由的url  lb://service1(可以使用 nacos 服务注册名,lb 固定写法代表注册) http://localhost:3901(也可以使用绝对地址)
          predicates:
            - Method=GET,POST # 支持方法
            - Path=/service1] # 请求包含 type 查询参数,并且值满足正则表达式,则此路由将匹配。如 /hystrix/calculate?a=10&b=5&type=/ 则匹配成功 /hystrix/calculate?a=10&b=5&type=% 则匹配失败
            # - RemoteAddr=192.168.3.1/24 # 如果请求的远程地址为192.168.3.240,则此路由将匹配。
            # - Cookie=chocolate, ch.p # 名为 chocolate 的 cookie,该 cookie 的值与ch.p正则表达式匹配。
            - Header=Content-Type, application/json;charset=UTF-8 # 请求头必须携带Content-Type,并且值为 application/json;charset=UTF-8 才生效,值支持正则表达式
            - Header=token, 123456789abcdefg # 请求头必须携带 token,并且值为 123456789abcdefg 路由才生效
            - Host=127.0.0.1:**,**.0.0.1:21000 # HTTP/1.1 请求头 Headers 默认包含 Host 头,可以是 IP,域名

postman 测试路由规则 GET 请求:http://127.0.0.1:21000/service1/hystrix/calculate?a=10&b=5&type=/

Predicate Weight 路由规则配置

spring:
  cloud:
    gateway:
      routes:
      - id: weight_high
        uri: https://weighthigh.org
        predicates:
        - Weight=group1, 8
      - id: weight_low
        uri: https://weightlow.org
        predicates:
        - Weight=group1, 2

该路由会将约 80% 的流量转发到 weighthigh.org,将约 20% 的流量转发到 weightlow.org

3、filter 配置
spring:
  cloud:
    gateway:
      routes:
        - id: service1
          order: 0
          uri: lb://SPRING-CLOUD-SERVICE-OPENFEIGN
          predicates:
            - Method=GET,POST
            - Path=/service1] # 请求包含 type 查询参数,并且值满足正则表达式,则此路由将匹配。如 /hystrix/calculate?a=10&b=5&type=/ 则匹配成功 /hystrix/calculate?a=10&b=5&type=% 则匹配失败
            # - RemoteAddr=192.168.3.1/24 # 如果请求的远程地址为192.168.3.240,则此路由将匹配。
            # - Cookie=chocolate, ch.p # 名为 chocolate 的 cookie,该 cookie 的值与ch.p正则表达式匹配。
            - Header=Content-Type, application/json;charset=UTF-8 # 请求头必须携带Content-Type,并且值为 application/json;charset=UTF-8 才生效,值支持正则表达式
            - Header=token, 123456789abcdefg # 请求头必须携带 token,并且值为 123456789abcdefg 路由才生效
            - Host=127.0.0.1:**,**.0.0.1:21000 # HTTP/1.1 请求头 Headers 默认包含 Host 头,可以是 IP,域名
②、代码配置
@Configuration
public class RouteLocatorConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("code_service1", r -> r.method(HttpMethod.GET,HttpMethod.POST)
                        .and().path("/service1/**","/service2/**")
                        .and().after(ZonedDateTime.parse("2022-05-05T02:00:00.000+08:00[Asia/Shanghai]"))
                        .and().header(HttpHeaders.CONTENT_TYPE, "application/json;charset=UTF-8")
                        .and().query("type")
                        .and().header("token", "123456789abcdefg")
                        .and().host("127.0.0.1:**","**.0.0.1:21000")
                        .uri("lb://SPRING-CLOUD-SERVICE-OPENFEIGN")
                )
                .build();
    }
}
③、sentinel 控制台

④、添加 route 限流

在 sentinel 控制台添加 Route ID 网关限流,下面配置说明:如果每秒请求数 >= 1,则快速失败并限流 5 s

3、自定义 API 维度

支持代码配置或 sentinel 控制台配置

①、代码添加 API
@Configuration
public class GatewayConfiguration {

    @PostConstruct
    private void initCustomizedApis() {
        Set definitions = new HashSet<>();
        ApiDefinition api1 = new ApiDefinition("code_service1_api")
                .setPredicateItems(new HashSet() {{
                    add(new ApiPathPredicateItem().setPattern("/service1/sentinel"));
                    add(new ApiPathPredicateItem().setPattern("/service1/openfeign/**")
                            // 一共有三种,对应 sentinel 控制台匹配模式,不写默认精确
                            // URL_MATCH_STRATEGY_EXACT = 0;    精确
                            // URL_MATCH_STRATEGY_PREFIX = 1;   前缀
                            // URL_MATCH_STRATEGY_REGEX = 2;    正则
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                }});
        ApiDefinition api2 = new ApiDefinition("code_service2_api")
                .setPredicateItems(new HashSet() {{
                    add(new ApiPathPredicateItem().setPattern("/service2/test"));
                }});
        definitions.add(api1);
        definitions.add(api2);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }
}
②、sentinel 控制台添加 API 分组

③、sentinel 控制台

④、添加 API 限流

在 sentinel 控制台添加 API 分组网关限流,下面配置说明:如果每秒请求数 >= 1,则快速失败并限流 5 s

四、sentinel 网关限流处理逻辑 1、yaml 配置使用默认处理逻辑

spring-cloud-alibaba-sentinel-gateway 提供了如下配置选项,支持 yaml 配置限流处理逻辑

配置项含义默认值

spring.cloud.sentinel.scg.fallback.mode

Spring Cloud Gateway 流控处理逻辑 (选择 redirect or response)

spring.cloud.sentinel.scg.fallback.redirect

Spring Cloud Gateway 响应模式为 'redirect' 模式对应的重定向 URL

spring.cloud.sentinel.scg.fallback.response-body

Spring Cloud Gateway 响应模式为 'response' 模式对应的响应内容

spring.cloud.sentinel.scg.fallback.response-status

Spring Cloud Gateway 响应模式为 'response' 模式对应的响应码

429

spring.cloud.sentinel.scg.fallback.content-type

Spring Cloud Gateway 响应模式为 'response' 模式对应的 content-type

application/json

如果不配置限流逻辑,则返回如下结果(DefaultBlockRequestHandler.class)

{
    "code": 429,
    "message": "Blocked by Sentinel: ParamFlowException"
}
①、response 响应模式

reponse 返回错误数据

spring:
  cloud:
    sentinel:
      scg:
        fallback:
          content-type: application/json
          response-status: 429
          response-body: spring-cloud-gateway-study 服务限流
          mode: response

②、redirect 响应模式

redirect 重定向到新的页面

spring:
  cloud:
    sentinel:
      scg:
        fallback:
          redirect: https://blog.csdn.net/qq_41538097/article/details/124447411
          mode: redirect

2、自定义网关限流处理逻辑

GatewayCallbackManager 注册回调进行定制:

  • setBlockHandler:注册函数用于实现自定义的逻辑处理被限流的请求,对应接口为 BlockRequestHandler。
  • 默认实现为 DefaultBlockRequestHandler,当被限流时会返回类似于下面的错误信息:Blocked by Sentinel: FlowException。

新增 DiyBlockRequestHandler 类实现自定义网关限流处理逻辑

@Configuration
public class DiyBlockRequestHandler implements BlockRequestHandler {
    @Override
    public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable e) {
        String msg = null;
        if (e instanceof FlowException) {
            msg = "限流了,请稍后访问";
        } else if (e instanceof DegradeException) {
            msg = "降级了,返回默认数据";
        } else if (e instanceof ParamFlowException) {
            msg = "热点参数限流";
        } else if (e instanceof SystemBlockException) {
            msg = "系统规则(负载/...不满足要求)";
        } else if (e instanceof AuthorityException) {
            msg = "授权规则不通过";
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msg", msg);
        jsonObject.put("code",HttpStatus.TOO_MANY_REQUESTS);
        // 返回默认数据
        Map map = new HashMap<>();
        map.put("username", "admin");
        map.put("address", "西安");
        jsonObject.put("mock", map);

        return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromObject(jsonObject));
    }

    @PostConstruct
    public void initBlockRequestHandler() {
        GatewayCallbackManager.setBlockHandler(this);
    }
}

结果如下

未完待续

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/872014.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号