## 一、配置中心 在[SpringCloud配置中心](https://www.soki.me/archives/366.html)中通过SpringConfig与Bus消息总线实现了应用动态配置,但需要配置的步骤过于繁琐,Nacous不仅可以用作服务注册与发现,也可以代替SpringConfig进行动态配置。 #### 1、服务端 将数据库相关的配置交给配置中心管理,修改`application.yml` ```yaml server: port: 9001 spring: application: name: order-service config: import: nacos:order-service.yaml cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml ``` 在Nacos后台新建配置`order-service.yaml` ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/order_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: auto logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 ```  #### 2、客户端 在Nacos后台新建配置`order-client.yaml` ```yaml test: name: doooog ```  在`ClientController.java`中添加测试内容 ```java @Value("${test.name}") private String name; @GetMapping("/health") public Result health() { return Result.success("order-client service is running" + name); } ``` 访问[localhost:9002/api/client/health](http://localhost:9002/api/client/health)  当Nacos后台更新配置时,客户端也会热更新  ## 二、Sentinel 功能和设计理念 在[SpringCloud延迟与容错](https://www.soki.me/archives/364.html)中说到过基于`Hystrix`限流熔断的使用,`Hystrix`是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。 `Sentinel`是阿里巴巴开源的一款断路器实现,本身在阿里内部已经被大规模采用,非常稳定。 二者主要的区别: | 特性/方面 | **Sentinel** | **Hystrix** | | :----------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | | **设计理念与侧重点** | **流量控制与系统自适应保护**。核心目标是保障微服务的稳定性,包括流量控制、熔断降级、系统自适应保护、热点参数限流等。 | **服务容错与隔离**。核心目标是防止分布式系统中的级联故障,通过熔断器模式、隔离(线程/信号量)等机制保证单个服务的故障不会蔓延。 | | **流量控制维度** | **丰富多样**。• **QPS/并发线程数**控制• **关联资源**限流• **链路**限流• **热点参数**限流(如对某个热点商品ID进行限流)• **集群模式**流量控制 | **相对简单**。主要基于**并发请求数(信号量隔离)** 或**线程池满**(线程池隔离)进行熔断,缺乏精细化的流量控制策略。 | | **熔断降级策略** | **基于响应时间、异常比例、异常数**。提供多种熔断策略,可配置在慢调用比例、异常比例或异常数量超过阈值时自动熔断。 | **基于错误百分比**。主要关注请求的失败率,当失败率超过阈值时触发熔断。 | | **实时监控与可观测性** | **非常强大**。提供开箱即用的**实时监控**控制台(Sentinel Dashboard),可以实时查看资源访问的 QPS、响应时间、熔断状态、限流情况等,并支持动态规则配置。 | **较为基础**。通过 Hystrix Dashboard 和 Turbine 提供近实时的聚合监控,主要展示熔断器状态和请求指标,但功能和易用性上不如 Sentinel。 | | **规则配置与动态性** | **支持动态配置**。规则(流控、熔断等)可以通过文件、Nacos, ZooKeeper, Apollo 等配置中心进行**动态实时推送和生效**,无需重启应用。 | **主要基于代码/静态配置**。规则通常在代码中硬编码或通过属性文件配置,**动态更新能力弱**,通常需要重启应用。 | | **隔离机制** | **信号量隔离**。默认采用轻量级的信号量隔离,开销小,性能高。也支持通过并发线程数进行隔离(类似于线程池隔离的效果,但实现更轻量)。 | **线程池隔离** 和 **信号量隔离**。默认推荐使用线程池隔离,为每个依赖服务创建一个独立的线程池,避免慢依赖占满所有容器线程,但资源开销较大。 | | **基于调用链路的限流** | **原生支持**。可以对某个API的特定入口来源进行限流,例如只限制来自某个重要入口的流量,而对其他入口不限流。 | **不支持**。 | | **系统自适应保护(特色功能)** | **支持**。从整体维度监控应用指标,如 **Load、CPU 使用率、平均响应时间、并发线程数** 等,让系统尽可能跑在最大吞吐量的同时保证系统稳定性。 | **不支持**。 | | **项目活跃度与生态** | **非常活跃**。阿里巴巴开源,是 Spring Cloud Alibaba 套件的核心组件,与云原生生态(如 Kubernetes, Dubbo, Spring Cloud)集成紧密。 | **维护模式**。Netflix 已宣布 Hystrix 进入维护模式,不再积极开发新功能。社区推荐使用 **Resilience4j** 等作为替代方案。 | | **配置方式** | **同时支持注解(如 `@SentinelResource`)和 API**,易于使用。 | **主要基于注解(如 `@HystrixCommand`)**。 | | **性能开销** | **更低**。由于其轻量级的信号量隔离和优化的实现,性能损耗非常小。 | **相对较高**。尤其是使用线程池隔离时,会带来线程上下文切换的开销。 | 使用场景选择: - Hystrix基于命令模式设计,将外部资源的调用封装在命令对象中,通过线程池或信号量来实现隔离。它提供了丰富的配置选项,如线程池大小、超时时间等,以实现对系统资源的有力控制。Hystrix更适用于需要高并发、快速响应的场景,因为它可以快速隔离和恢复故障。 - Sentinel则基于流量控制和熔断降级的思想,可以与Spring Cloud、gRPC、Dubbo等框架集成。它通过定义资源规则和应用策略来实现对系统资源的控制。Sentinel更适用于需要流量控制和熔断降级的场景,它可以根据系统负载和响应时间来实现自动熔断和降级操作。 ##### 1、流量控制 流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:  流量控制有以下几个角度: - 资源的调用关系,例如资源的调用链路,资源和资源之间的关系; - 运行指标,例如 QPS、线程池、系统负载等; - 控制的效果,例如直接限流、冷启动、排队等。 Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。 ##### 2、熔断降级 降级是当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。 降级策略包括:`返回默认值`、`提供备用数据`、`简化功能` 熔断就像电路中的保险丝短路保护电路系统一样,A服务调用B服务的某个方法,但是由于B服务的网络不稳定,导致我们整个调用链路变慢,那么这个时候我们就停止调用B服务,防止把整个系统拖垮。所以说熔断是为了防止系统因某些服务的故障而整体崩溃,类似于电路中的保险丝。在检测到下游服务异常时,自动停止向该服务发送请求,并在一定时间后**尝试恢复**。 **注意:**即使 Sentinel 实现了服务熔断,Nacos 作为服务注册和发现的组件,理论上仍然能够发现注册的服务实例,但是调用这些服务可能会失败,因为熔断机制已经介入。服务消费者需要适当地处理这种失败情况。 ## 三、熔断降级 #### 1、下载控制台 下载地址:[release 页面](https://github.com/alibaba/Sentinel/releases) 下载完成后在其所在目录运行命令,其中 `-Dserver.port=8090` 用于指定 Sentinel 控制台端口为 `8090`。 ```bash java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.9.jar ``` **注意**:Windows使用PowerShell可能会出现错误,切换成CMD即可 从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的**登录**功能,默认用户名和密码都是 `sentinel`。可以参考 [鉴权模块文档](https://sentinelguard.io/zh-cn/docs/dashboard.html#鉴权) 配置用户名和密码。  访问[Sentinel Dashboard](http://localhost:8090/#/login)  #### 2、客户端配置 ##### 添加依赖 修改`build.gralde`文件 ```groovy implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel' ``` ##### 修改配置 修改Nacos的`order-client.yaml` ```yaml spring: cloud: sentinel: transport: port: 8719 dashboard: localhost:8090 feign: sentinel: enabled: true ``` 这里的 `spring.cloud.sentinel.transport.port` 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。  ##### 修改Feign调用 修改`client/OrderClient.java` ```java import cn.doooog.common.vo.Result; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "order-service", path = "/api/orders" ,configuration = OrderClient.FeignConfiguration.class, fallback = OrderClient.OrderClientFallback.class) public interface OrderClient { @GetMapping("/{orderNo}") Result getOrderByNo(@PathVariable String orderNo); @GetMapping("/user/{userId}") Result getOrdersByUserId(@PathVariable Long userId); class FeignConfiguration { @Bean public OrderClientFallback orderClientFallback() { return new OrderClientFallback(); } } class OrderClientFallback implements OrderClient { @Override public Result getOrderByNo(@PathVariable("orderNo") String orderNo) { return Result.error("服务降级"); } @Override public Result getOrdersByUserId(@PathVariable("userId") Long userId) { return Result.error("服务降级"); } } } ``` #### 3、测试 顺序启动服务后访问:[localhost:9002/api/client/order/ORDER202501060001](http://localhost:9002/api/client/order/ORDER202501060001) 正常情况  服务端离线情况(手动关闭服务端)  ## 四、资源限流 #### 1、`@SentinelResource` 在Controller中添加`@Sentinelresource`注解来实现对某个资源(方法)的限流 ```java @GetMapping("/health") @SentinelResource(value = "health", blockHandler = "LimitResource") public Result health() { return Result.success("order-client service is running" + name); } public Result LimitResource(BlockException e) { e.printStackTrace(); return Result.error("限流了"); } ``` `value`表示要进行限流的资源名(方法名),`blockHandler`表示限流之后系统调用的方法 #### 2、设置限流 访问:[Sentinel Dashboard](http://localhost:8090/#/dashboard/flow/order-client) **注意**:Sentinel是懒加载的,也就是第一次被调用时才加载,如果没有`order-client`则访问一次接口即可   这里单机阈值设置为1,表示1s内的访问量超过一次,则会触发限流效果。系统便会执行自己设定的LimitResource方法。 正常访问  触发限流   Loading... ## 一、配置中心 在[SpringCloud配置中心](https://www.soki.me/archives/366.html)中通过SpringConfig与Bus消息总线实现了应用动态配置,但需要配置的步骤过于繁琐,Nacous不仅可以用作服务注册与发现,也可以代替SpringConfig进行动态配置。 #### 1、服务端 将数据库相关的配置交给配置中心管理,修改`application.yml` ```yaml server: port: 9001 spring: application: name: order-service config: import: nacos:order-service.yaml cloud: nacos: discovery: server-addr: localhost:8848 config: server-addr: localhost:8848 file-extension: yaml ``` 在Nacos后台新建配置`order-service.yaml` ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/order_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: id-type: auto logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 ```  #### 2、客户端 在Nacos后台新建配置`order-client.yaml` ```yaml test: name: doooog ```  在`ClientController.java`中添加测试内容 ```java @Value("${test.name}") private String name; @GetMapping("/health") public Result<String> health() { return Result.success("order-client service is running" + name); } ``` 访问[localhost:9002/api/client/health](http://localhost:9002/api/client/health)  当Nacos后台更新配置时,客户端也会热更新  ## 二、Sentinel 功能和设计理念 在[SpringCloud延迟与容错](https://www.soki.me/archives/364.html)中说到过基于`Hystrix`限流熔断的使用,`Hystrix`是由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。 `Sentinel`是阿里巴巴开源的一款断路器实现,本身在阿里内部已经被大规模采用,非常稳定。 二者主要的区别: | 特性/方面 | **Sentinel** | **Hystrix** | | :----------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | | **设计理念与侧重点** | **流量控制与系统自适应保护**。核心目标是保障微服务的稳定性,包括流量控制、熔断降级、系统自适应保护、热点参数限流等。 | **服务容错与隔离**。核心目标是防止分布式系统中的级联故障,通过熔断器模式、隔离(线程/信号量)等机制保证单个服务的故障不会蔓延。 | | **流量控制维度** | **丰富多样**。<br>• **QPS/并发线程数**控制<br>• **关联资源**限流<br>• **链路**限流<br>• **热点参数**限流(如对某个热点商品ID进行限流)<br>• **集群模式**流量控制 | **相对简单**。<br>主要基于**并发请求数(信号量隔离)** 或**线程池满**(线程池隔离)进行熔断,缺乏精细化的流量控制策略。 | | **熔断降级策略** | **基于响应时间、异常比例、异常数**。提供多种熔断策略,可配置在慢调用比例、异常比例或异常数量超过阈值时自动熔断。 | **基于错误百分比**。主要关注请求的失败率,当失败率超过阈值时触发熔断。 | | **实时监控与可观测性** | **非常强大**。提供开箱即用的**实时监控**控制台(Sentinel Dashboard),可以实时查看资源访问的 QPS、响应时间、熔断状态、限流情况等,并支持动态规则配置。 | **较为基础**。通过 Hystrix Dashboard 和 Turbine 提供近实时的聚合监控,主要展示熔断器状态和请求指标,但功能和易用性上不如 Sentinel。 | | **规则配置与动态性** | **支持动态配置**。规则(流控、熔断等)可以通过文件、Nacos, ZooKeeper, Apollo 等配置中心进行**动态实时推送和生效**,无需重启应用。 | **主要基于代码/静态配置**。规则通常在代码中硬编码或通过属性文件配置,**动态更新能力弱**,通常需要重启应用。 | | **隔离机制** | **信号量隔离**。默认采用轻量级的信号量隔离,开销小,性能高。也支持通过并发线程数进行隔离(类似于线程池隔离的效果,但实现更轻量)。 | **线程池隔离** 和 **信号量隔离**。默认推荐使用线程池隔离,为每个依赖服务创建一个独立的线程池,避免慢依赖占满所有容器线程,但资源开销较大。 | | **基于调用链路的限流** | **原生支持**。可以对某个API的特定入口来源进行限流,例如只限制来自某个重要入口的流量,而对其他入口不限流。 | **不支持**。 | | **系统自适应保护(特色功能)** | **支持**。从整体维度监控应用指标,如 **Load、CPU 使用率、平均响应时间、并发线程数** 等,让系统尽可能跑在最大吞吐量的同时保证系统稳定性。 | **不支持**。 | | **项目活跃度与生态** | **非常活跃**。阿里巴巴开源,是 Spring Cloud Alibaba 套件的核心组件,与云原生生态(如 Kubernetes, Dubbo, Spring Cloud)集成紧密。 | **维护模式**。Netflix 已宣布 Hystrix 进入维护模式,不再积极开发新功能。社区推荐使用 **Resilience4j** 等作为替代方案。 | | **配置方式** | **同时支持注解(如 `@SentinelResource`)和 API**,易于使用。 | **主要基于注解(如 `@HystrixCommand`)**。 | | **性能开销** | **更低**。由于其轻量级的信号量隔离和优化的实现,性能损耗非常小。 | **相对较高**。尤其是使用线程池隔离时,会带来线程上下文切换的开销。 | 使用场景选择: - Hystrix基于命令模式设计,将外部资源的调用封装在命令对象中,通过线程池或信号量来实现隔离。它提供了丰富的配置选项,如线程池大小、超时时间等,以实现对系统资源的有力控制。Hystrix更适用于需要高并发、快速响应的场景,因为它可以快速隔离和恢复故障。 - Sentinel则基于流量控制和熔断降级的思想,可以与Spring Cloud、gRPC、Dubbo等框架集成。它通过定义资源规则和应用策略来实现对系统资源的控制。Sentinel更适用于需要流量控制和熔断降级的场景,它可以根据系统负载和响应时间来实现自动熔断和降级操作。 ##### 1、流量控制 流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状,如下图所示:  流量控制有以下几个角度: - 资源的调用关系,例如资源的调用链路,资源和资源之间的关系; - 运行指标,例如 QPS、线程池、系统负载等; - 控制的效果,例如直接限流、冷启动、排队等。 Sentinel 的设计理念是让您自由选择控制的角度,并进行灵活组合,从而达到想要的效果。 ##### 2、熔断降级 降级是当调用链路中某个资源出现不稳定,例如,表现为 timeout,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。 降级策略包括:`返回默认值`、`提供备用数据`、`简化功能` 熔断就像电路中的保险丝短路保护电路系统一样,A服务调用B服务的某个方法,但是由于B服务的网络不稳定,导致我们整个调用链路变慢,那么这个时候我们就停止调用B服务,防止把整个系统拖垮。所以说熔断是为了防止系统因某些服务的故障而整体崩溃,类似于电路中的保险丝。在检测到下游服务异常时,自动停止向该服务发送请求,并在一定时间后**尝试恢复**。 **注意:**即使 Sentinel 实现了服务熔断,Nacos 作为服务注册和发现的组件,理论上仍然能够发现注册的服务实例,但是调用这些服务可能会失败,因为熔断机制已经介入。服务消费者需要适当地处理这种失败情况。 ## 三、熔断降级 #### 1、下载控制台 下载地址:[release 页面](https://github.com/alibaba/Sentinel/releases) 下载完成后在其所在目录运行命令,其中 `-Dserver.port=8090` 用于指定 Sentinel 控制台端口为 `8090`。 ```bash java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.9.jar ``` **注意**:Windows使用PowerShell可能会出现错误,切换成CMD即可 从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的**登录**功能,默认用户名和密码都是 `sentinel`。可以参考 [鉴权模块文档](https://sentinelguard.io/zh-cn/docs/dashboard.html#鉴权) 配置用户名和密码。  访问[Sentinel Dashboard](http://localhost:8090/#/login)  #### 2、客户端配置 ##### 添加依赖 修改`build.gralde`文件 ```groovy implementation 'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel' ``` ##### 修改配置 修改Nacos的`order-client.yaml` ```yaml spring: cloud: sentinel: transport: port: 8719 dashboard: localhost:8090 feign: sentinel: enabled: true ``` 这里的 `spring.cloud.sentinel.transport.port` 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。  ##### 修改Feign调用 修改`client/OrderClient.java` ```java import cn.doooog.common.vo.Result; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "order-service", path = "/api/orders" ,configuration = OrderClient.FeignConfiguration.class, fallback = OrderClient.OrderClientFallback.class) public interface OrderClient { @GetMapping("/{orderNo}") Result<Object> getOrderByNo(@PathVariable String orderNo); @GetMapping("/user/{userId}") Result<Object> getOrdersByUserId(@PathVariable Long userId); class FeignConfiguration { @Bean public OrderClientFallback orderClientFallback() { return new OrderClientFallback(); } } class OrderClientFallback implements OrderClient { @Override public Result<Object> getOrderByNo(@PathVariable("orderNo") String orderNo) { return Result.error("服务降级"); } @Override public Result<Object> getOrdersByUserId(@PathVariable("userId") Long userId) { return Result.error("服务降级"); } } } ``` #### 3、测试 顺序启动服务后访问:[localhost:9002/api/client/order/ORDER202501060001](http://localhost:9002/api/client/order/ORDER202501060001) 正常情况  服务端离线情况(手动关闭服务端)  ## 四、资源限流 #### 1、`@SentinelResource` 在Controller中添加`@Sentinelresource`注解来实现对某个资源(方法)的限流 ```java @GetMapping("/health") @SentinelResource(value = "health", blockHandler = "LimitResource") public Result<String> health() { return Result.success("order-client service is running" + name); } public Result<Object> LimitResource(BlockException e) { e.printStackTrace(); return Result.error("限流了"); } ``` `value`表示要进行限流的资源名(方法名),`blockHandler`表示限流之后系统调用的方法 #### 2、设置限流 访问:[Sentinel Dashboard](http://localhost:8090/#/dashboard/flow/order-client) **注意**:Sentinel是懒加载的,也就是第一次被调用时才加载,如果没有`order-client`则访问一次接口即可   这里单机阈值设置为1,表示1s内的访问量超过一次,则会触发限流效果。系统便会执行自己设定的LimitResource方法。 正常访问  触发限流   最后修改:2026 年 01 月 06 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 👆请简单粗暴地爱我。