feign 整合sentinel_双剑合璧 Nacos 结合 Sentinel 实现流量安全控制

本文详细介绍了如何将Sentinel与Feign整合,利用Nacos实现流量安全控制和熔断降级。Sentinel是一款高性能的流量控制组件,提供了丰富的流量控制策略和实时监控功能。通过Sentinel控制台,可以轻松定义和管理流量控制规则、熔断降级规则等。文中还展示了如何在Spring Cloud环境中接入Sentinel,包括配置依赖、定义资源和规则,以及测试限流和熔断效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

f5f5ba9b69164b51cf30089db20087d9.png

fcb5929e108a054c8ae77b0860265208.png

Alibaba Sentinel 是一款高性能且轻量级的流量控制、熔断降级解决方案。是面向分布式服务架构的高可用流量控制组件。

Sentinel 官网:https://sentinelguard.io/zh-cn/

Github:https://github.com/alibaba/Sentinel

Sentinel 是什么

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来保障微服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

Sentinel 主要特征

8aec6531a57cff4cdfebca9d372f72b5.png

Sentinel 开源生态

482753fe7cbf07d5b76a5c163204b3d7.png

Sentinel 目前已经针对 Servlet、Dubbo、Spring Boot/Spring Cloud、gRPC 等进行了适配,用户只需引入相应依赖并进行简单配置即可非常方便地享受 Sentinel 的高可用流量防护能力。Sentinel 还为 Service Mesh 提供了集群流量防护的能力。未来 Sentinel 还会对更多常用框架进行适配。

Sentinel 分为两个部分:

  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有 Java 运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard)基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

Sentinel 的历史

  • 2012 年,Sentinel 诞生,主要功能为入口流量控制。
  • 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
  • 2018 年,Sentinel 开源,并持续演进。
  • 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
  • 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。

Sentinel 核心

Sentinel 的使用可以分为两个部分:

  • 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。
  • 控制台(Dashboard):控制台主要负责管理推送规则、监控、集群限流分配管理、机器发现等。

Sentinel 控制台

Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。

官网文档:https://github.com/alibaba/Sentinel/wiki/控制台

获取控制台

您可以从 release 页面 下载最新版本的控制台 jar 包。

您也可以从最新版本的源码自行构建 Sentinel 控制台:

  • 下载 控制台 工程
  • 使用以下命令将代码打包成一个 fat jar: mvn clean package

启动控制台

启动命令如下,本文使用的是目前最新 1.7.2 版本:

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar
注意:启动 Sentinel 控制台需要 JDK 版本为 1.8 及以上版本。

其中 -Dserver.port=8080 用于指定 Sentinel 控制台端口为 8080

从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel。可以参考 鉴权模块文档 配置用户名和密码。

注:若您的应用为 Spring Boot 或 Spring Cloud 应用,您可以通过 Spring 配置文件来指定配置,详情请参考 Spring Cloud Alibaba Sentinel 文档。

为了方便启动,可以编写一个启动脚本 run.bat

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.7.2.jar
pause

访问

访问:http://localhost:8080/

9623e58cd7b7933e3db457f377c23edc.png

输入默认用户名和密码 sentinel 点击登录。至此控制台就安装完成了。

092aeb3accfb9a4020c94465503f83d7.png

环境准备

sentinel-demo 聚合工程。SpringBoot 2.3.0.RELEASESpring Cloud Hoxton.SR4

  • Nacos 注册中心
  • product-service:商品服务,提供了 /product/{id} 接口
  • order-service-rest:订单服务,基于 Ribbon 通过 RestTemplate 调用商品服务
  • order-server-feign:订单服务,基于 Feign 通过声明式服务调用商品服务

6640ff19ef82d73357e68f6bd2512747.png

客户端接入控制台

控制台启动后,客户端需要按照以下步骤接入到控制台:

  • 添加依赖
  • 定义资源
  • 定义规则

先把可能需要保护的资源定义好,之后再配置规则。也可以理解为,只要有了资源,我们就可以在任何时候灵活地定义各种流量控制规则。在编码的时候,只需要考虑这个代码是否需要保护,如果需要保护,就将之定义为一个资源。

由于我们的项目是 Spring Cloud 项目,所以可以借助官方文档来进行学习。

Spring 官网文档:https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html

Github 文档:https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel

添加依赖

父工程需要添加如下依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.1.0.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

子工程需要添加如下依赖:

<!-- spring cloud alibaba sentinel 依赖 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

配置文件

客户端需要启动 Transport 模块来与 Sentinel 控制台进行通信。

order-service-rest 的 application.yml

spring:
  cloud:
    # 配置 Sentinel
    sentinel:
      transport:
        port: 8719
        dashboard: localhost:8080

这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。

初始化客户端

确保客户端有访问量,Sentinel 会在客户端首次调用的时候进行初始化,开始向控制台发送心跳包。

简单的理解就是:访问一次客户端,Sentinel 即可完成客户端初始化操作,并持续向控制台发送心跳包。

访问

多次访问:http://localhost:9090/order/1 然后查看控制台实时监控结果如下:

2dc17a186f0abd10975900ee29f821d5.png

定义资源

资源 是 Sentinel 中的核心概念之一。我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。最常用的资源是我们代码中的 Java 方法。Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。

只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

官网文档:https://github.com/alibaba/Sentinel/wiki/如何使用#定义资源

注解支持

官网文档:https://github.com/alibaba/Sentinel/wiki/注解支持

OrderServiceImpl.java

package com.example.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.pojo.Order;
import com.example.service.OrderService;
import com.example.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;

@Service
public class OrderServiceImpl implements OrderService {
    
    

    @Autowired
    private ProductService productService;

    /**
     * 根据主键和订单编号查询订单
     *
     * @param id
     * @param orderNo
     * @return
     */
    @Override
    @SentinelResource(value = "selectOrderByIdAndOrderNo",
            blockHandler = "selectOrderByIdAndOrderNoBlockHandler",
            fallback = "selectOrderByIdAndOrderNoFallback")
    public Order selectOrderByIdAndOrderNo(Integer id, String orderNo) {
    
    
        return new Order(id, orderNo, "中国", 2666D,
                Arrays.asList(productService.selectProductById(1)));
    }

    // 服务流量控制处理,参数最后多一个 BlockException,其余与原函数一致。
    public Order selectOrderByIdAndOrderNoBlockHandler(Integer id, String orderNo,
                                                       BlockException ex) {
    
    
        // Do some log here.
        ex.printStackTrace();
        return new Order(id, "服务流量控制处理-托底数据", "中国", 2666D,
                Arrays.asList(productService.selectProductById(1)));
    }

    // 服务熔断降级处理,函数签名与原函数一致或加一个 Throwable 类型的参数
    public Order selectOrderByIdAndOrderNoFallback(Integer id, String orderNo,
                                                   Throwable throwable) {
    
    
        System.out.println("order-service 服务的 selectOrderById 方法出现异常,异常信息如下:"
                + throwable);
        return new Order(id, "服务熔断降级处理-托底数据", "中国", 2666D,
                Arrays.asList(productService.selectProductById(1)));
    }

}

ProductServiceImpl.java

package com.example.service.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.example.pojo.Product;
import com.example.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * 商品管理
 */
@Service
public class ProductServiceImpl implements ProductService {
    
    

    @Autowired
    private RestTemplate restTemplate;

    /**
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值