sentinel整合openfeign实现熔断降级+nacos规则持久化

515 阅读9分钟

Sentinel是阿里巴巴开源的一款微服务流量控制组件。 是面向分布式系统轻量级流量治理框架,其核心技术围绕流量控制、熔断降级、系统负载保护等维度展开,适用于微服务架构下的高并发场景,以流量控制为切入点,保障服务稳定性。

相比Hystrix 具有以下优点:

特性SentinelHystrix
隔离策略信号量隔离(低损耗)线程池/信号量隔离
流量支持匀速排队、冷启动不支持
系统负载保护内置支持
监控平台开箱即用可视化控制台需自行整合监控系统
扩展性SPI扩展点丰富扩展依赖插件机制

OpenFeign 是一个基于 Java 声明式 HTTP 客户端框架,是 Spring Cloud 对 Feign 的增强版,支持 Spring MVC 注解。 Nacos 是阿里巴巴开源的动态服务发现、配置管理和服务管理平台,专为云原生和微服务架构设计,提供一站式解决方案。

那怎样实现sentinel与OpenFeign的整合实现,两者的整合实现服务的熔断降级,并且通过nacos实现sentinel配置持久化。本文主要介绍这一部分的实现。

一、sentinel与nacos整合实现规则持久化

1.1 jar包依赖引入

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-datasource</artifactId>
</dependency>

引入spring-cloud-starter-alibaba-sentinel sentinel组件,限流规则持久化组件(这里我们是以nacos作为持久化)sentinel-datasource-nacos, spring-cloud-alibaba-sentinel-datasource 。

1.2 Sentinel的规则持久化原因和模式选择

那为什么要持久化: 1、Sentinel 默认是将流控、熔断等规则存储在应用内存中。当应用或 Sentinel 服务重启时,内存中的规则会全部丢失。 2、持久化(如存储 Nacos等)可实现规则集中管理。修改配置后,Sentinel 客户端自动同步更新规则,避免手动维护多个实例的一致性. 3、生产环境要求配置可追溯、可回滚。

1.3 sentinel支持三种规则管理模式

1.3.1. ‌ 原始模式 (原始 API 推送)

  • 原理‌:规则通过 Sentinel 控制台直接推送到客户端内存中,不持久化存储。
  • 特点‌:    ‌优点‌:简单易用,无外部依赖。    ‌缺点‌:应用重启后规则丢失,仅适用于测试环境。

1.3.2 ‌Pull 模式 (客户端主动拉取)

  • 原理‌:客户端定时从数据源(如本地文件、数据库)读取规则并加载到内存。
  • 特点‌:    ‌持久化‌:规则存储在外部,重启后仍可恢复。    ‌灵活性‌:支持自定义数据源(需实现读/写接口)。    ‌缺点‌:实时性较差,依赖客户端定时拉取同步。

1.3.3 ‌Push 模式 (配置中心推送)

  • 原理‌:规则由 Sentinel 控制台推送到配置中心(如 Nacos、Apollo、ZooKeeper),客户端监听配置中心实时更新。
  • 特点‌:    ‌持久化 & 高实时性‌:规则集中管理,修改后秒级生效。    ‌生产推荐‌:支持灰度发布、版本回滚,保障稳定性。    ‌依赖‌:需整合配置中心组件(如 Nacos)。

我们使用push模式,通过配置中心nacos,将配置规则持久化到nacos,进而同步到sentinel。

1.4 持久化具体配置步骤

在配置文件中定义持久化规则。这里以熔断降级规则配置为例
在nacos项目文件中进行sentinel配置
spring:
    cloud:
        sentinel:
            eager: true
            transport:
                port: 8719
                dashboard: sentinel-sit.teset.com
            datasource:
                    dgrade:
                        nacos:
                            dataId: market-degrade-control
                            server-addr: ${spring.cloud.nacos.discovery.server-addr}
                            namespace: ${spring.cloud.nacos.config.namespace}
                            group-id: DEFAULT_GROUP
                            rule-type: degrade
                            data-type: json
                            data-type: json

sentinel配置项下添加datasource,在datasource下就可以添加各种流控配置,这里以熔断降级规则示例。 主要配置项说明: dgrade: 熔断管理(名称可以自定义) dataId:规则配置持久化的文件dataId username:nacos用户名 password: nacos密码 group-id:文件存放的nacos分组 rule-type:sentinel的配置规则。这里degrade指的是熔断 data-type: 存放的数据格式

同时在nacos中添加dataId声明的流控文件,如下:

图片描述

在指定的nacos分组下添加规则配置文件,文件内容就是我们要配置流控接口明细。 以我们的例子配置

[{    "resource":"/test/sentinel",    "limitApp":"default",    "grade":0,    "count":1000,    "timeWindow":10,    "minRequestAmount":1,    "statIntervalMs":2500}]

配置项说明: resource:资源名,就是熔断降级的接口名称 limitApp:针对来源,若为 default 则不区分调用来源 grade:熔断策略(0 、慢调用比例1、异常比例2、异常数) count:慢调用比例下的临界值,这里我们配置1000(1s),接口响应超过1s即认为是慢调用 timeWindow: 熔断的时长 minRequestAmount:触发熔断的最小请求数量 statIntervalMs:统计时长 slowRatioThreshold: 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)

