一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - zuul集成Sentinel,完成對path映射的限流操作

zuul集成Sentinel,完成對path映射的限流操作

2021-09-14 13:36天涯淚小武 Java教程

這篇文章主要介紹了zuul集成Sentinel,完成對path映射的限流操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

zuul集成Sentinel完成對path映射的限流

前面我們講過了對單體應用的Sentinel限流,以及使用zookeeper對規則的持久化。通過前面的工作,我們可以完成單個實例的細粒度的限流、熔斷操作。

譬如有一個服務User,在分布式環境下,開啟了多個實例,那么每個實例都可以獲得如每秒限制10個登錄的限流功能。但是有些場景下,我們想要另外一種限流方式,譬如在網關zuul層,想限制對User服務的限流,而不去關心具體它有多少個實例。這時,就需要用到網關限流了。

Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模塊,包含網關限流的規則和自定義 API 的實體和管理邏輯:

GatewayFlowRule:網關限流規則,針對 API Gateway 的場景定制的限流規則,可以針對不同 route 或自定義的 API 分組進行限流,支持針對請求中的參數、Header、來源 IP 等進行定制化的限流。

ApiDefinition:用戶自定義的 API 定義分組,可以看做是一些 URL 匹配的組合。比如我們可以定義一個 API 叫 my_api,請求 path 模式為 /foo/** 和 /baz/** 的都歸到 my_api 這個 API 分組下面。

限流的時候可以針對這個自定義的 API 分組維度進行限流。

注意這個版本,1.6.0以后才有的。

zuul集成Sentinel,完成對path映射的限流操作

我們直接上代碼,進入實戰。新建一個SpringCloud項目,選中zuul。并在啟動類上加上@EnableZuulProxy注解,代表這是一個zuul網關項目。

pom.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sentinelzuul</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sentinelzuul</name>
    <description>Demo project for Spring Boot</description>
 
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
        <sentinel.version>1.6.1</sentinel.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
        <!--<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-zookeeper</artifactId>
        </dependency>-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-zuul-adapter</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
 
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-parameter-flow-control</artifactId>
            <version>${sentinel.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
 
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>0.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

官方文檔上寫,只需要引入sentinel-zuul-adapter依賴,實測后發現,只引入這個的話,所依賴的Sentinel-core是1.5.2版本,會導致啟動失敗。所以我手工加入了其他幾個依賴。

yml文件如下:

server:
  port: 9999
zuul:
  routes:
    one:
      path: /baoban/**
      url: http://localhost:8888/baoban/
spring:
  application:
    name: sentinelzuul

這里配了一個簡單的routes映射。那是另外一個本地服務。

使用zuul的限流很簡單,2個類即可

ZuulConfig.java

import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulErrorFilter;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPostFilter;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter;
import com.netflix.zuul.ZuulFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
 * @author wuweifeng wrote on 2019/7/3.
 */
@Configuration
public class ZuulConfig {
 
    @Bean
    public ZuulFilter sentinelZuulPreFilter() {
        return new SentinelZuulPreFilter(10000);
    }
 
    @Bean
    public ZuulFilter sentinelZuulPostFilter() {
        return new SentinelZuulPostFilter(1000);
    }
 
    @Bean
    public ZuulFilter sentinelZuulErrorFilter() {
        return new SentinelZuulErrorFilter(-1);
    }
}
package com.example.sentinelzuul.config; 
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.slots.block.RuleConstant;
import org.springframework.context.annotation.Configuration; 
import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.Set;
 
/**
 * @author wuweifeng wrote on 2019/7/3.
 */
@Configuration
public class GatewayRuleConfig {
    private static final int URL_MATCH_STRATEGY_EXACT = 0;
    private static final int URL_MATCH_STRATEGY_PREFIX = 1;
    private static final int URL_MATCH_STRATEGY_REGEX = 2;
 
    @PostConstruct
    public void doInit() {
        // Prepare some gateway rules and API definitions (only for demo).
        // It"s recommended to leverage dynamic data source or the Sentinel dashboard to push the rules.
        initCustomizedApis();
        initGatewayRules();
    }
 
