sentinel接入記錄

Doyourself!發表於2024-10-11

1.引入pom依賴

<!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

<!-- SpringCloud ailibaba sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
<dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-web-servlet</artifactId>
        </dependency>

        <!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>

        <!-- 引入 Sentinel 資料來源 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
        </dependency>
<dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-annotation-aspectj</artifactId>
    </dependency>

版本好統一按照

<version>1.8.3</version> 
為例。

2.本機啟動
首先需要再idea的啟動指令碼新增命令
-Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=專案別名

其中,-Dserver.port是自己的專案名稱,-Dcsp.sentinel.dashboard.server 是sentinel開啟控制檯的埠號,-Dproject是自己的專案名稱

3.再專案裡面使用sentinel做限流

sentinel 有兩種方式都可以做限流和降級,一種方式是直接再spring bean裡面使用fallback以及blockHandler註解,另外一種方式則是和openFeign整合。目前專案裡面使用的是第一種方式。

注意一點,使用sentinel需要相應的bean被spring容器載入進去。

@Service
public class QueryRecommentServiceImpl{

@SentinelResource(value = "queryRecommend", fallback = "getStaticData",blockHandler = "blockExceptionHandler")
    public List<String> queryRecommend(HomeRecommendStreamQuery query, HomeRecommendStreamDto streamDto, String sourceApp) {
  return null;
}



public List<String> getStaticData(HomeRecommendStreamQuery query, HomeRecommendStreamDto streamDto, String sourceApp) {
        logger.info("==========start sentinel 降級策略==========");
        try {
            Random random = new Random();
            int r = random.nextInt(100) + 1;
            logger.debug("========隨機從快取獲取一組帖子id:" + r);
            Set<String> stringSet = gwmRedisTemplate.opsForValue().get(RedisConstants.THREAD_HOT_SCORE_KEY + r);

            logger.debug("=========隨機從快取獲取帖子result=======" + JSONObject.toJSON(stringSet));
            if (CollectionUtils.isNotEmpty(stringSet)) {
                List<String> stringList = new ArrayList<>(stringSet);

                return stringList;
            } else {
                logger.debug("============讀取預設配置資料========" + config.getPostIds());
                return Optional.ofNullable(config.getPostIds()).orElse(Collections.emptyList());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * blockHandler需要設定為static
     *
     * @param ex
     * @return
     */
    public  List<String> blockExceptionHandler(HomeRecommendStreamQuery query, HomeRecommendStreamDto streamDto, String sourceApp,BlockException ex) {
        try {
            Random random = new Random();
            int r = random.nextInt(100) + 1;
            logger.debug("========隨機從快取獲取一組帖子id:" + r);
            Set<String> stringSet = gwmRedisTemplate.opsForValue().get(RedisConstants.THREAD_HOT_SCORE_KEY + r);

            logger.debug("=========隨機從快取獲取帖子result=======" + JSONObject.toJSON(stringSet));
            if (CollectionUtils.isNotEmpty(stringSet)) {
                List<String> stringList = new ArrayList<>(stringSet);

                return stringList;
            } else {
                logger.debug("============讀取預設配置資料========" + config.getPostIds());
                return Optional.ofNullable(config.getPostIds()).orElse(Collections.emptyList());
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


}

Sentinel 提供了 @SentinelResource 註解用於定義資源,並提供了 AspectJ 的擴充套件用於自動定義資源、處理 BlockException 等。使用 Sentinel Annotation AspectJ Extension 的時候需要引入以下依賴:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-annotation-aspectj</artifactId>
    <version>x.y.z</version>
</dependency>
之後再控制檯介面就可以進行設定了。
另外就是如果想要每次啟動讓sentinel生效,需要再配置一個sentienl的yaml配置,每次專案啟動可以自動生效,大概格式如下:
[
    {
        "resource":"queryRecommend",
        "controlBehavior":0,
        "count":20,
        "grade":1,
        "limitApp":"default",
        "strategy":0
    }
]

相關文章