Sentinel限流入門,與gatewway,nacos,boot搭配等

前言

  • 講解spring boot中使用。spring cloud中使用(gateway、nacos中使用)株灸。注意莱革,只做限流講解桐筏,同時spring boot為spring mvc框架除破。spring cloud使用spring webflux框架

  • 基礎環(huán)境 spring boot 2.4.13光坝,sentinel 2021.1,nacos 2021.1gateway 3.0.7

  • 不提供sentinel控制臺jar包芝发,版本1.8.2。不提供nacos中心jar包绵患,版本2.0.3移迫。

spring boot項目限流(需要gateway等的往下翻)

  • 在單獨的spring boot整體項目中限流,此處我做的是代碼持久化,注意是注解式传透。

  • pom.xml文件配置

        <!-- sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>

  • xxx.yml配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:30010  //控制包jar包地址托享。是否與控制臺連接開關碧查,不做測試建議注釋羊瘩,會產(chǎn)生本地文件
        heartbeat-interval-ms: 5000  //心跳時間ms
      enabled: true //Sentinel自動化配置是否生效
  • 創(chuàng)建自定義規(guī)則配置。注意积仗,我這里spring boot項目是多模塊,為了解耦才這么寫
public abstract class CustomSentinelConfig {

    @PostConstruct
    private void config() {
        List<FlowRule> flowRules = new ArrayList<>();

        /**
         * 添加限流方式
         * 10次拒絕訪問
         */
        FlowRule flowRule1 = new FlowRule();
        //資源名,資源名是限流規(guī)則的作用對象
        flowRule1.setResource("限流-10");
        //限流閾值
        flowRule1.setCount(10);
        //調用關系限流策略:直接管搪、鏈路缀壤、關聯(lián)
        flowRule1.setStrategy(0);
        //限流閾值類型蛤织,QPS 或線程數(shù)模式
        flowRule1.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒絕 / 慢啟動模式 / 排隊等待)免猾,不支持按調用關系限流蚓炬,不支持線程
        flowRule1.setControlBehavior(0);
        //組裝
        flowRules.add(flowRule1);

        /**
         * 添加限流方式
         * 5次等待排隊
         */
        FlowRule flowRule2 = new FlowRule();
        //資源名,資源名是限流規(guī)則的作用對象
        flowRule2.setResource("限流等待-5");
        //限流閾值
        flowRule2.setCount(5);
        //調用關系限流策略:直接李根、鏈路盔几、關聯(lián)
        flowRule2.setStrategy(0);
        //限流閾值類型顺献,QPS 或線程數(shù)模式
        flowRule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒絕 / 慢啟動模式 / 排隊等待)椒袍,不支持按調用關系限流驹暑,不支持線程
        flowRule2.setControlBehavior(2);
        //超時時間設置
        flowRule2.setMaxQueueingTimeMs(60000);
        //組裝
        flowRules.add(flowRule2);

        /**
         * 添加限流方式
         * 2次拒絕訪問
         */
        FlowRule flowRule3 = new FlowRule();
        //資源名帆焕,資源名是限流規(guī)則的作用對象
        flowRule3.setResource("限流-2");
        //限流閾值
        flowRule3.setCount(2);
        //調用關系限流策略:直接、鏈路、關聯(lián)
        flowRule3.setStrategy(0);
        //限流閾值類型鲸沮,QPS 或線程數(shù)模式
        flowRule3.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒絕 / 慢啟動模式 / 排隊等待)炫狱,不支持按調用關系限流,不支持線程
        flowRule3.setControlBehavior(0);
        //組裝
        flowRules.add(flowRule3);

        /**
         * 添加限流方式
         * 10次等待排隊
         */
        FlowRule flowRule4 = new FlowRule();
        //資源名剔猿,資源名是限流規(guī)則的作用對象
        flowRule4.setResource("限流等待-10");
        //限流閾值
        flowRule4.setCount(10);
        //調用關系限流策略:直接视译、鏈路、關聯(lián)
        flowRule4.setStrategy(0);
        //限流閾值類型归敬,QPS 或線程數(shù)模式
        flowRule4.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //流控效果(直接拒絕 / 慢啟動模式 / 排隊等待)酷含,不支持按調用關系限流,不支持線程
        flowRule4.setControlBehavior(2);
        //超時時間設置
        flowRule4.setMaxQueueingTimeMs(60000);
        //組裝
        flowRules.add(flowRule4);

        /**
         * 添加限流方式
         * 線程最多五個
         */
        FlowRule flowRule5 = new FlowRule();
        //資源名弄慰,資源名是限流規(guī)則的作用對象
        flowRule5.setResource("線程-5");
        //限流閾值
        flowRule5.setCount(5);
        //調用關系限流策略:直接第美、鏈路、關聯(lián)
        flowRule5.setStrategy(0);
        //限流閾值類型陆爽,QPS 或線程數(shù)模式
        flowRule5.setGrade(RuleConstant.FLOW_GRADE_THREAD);
        //流控效果(直接拒絕 / 慢啟動模式 / 排隊等待)什往,不支持按調用關系限流,不支持線程
        flowRule5.setControlBehavior(0);
        //超時時間設置
        flowRule5.setMaxQueueingTimeMs(60000);
        //組裝
        flowRules.add(flowRule5);


        /**
         * 組裝限流
         */
        FlowRuleManager.loadRules(currentLimitRules(flowRules));
    }

    /**
     * 限流規(guī)則配置
     *
     * @param rules
     * @return
     */
    protected abstract List<FlowRule> currentLimitRules(List<FlowRule> rules);

}
/**
 * 自定義限流規(guī)則
 *
 * @date 2021-8-9
 */
