Bootstrap

[ Spring ] Spring Cloud Alibaba Flow Limit with Sentinel 2025

Declare Plugins
pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

dependencyResolutionManagement {
    repositoriesMode = RepositoriesMode.PREFER_SETTINGS
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

buildscript {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}

plugins {
    id("org.jetbrains.kotlin.jvm") version "2.0.21" apply false
    id("org.jetbrains.kotlin.kapt") version "2.0.21" apply false
    id("org.jetbrains.kotlin.plugin.spring") version "2.0.21" apply false
    id("org.springframework.boot") version "3.4.1" apply false
}

include("sentinel-app")
Add Dependency
plugins {
    id("org.jetbrains.kotlin.jvm")
    id("org.jetbrains.kotlin.kapt")
    id("org.jetbrains.kotlin.plugin.spring")
    id("org.springframework.boot")
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

dependencies {
    val springBootVersion = "3.4.1"
    val springCloudVersion = "4.2.0"
    val springCloudAlibabaVersion = "2023.0.3.2"
    val alibabaCspVersion = "1.8.8"
    // commons
    api("io.github.hellogoogle2000:kotlin-commons:1.0.19")
    // kotlin
    api("org.jetbrains.kotlin:kotlin-reflect:2.0.21")
    // spring
    api("org.springframework.boot:spring-boot-starter:$springBootVersion")
    api("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
    api("org.springframework.cloud:spring-cloud-starter-bootstrap:$springCloudVersion")
    // spring cloud alibaba sentinel
    api("com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:$springCloudAlibabaVersion")
    api("com.alibaba.csp:sentinel-datasource-nacos:$alibabaCspVersion")
    api("com.alibaba.csp:sentinel-annotation-aspectj:$alibabaCspVersion")
}
Configure Properties
# service
server.port=10003
spring.application.name=sentinel-app
# sentinel
spring.cloud.sentinel.enabled=true
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds1.nacos.username=nacos
spring.cloud.sentinel.datasource.ds1.nacos.password=nacos
spring.cloud.sentinel.datasource.ds1.nacos.namespace=public
spring.cloud.sentinel.datasource.ds1.nacos.group-id=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.data-id=sentinel-config.json
spring.cloud.sentinel.datasource.ds1.nacos.data-type=json
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=flow
Add Config File to Nacos Server

config file should be named to sentinel-config.json

http://localhost:8848/nacos
[
    {
       "resource": "upgrade",
       "grade": 0,
       "count": 1,
       "strategy": 0
	}
]

grade=0 means limit by thread count

count=0 represent thread count

strategy=0 means count by current resource only

Sentinel Application
package x.spring.hello

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class SentinelApplication

fun main(args: Array<String>) {
    runApplication<SentinelApplication>(*args)
}
Sentinel Controller
package x.spring.hello.controller

import com.alibaba.csp.sentinel.annotation.SentinelResource
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@RestController
class UpgradeController {

    @GetMapping("upgrade")
    @SentinelResource("upgrade")
    fun upgrade(): String {
        Thread.sleep(3000)
        return "upgraded"
    }
}
Sentinel Blocking Handler
package x.spring.hello.component

import com.alibaba.csp.sentinel.slots.block.flow.FlowException
import jakarta.servlet.http.HttpServletResponse
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice

@RestControllerAdvice
class SentinelBlockingHandler {

    @ExceptionHandler(FlowException::class)
    fun handle(response: HttpServletResponse, e: FlowException) {
        response.status = HttpStatus.TOO_MANY_REQUESTS.value()
        response.contentType = MediaType.TEXT_PLAIN.type
        response.outputStream.write("TOO_MANY_REQUESTS".toByteArray())
    }
}
;