08--gateway 集成sentinel

  1. 前面我们已经说了WebFlux集成sentinel,此集成在gateway中同样适用.
  2. gateway集成sentinel开发包
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
  1. sentinel中可以做为 resource 的资源

    1. 网关中 的 route.id
    2. 自定义api分组
    3. 链接
  2. 接下来我们 自定义 api分组,限流规则及异常处理器

package com.cloud.alibaba.config.sentinel.gateway;

import com.alibaba.csp.sentinel.adapter.gateway.common.SentinelGatewayConstants;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiDefinition;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPathPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.ApiPredicateItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.api.GatewayApiDefinitionManager;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayParamFlowItem;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * 限流规则配置类
 *
 * @author admin
 */
@Configuration
public class GatewayConfiguration {

    @PostConstruct
    public void doInit() {
        // 自定义api分组
        initCustomizedApis();
        // 加载网关限流规则
        initGatewayRules();
        // 加载自定义限流异常处理器
        initBlockHandler();
    }

    /**
     * 自定义api分组
     */
    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();
        // product-api 组
        ApiDefinition api1 = new ApiDefinition("producer-example-api")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    add(new ApiPathPredicateItem().setPattern("/producer/**")
                            /**
                             * 网址匹配策略前缀 /producer 和 /producer/**
                             */
                            .setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
                    /**
                     * 只匹配/producer/getUser
                     */
                    add(new ApiPathPredicateItem().setPattern("/producer/getUser"));
                }});
        definitions.add(api1);
        /**
         * 加载限流分组
         */
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }

    /**
     * 网关限流规则
     */
    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();

        /**
         * PARAM_PARSE_STRATEGY_URL_PARAM 参数提取策略 任意 URL 参数
         * PARAM_MATCH_STRATEGY_CONTAINS 匹配规则 URL 参数中是否包含 FieldName。示例中是type字段
         * 通俗讲就是 如果url携带type参数。将走此规则。否则不走此规则
         * 示例 http://192.168.1.25:10004/producer/getUserName?type=1 走此规则
         * 示例 http://192.168.1.25:10004/producer/getUserName 不走此规则
         * 其余的规则 参考 https://github.com/alibaba/Sentinel/blob/master/sentinel-demo/sentinel-demo-spring-cloud-gateway/src/main/java/com/alibaba/csp/sentinel/demo/spring/sc/gateway/GatewayConfiguration.java
         */
        rules.add(new GatewayFlowRule("producer-example-api")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                .setGrade(1)
                .setCount(1)
                .setIntervalSec(1)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        .setFieldName("type")
                        .setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_CONTAINS)
                )
        );

        GatewayRuleManager.loadRules(rules);
    }

    /**
     * 自定义限流异常处理器
     */
    private void initBlockHandler() {
        BlockRequestHandler blockRequestHandler = (serverWebExchange, throwable) -> {
            ParamFlowException paramFlowException = (ParamFlowException) throwable;
            Map<String, String> result = new HashMap<>(3);
            result.put("state", String.valueOf(HttpStatus.TOO_MANY_REQUESTS.value()));
            result.put("msg", HttpStatus.TOO_MANY_REQUESTS.getReasonPhrase());
            result.put("route", paramFlowException.getResourceName());
            return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(BodyInserters.fromObject(result));
        };

        // 加载自定义限流异常处理器
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }

}

GatewayFlowRule规则配置

源码地址
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值