@Configuration
public class SentinelConfig extends CustomSentinelConfig {

    @Override
    protected List<FlowRule> currentLimitRules(List<FlowRule> rules) {
        return rules;  //為了解耦慌闭,繼承默認配置别威,此處自定義增添配置
    }
}
  • 在接口上使用躯舔,注意:限流可以在方法上使用,不僅僅只針對接口
    /**
     * 下載省古、文件
     *
     * @param url
     * @param response
     */
    @SentinelResource(value = "限流-10")  //value為對應規(guī)則
    @GetMapping("/download")
    public void download(@RequestParam String url, HttpServletResponse response) throws Exception {
        new RestBeanUtil<String, String>(null)
                .build(new OnCallBeanListener<String, String>() {
                    @Override
                    public String run(String value) throws Exception {
                        try {
                            log.info("文件下載:" + url);
                            ossService.handlerDownload(url, response);
                        } catch (Exception e) {
                            e.printStackTrace();
                            MinioUtil.downLoadFail(response, e);
                        }
                        return null;
                    }
                });
    }

  • 返回規(guī)則當限流時候粥庄,需要自定義一個規(guī)則配置
/**
 * 自定義、外接哨兵異常
 *
 * @date 2021/8/9
 */
@Configuration
public class CustomBlockHandler implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        String msg = null;
        if (e instanceof FlowException) {
            //限流
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_BUSINESS));
        } else if (e instanceof DegradeException) {
            //BUSY_TOO_MANY_PEOPLE
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        } else if (e instanceof ParamFlowException) {
            //熱點參數(shù)限流
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_BUSINESS));
        } else if (e instanceof SystemBlockException) {
            //系統(tǒng)規(guī)則
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        } else if (e instanceof AuthorityException) {
            //授權規(guī)則
            msg = JSON.toJSONString(new RestBean<>(RestCodeType.BUSY_UNREACHABLE));
        }
        response.setStatus(HttpStatus.NOT_ACCEPTABLE.value());
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        response.getWriter().write(msg);
        response.getWriter().close();
    }

}


  • RestBean是自定義的restful風格實體豺妓,RestCodeType為枚舉類
    /**
     * 流量限制類
     */
    BUSY_BUSINESS(70000, "當前業(yè)務繁忙惜互,請稍后再試"),

    BUSY_UNREACHABLE(70010, "當前業(yè)務暫停,請稍后再試"),

    BUSY_TOO_MANY_PEOPLE(70020, "當前訪問人數(shù)過多琳拭,請稍后再試"),

    BUSY_IP_BAN(70030, "超出接口訪問次數(shù)训堆,請稍后再試"),

spring cloud 限流注意:框架為webflux

  • pom.xml文件配置
<!--gateway依賴,不能與web依賴放在一起-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.0.7</version>
        </dependency>

        <!--gateway與nacos獲取微服務-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
            <version>3.0.5</version>
        </dependency>

        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
            <scope>provided</scope>
        </dependency>

        <!-- 注冊中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.1</version>
        </dependency>

        <!--fastjson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

        <!--sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>

        <!--sentinel-nacos-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>1.8.3</version>
        </dependency>

        <!--sentinel-gateway 暫時不用添加白嘁,后續(xù)講解-->  
        <!--        <dependency>-->
        <!--            <groupId>com.alibaba.cloud</groupId>-->
        <!--            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>-->
        <!--            <version>2021.1</version>-->
        <!--        </dependency>-->

  • xxx.yml配置
---
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        group: remote
        namespace: b14470b8-2099-41c1-8652-8cad015b0b53


