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())
}
}