    private void initCustomizedApis() {
        Set<ApiDefinition> definitions = new HashSet<>();
        ApiDefinition api1 = new ApiDefinition("baobao_api")
                .setPredicateItems(new HashSet<ApiPredicateItem>() {{
                    //add(new ApiPathPredicateItem().setPattern("/ahas"));
                    add(new ApiPathPredicateItem().setPattern("/baoban/**")
                            .setMatchStrategy(URL_MATCH_STRATEGY_PREFIX));
                }});
        //ApiDefinition api2 = new ApiDefinition("another_customized_api")
        //        .setPredicateItems(new HashSet<ApiPredicateItem>() {{
        //            add(new ApiPathPredicateItem().setPattern("/**")
        //                    .setMatchStrategy(URL_MATCH_STRATEGY_PREFIX));
        //        }});
        definitions.add(api1);
        //definitions.add(api2);
        GatewayApiDefinitionManager.loadApiDefinitions(definitions);
    }
 
    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();
        rules.add(new GatewayFlowRule("baobao_api")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                .setCount(1)
                .setIntervalSec(1)
        );
        rules.add(new GatewayFlowRule("aliyun-product-route")
                .setCount(2)
                .setIntervalSec(2)
                //應對突發請求時額外允許的請求數目。
                .setBurst(2)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)
                )
        );
        rules.add(new GatewayFlowRule("another-route-httpbin")
                .setCount(10)
                //統計時間窗口,單位是秒,默認是 1 秒。
                .setIntervalSec(1)
                //流量整形的控制效果,同限流規則的 controlBehavior 字段,目前支持快速失敗和勻速排隊兩種模式,默認是快速失敗。
                .setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
                //勻速排隊模式下的最長排隊時間,單位是毫秒,僅在勻速排隊模式下生效。
                .setMaxQueueingTimeoutMs(600)
                //參數限流配置
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
                        .setFieldName("X-Sentinel-Flag")
                )
        );
        rules.add(new GatewayFlowRule("another-route-httpbin")
                .setCount(1)
                .setIntervalSec(1)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        .setFieldName("pa")
                )
        );
 
        rules.add(new GatewayFlowRule("some_customized_api")
                .setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
                .setCount(5)
                .setIntervalSec(1)
                .setParamItem(new GatewayParamFlowItem()
                        .setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
                        .setFieldName("pn")
                )
        );
        GatewayRuleManager.loadRules(rules);
 
        //監聽zookeeper,使用zookeeper的規則
        //ReadableDataSource<String, Set<GatewayFlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(null, null,
        //        source -> JSON.parseObject(source, new TypeReference<Set<GatewayFlowRule>>() {
        //        }));
        //GatewayRuleManager.register2Property(flowRuleDataSource.getProperty());
    }
}

主要做的有2件事

1是配置一下APIDefinition,也就是給自己的映射規則起個名字。

2是配置Rule,和之前的配置rule差不多。創建一個rule的集合,設置rule規則,具體規則各字段在上面截圖中有解釋。

zuul集成Sentinel,完成對path映射的限流操作

這里我配了一個簡單的一秒1個QPS的規則。最后用GatewayRuleManager去loadRules即可。

之后測試一下就發現規則已生效。頻繁訪問被限流的服務時,會報下面的異常。

zuul集成Sentinel,完成對path映射的限流操作

如果你想自定義這個熔斷的返回值的話,可以加個類實現ZuulBlockFallbackProvider:

import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.BlockResponse;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.DefaultBlockFallbackProvider;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.ZuulBlockFallbackProvider;
import com.alibaba.csp.sentinel.log.RecordLog;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
/**
 * @author wuweifeng wrote on 2019/7/3.
 */
public class MyBlockFallbackProvider implements ZuulBlockFallbackProvider {
 
    private Logger logger = LoggerFactory.getLogger(DefaultBlockFallbackProvider.class);
 
    // you can define route as service level
    @Override
    public String getRoute() {
        return "baobao_api";
    }
 
    @Override
    public BlockResponse fallbackResponse(String route, Throwable cause) {
        RecordLog.info(String.format("[Sentinel DefaultBlockFallbackProvider] Run fallback route: %s", route));
        if (cause instanceof BlockException) {
            return new BlockResponse(429, "the route is blocked", route);
        } else {
            return new BlockResponse(500, "System Error", route);
        }
    }
}

getRoute方法返回的就是上面定義的resouceName。然后注冊一下就好了。

zuul集成Sentinel,完成對path映射的限流操作

zuul集成Sentinel,完成對path映射的限流操作

當然這也是基于內存的規則,不能動態改變,在實際生產中,如果需要動態改變規則的話,還是需要去用zookeeper之類的。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://tianyalei.blog.csdn.net/article/details/94577775

延伸 · 閱讀

精彩推薦
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7472021-02-04
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
主站蜘蛛池模板: 1024免费观看完整版在线播放 | 大吊操 | 91香蕉视频在线观看 | 亚洲天堂.com| 国产日韩精品欧美一区 | 爱爱小说漫画 | 亚洲人影院 | 爱情岛永久成人免费网站 | 干b视频在线观看 | 午夜在线观看视频 | 调教开发新婚娇妻放荡 | 久久两性视频 | 欧美免赞性视频 | 男人猛戳女人下部30分钟 | 日本高清中文字幕 | 免费真实播放国产乱子伦 | 天天干夜夜添 | 成人精品在线 | 日本三级大学生17 | 国产日本欧美亚洲精品视 | 双性肉文高h | 色天天综合色天天碰 | 91麻豆精品国产自产在线观看 | 激情五月开心 | 美女尿口羞羞视频 | porno美国xxxx| 男人添女人 | 亚洲成人免费 | 欧美肥胖老妇做爰变态 | 99re在线视频免费观看 | 白丝校花好湿好紧 | 99久久99热久久精品免 | 美女黄金大片视频免费看 | 视频免费观看在线播放高清 | 国产三区二区 | 国产码一区二区三区 | 国产亚洲综合成人91精品 | 天天操天天做 | 国产精品视频一区二区三区 | 歪歪漫画a漫入口 | 亚洲春黄在线观看 |