---
#限流配置
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:30010
        heartbeat-interval-ms: 5000
      datasource:
        ds1:
          nacos:
            server-addr: 127.0.0.1:8848
            dataId: sentinel-service
            groupId: sentinel
            data-type: json
            rule_type: flow
            namespace: b14470b8-2099-41c1-8652-8cad015b0b53  //看是否為個人空間坑鱼,否則去掉
      enabled: true //此處必須打開

---
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: false
          lower-case-service-id: true
      routes:   //網(wǎng)關的路由,測試使用絮缅,不成功去掉
        - id: oss-service
          uri: lb://oss
          predicates:
            - Path=/oss/**
            - Method=GET,POST


  • 打開nacos中心鲁沥,創(chuàng)建sentinel-service配置

    image.png

  • 文件配置

resource:資源名稱
limitApp:來源應用
grade:閥值類型,0---線程數(shù)耕魄,1---QPS
count:單機閥值
strategy:流控模式画恰,0---直接,1---關聯(lián)屎开,2---鏈路
controlBehavior:流控效果阐枣,0---快速失敗,1---warmUp奄抽,2---排隊等待
clusterMode:是否集群
[
    {
       "resource": "/authentication/queryUserList",
       "limitApp":"default",
       "grade":1,
       "count":1,
       "strategy":0,
       "controlBehavior":0,
       "clusterMode":false 
    },
    {
       "resource": "/main/s",
       "limitApp":"default",
       "grade":1,
       "count":1,
       "strategy":0,
       "controlBehavior":0,
       "clusterMode":false 
    }
]
  • 配置限流返回信息
@Configuration
public class SentinelHandler implements BlockRequestHandler {

    @Value("${customGateWay.sentinel.info:{\"result\":7000,\"message\":\"當前業(yè)務繁忙蔼两,請稍后再試\"}}")
    private String info;

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(Mono.just(info), String.class);
    }
}

  • 啟動項目


    image.png
image.png

spring 網(wǎng)關限流基于spring-cloud-alibaba-sentinel-gateway

  • 上面的spring cloud限流針對的是接口名稱,加上下包后逞度,將會是針對網(wǎng)關的限流
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
            <version>2021.1</version>
        </dependency>
  • 根據(jù)項目業(yè)務需求额划,看是針對單個接口限流還是某類業(yè)務限流。添加后档泽,接口限流將會失敗俊戳,二者應該是存一不兼容。

    image.png

  • 修改SentinelHandler的繼承類馆匿,否則無法正骋痔ィ回調


//import com.alibaba.csp.sentinel.adapter.spring.webflux.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;



/**
 * 限流、處理器
 *
 * @date 2022/4/6
 */
@Configuration
public class SentinelHandler implements BlockRequestHandler {

    @Value("${customGateWay.sentinel.info:{\"result\":7000,\"message\":\"當前業(yè)務繁忙渐北,請稍后再試\"}}")
    private String info;

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable throwable) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(Mono.just(info), String.class);
    }
}

注意

  • 不必要的文件不使用sentinel控制臺時阿逃,請注釋dashboard監(jiān)控,否則會產(chǎn)生大量警告日志
      transport:
#        dashboard: localhost:30010
        heartbeat-interval-ms: 5000
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恃锉,隨后出現(xiàn)的幾起案子搀菩,更是在濱河造成了極大的恐慌,老刑警劉巖破托,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肪跋,死亡現(xiàn)場離奇詭異,居然都是意外死亡土砂,警方通過查閱死者的電腦和手機州既,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萝映,“玉大人易桃,你說我怎么就攤上這事⌒烤悖” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵敌呈,是天一觀的道長贸宏。 經(jīng)常有香客問我,道長磕洪,這世上最難降的妖魔是什么吭练? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮析显,結果婚禮上鲫咽,老公的妹妹穿的比我還像新娘。我一直安慰自己谷异,他們只是感情好分尸,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著歹嘹,像睡著了一般箩绍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尺上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天材蛛,我揣著相機與錄音,去河邊找鬼怎抛。 笑死卑吭,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的马绝。 我是一名探鬼主播豆赏,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了河绽?” 一聲冷哼從身側響起己单,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耙饰,沒想到半個月后纹笼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡苟跪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年廷痘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片件已。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡笋额,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篷扩,到底是詐尸還是另有隱情兄猩,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布鉴未,位于F島的核電站枢冤,受9級特大地震影響,放射性物質發(fā)生泄漏铜秆。R本人自食惡果不足惜淹真,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望连茧。 院中可真熱鬧核蘸,春花似錦、人聲如沸啸驯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坯汤。三九已至虐唠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惰聂,已是汗流浹背疆偿。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搓幌,地道東北人杆故。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像溉愁,于是被迫代替她去往敵國和親处铛。 傳聞我的和親對象是個殘疾皇子饲趋,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361