一、Sentinel概述
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
二、Sentinel 特征
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 的主要特性:
三、核心术语定义
资源:Sentinel 保护的对象,如接口方法、服务名、URL,是限流 / 熔断的最小粒度
规则:限流、熔断、热点等配置策略,如 “QPS 上限 100”“慢调用比例阈值 50%”
流量控制:限制资源的访问 QPS / 线程数,避免流量超出服务承载能力
熔断降级:当资源调用异常(慢调用、异常率高)时,暂时切断调用,避免故障扩散
热点参数限流:对资源的热点参数(如高频访问的商品 ID)单独限流,精准防护
Degrade(降级):熔断后执行的兜底逻辑,如返回默认值、缓存数据,避免返回 500 错误。
四、Sentinel 分为两个部分
核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。
在限制的手段上,Sentinel 和 Hystrix 采取了完全不一样的方法。
Hystrix 通过 线程池隔离 的方式,来对依赖(在 Sentinel 的概念中对应 资源)进行了隔离。这样做的好处是资源和资源之间做到了最彻底的隔离。缺点是除了增加了线程切换的成本(过多的线程池导致线程数目过多),还需要预先给各个资源做线程池大小的分配。
Sentinel 对这个问题采取了两种手段:
通过并发线程数进行限制和资源池隔离的方法不同,Sentinel 通过限制资源并发线程的数量,来减少不稳定资源对其它资源的影响。这样不但没有线程切换的损耗,也不需要您预先分配线程池的大小。当某个资源出现不稳定的情况下,例如响应时间变长,对资源的直接影响就是会造成线程数的逐步堆积。当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
通过响应时间对资源进行降级除了对并发线程数进行控制以外,Sentinel 还可以通过响应时间来快速降级不稳定的资源。当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
五、为什么选择 Sentinel?核心优势与应用场景
5.1 核心优势(对比 Hystrix)
轻量级高性能:核心包仅几十 KB,基于 Netty 非阻塞 IO 模型,QPS 支持可达百万级,性能远超 Hystrix
功能全面:原生支持流量控制、熔断降级、热点限流、系统保护、黑白名单等,无需额外集成插件
可视化易用:Dashboard 提供直观的规则配置、监控面板、流量监控,上手成本低
易集成:无缝适配 SpringCloud、SpringBoot、Dubbo 等主流框架,配置简单
动态灵活:支持规则动态调整(无需重启服务),支持多种规则持久化方案
社区活跃:Alibaba 官方维护,持续迭代更新,适配最新微服务生态
5.2 典型应用场景
流量削峰:秒杀、促销活动时限制并发请求,避免服务被击垮
熔断降级:下游服务故障时快速熔断,避免连锁反应,保护核心服务
热点防护:限制高频访问的热点参数(如商品 ID、用户 ID),防止缓存穿透
系统保护:监控系统 CPU、内存、负载,避免系统过载
权限控制:通过黑白名单限制 IP、用户访问,实现接口安全防护
熔断降级核心原理(状态流转)
熔断机制基于 “熔断器模式”,包含三个状态,流转逻辑如下:
闭合状态:正常放行请求,同时统计调用指标(成功率、响应时间)
打开状态:熔断触发后进入,一定时间内(如 5 秒)拒绝所有请求,执行降级逻辑
半打开状态:熔断时长到期后进入,允许少量请求尝试调用;若成功则恢复闭合,失败则重回打开
5.3 流量控制核心模式
Sentinel 支持三种流量控制模式,覆盖不同场景:
六、Docker部署 Sentinel Dashboard
可以在GitHub官方网站 Sentinel 下载源码包:
https://github.com/alibaba/Sentinel/releases
6.1 编写Dockerfile
FROM adoptopenjdk/openjdk11
MAINTAINER jackey <36944xx@qq.com>
mvn clean package
COPY ./target/sentinel-dashboard.jar sentinel-dashboard.jar
EXPOSE 8080
CMD java ${JAVA_OPTS} -jar sentinel-dashboard.jar6.2 执行Dockerfile 构建docker镜像
docker build -t wuzhixuan/sentinel-dashboard:latest .
6.3测试构建的docke镜像可行
docker run -d -p 8081:8080 --name sentinel-dashboard \
-e "JAVA_OPTS= -D server.port=8080 \
-Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dsentinel.dashboard.auth.username=sentinel \
-Dsentinel.dashboard.auth.password=sentinel \
-Dserver.servlet.session.timeout=7200" wuzhixuan/sentinel-dashboard
其实查看源文件可以设置 登录的用户名和密码 默认的用户名和密码都是sentinel
然后你就可以访问http://127.0.0.1:8081/sentinel
七、K8s部署 Sentinel Dashboard
直接使用jenkins pieline Jenkinsfile 先将docker镜像push 阿里云 容器镜像服务 仓库 然后k8s拉取容器镜像自动部署
def label = "slave-${UUID.randomUUID().toString()}"podTemplate(label: label, containers: [
containerTemplate(name: 'jdk-maven', image: 'appinair/jdk11-maven:latest', command: 'cat', ttyEnabled: true),
containerTemplate(name: 'docker', image: 'docker:latest', command: 'cat', ttyEnabled: true),containerTemplate(name: 'kubectl', image: 'cnych/kubectl', command: 'cat', ttyEnabled: true) ],
serviceAccount: 'jenkins-admin', volumes: [
hostPathVolume(mountPath: '/home/jenkins/.kube', hostPath: '/root/.kube'), hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock') ]){ node(label) {def repo = checkout scm
def gitCommit = repo.GIT_COMMIT
def gitBranch = repo.GIT_BRANCH
// 获取 git commit id 作为镜像标签
def imageTag = sh(script: "git rev-parse --short
HEAD", returnStdout: true).trim()
// 仓库地址
def registryUrl = "registry-vpc.cn-shenzhen.aliyuncs.com"
def imageEndpoint = "wuzhixuan/sentinel-dashboard"
// 镜像
def image = "${registryUrl}/${imageEndpoint}:latest" stage('单元测试') {echo"测试阶段"
}
stage('代码编译打包') { container('jdk-maven') {echo"代码编译打包阶段"
sh "mvn clean package -Dmaven.test.skip=true"
}
}
stage('构建 Docker 镜像') { withCredentials([usernamePassword(credentialsId: 'dock-auth-ali', passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USER')]) { container('docker') {echo"3. 构建 Docker 镜像阶段"
sh """
docker login ${registryUrl} -u ${DOCKER_USER} -p ${DOCKER_PASSWORD} docker build -t ${image} . docker push ${image}"""
}
}
}
stage('部署到k8s') { container('kubectl') {echo"部署到k8s集群"
sh """
sed -i 's#\$image#${image}#' deployment.yaml"""
kubernetesDeploy(enableConfigSubstitution: false,
kubeconfigId: 'kubeconfig1', configs: 'deployment.yaml')
}
}
}
}
7.2 k8s-sentinel.yaml
# 外部访问服务
apiVersion: v1
kind: Service
metadata:
namespace: kube-ops
name: sentinel
labels:
app: sentinel
spec:
ports:
- protocol: TCP
name: http
port: 8080
targetPort: 8080
nodePort: 8081
type: NodePort
selector:
app: sentinel
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sentinel
namespace: kube-ops
spec:
serviceName: sentinel
replicas: 1
template:
metadata:
labels:
app: sentinel
annotations:
pod.alpha.kubernetes.io/initialized: "true"
spec:
containers:
- name: sentinel
imagePullPolicy: Always
image: $image
resources:
limits:
memory: "1Gi"
cpu: "1"
ports:
- containerPort: 8080
name: client
env:
- name: TZ
value: Asia/Shanghai
- name: JAVA_OPTS
value: "-Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dsentinel.dashboard.auth.username=sentinel -Dsentinel.dashboard.auth.password=sentinel -Dserver.servlet.session.timeout=7200"
selector:
matchLabels:
app: sentinel