配置完成后,在sentinel控制台就能看到我们的配置规则:

到这里持久化配置好了,那怎样才能整合feign实现流控效果呢。

接下来讲与OpenFeign整合过程。

二、sentinel整合OpenFeign

前提是项目已经引用OpenFeign实现服务间接口调用。 假设刚才我们配置服务定义为A(服务提供方),B服务(服务消费方)需要通过feign调用A的服务接口testSentinel。

2.1 A服务接口定义如下:

定义feignclient接口及fallbackfactory类名:

@FeignClient(value = "test-center", contextId = "TestSentinelApi",fallbackFactory = TestSentinelApiFactory.class)
@ResponseBody
public interface TestSentinelApi {
    @GetMapping(value = "/test/sentinel")
    String testSentinel();
}

2.2 定义接口的实现类

定义正常接口返回success

@RestController
public class TestSentinelController implements TestSentinelApi {
    @Override
    public String testSentinel() {
        return "success";
    }
}

2.3 编写接口的熔断实现类fallback,即触发降级熔断后接口的返回:

feign远程调用服务失败后,就会走降级逻辑,具体实现在fallbackFatory实现类中。 FallbackFactory接口,在泛型里指定Feign api,我们这里是TestSentinelApi。代码里返回一个实例,重新testSentinel方法。 可以这里记录日志,返回友好提示或者返回一个默认的结果,都可以。根据你的接口实现自己定义。

@Component
@Slf4j
public class TestSentinelApiFactory  implements FallbackFactory<TestSentinelApi> {
    @Override
    public TestSentinelApi create(Throwable cause) {
        return new TestSentinelApi() {
            @Override
            public String testSentinel() {
                log.error("testSentinel fallback", cause);
                return "fallback";
            }
        };
    }
}

2.4 B服务引用A服务api进行调用,我们这里返回加了固定返回格式,A的返回数据在data中,B服务调用代码如下:

@GetMapping("/testSentinel1")
@ResponseBody
public Response testSentinel(){
   //这里调用A服务api
    String s = testSentinelApi.testSentinel();
    log.info("testSentinel->:{}", s);
    return Response.buildSuccess(s);
}

2.5 修改配置文件

在服务调用方打开feign支持sentinel的配置,修改B服务的配置文件,添加启用feign sentinel的配置:

feign:
    sentinel:   
        enabled: true

2.6 调用测试验证

上面咱们配置的是熔断降级规则为例,sentinel提供了三种熔断策略:

慢调用比例 (SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。 异常比例 (ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。 异常数 (ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

这里我们通过慢调用比例来进行测试,注意慢调用比例阈值支持的版本(Sentinel 1.7.x版本无效)。

配置完成后,调用接口testSentinel,正常情况下调用B服务接口返回: image.png#729px #244px

接下来对接口进行降级熔断规则,配置降级规则后,为了验证熔断降级配置,在代码中设置随机休眠时间,以便模拟触发降级规则场景。

public class TestSentinelApiImpl implements TestSentinelApi {
@Override
public String testSentinel() {
    log.info("testSentinel");
    long start = System.currentTimeMillis();
    try {
    //休眠随机时间
        Random random = new Random();
        Thread.sleep(random.nextInt(10)*500);
    } catch (Exception e) {

    }
    log.info("end {}",System.currentTimeMillis()-start);
    return "success";
 }
}

在A服务上配置接口test/sentinel的降级规则,为了展现效果,将RT阈值设为2000ms,熔断时长配置为10s,然后频繁刷新请求接口。 ![image.png] (ossprod.jrdaimao.com/file/easyho…)

查看返回结果: image.png 触发降级。 查看sentinel控制面板,实时监控图,表明熔断降级功能已经触发,蓝色表示拒绝请求数,如下,触发降级后有10s中左右请求都会触发降级(我们配置的是10s)。 A服务接口在sentinel控制面板的实时监控: Dingtalk_20250622194047.jpg B服务的接口在sentinel控制面板实时监控:

这里我们是把降级规则配置在服务提供方的接口上,而不是配置在消费一方,也可以实现降级熔断。

下来咱们在B服务上配置降级规则,sentinel控制面板上找到B服务,点击“簇点链路“,找到testSentinel资源名,注意这里的资源名就是红框的全部了,配置如下: 配置规则如下: 其他的配置相同。再重复上面的调用步骤验证。

B服务sentinel面板上接口实时监控情况: A服务sentinel面板上接口实际监控情况: 通过观察对比,蓝线表示已经触发降级,返回fallback。

到此已经完成了sentinel与OpenFeign整合并实现熔断降级效果,并通过nacos进行持久化配置。

总结

sentinel 与openfeign整合,支持控制台实时调整规则,通过@FeignClient注解快速实现降级逻辑,与Spring Cloud Alibaba生态无缝集成,大大降低了代码开发量。集成流量控制、系统自适应保护、热点限流等功能与一体,可有效应对流量高峰、依赖服务故障、热点限流等各类生产环境的挑战。

作者:洞窝-宗望