【PmHub后端篇】PmHub集成 Sentinel+OpenFeign实现网关流量控制与服务降级

news2025/5/15 6:35:02

在微服务架构中,保障服务的稳定性和高可用性至关重要。本文将详细介绍在 PmHub 中如何利用 Sentinel + Gateway 进行网关限流,以及集成 Sentinel + OpenFeign 实现自定义的 fallback 服务降级。

1 熔断降级的必要性

在微服务架构中,服务间的调用错综复杂。一个服务可能会调用远程服务、数据库或第三方 API,例如支付时调用银联 API、查询商品价格时访问数据库等。然而,依赖的服务稳定性不可控,若其出现不稳定情况,请求响应时间过长,调用服务的方法会阻塞,耗尽业务线程资源,最终导致服务不可用。为避免这种情况,对不稳定的弱依赖服务调用进行熔断降级是保障高可用的重要措施。

2 Sentinel 的发展历史

早些年,Netflix 的 Hystrix 是熔断降级的热门组件,但在 2018 年底 Netflix 宣布不再维护它。此后,阿里巴巴开源的 Sentinel 成为了不错的替代产品。此外,Resilience4J 也是 Hystrix 官方推荐的替代产品,具有轻量、简单、文档清晰丰富的特点。Sentinel 是面向分布式的流量治理组件,以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、自适应过载保护、热点流量防护等多个维度保障微服务的稳定性。Sentinel 自 2012 年诞生,历经多次版本更新。

在这里插入图片描述

3 Sentinel 的基本概念

  • 资源
    资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文档中,我们都会用资源来描述代码块。

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

  • 规则
    围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整。

4 Sentinel 的原理

在 Sentinel 中,所有资源对应一个资源名称和一个 Entry。Entry 可通过对主流框架的适配自动创建,也可通过注解或调用 API 显式创建。每个 Entry 创建时,会同时创建一系列功能插槽(slot chain)。

这些插槽有不同的职责,例如:

  • NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;
  • ClusterBuilderSlot 则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;
  • StatisticSlot 则用于记录、统计不同纬度的 runtime 指标监控信息;
  • FlowSlot 则用于根据预设的限流规则以及前面 slot 统计的状态,来进行流量控制;
  • AuthoritySlot 则根据配置的黑白名单和调用来源信息,来做黑白名单控制;
  • DegradeSlot 则通过统计信息以及预设的规则,来做熔断降级;
  • SystemSlot 则通过系统的状态,例如 load1 等,来控制总的入口流量;

总体的框架如下:
在这里插入图片描述

Sentinel 将 ProcessorSlot 作为 SPI 接口进行扩展(1.7.2 版本以前 SlotChainBuilder 作为 SPI),使 Slot Chain 具备扩展能力,可加入自定义 slot 并编排顺序,为 Sentinel 添加自定义功能。
在这里插入图片描述

5 Sentinel 的下载和使用

5.1 下载Sentinel

  • 下载地址:https://github.com/alibaba/Sentinel/releases
  • 官方参考文档地址:https://sentinelguard.io/zh-cn/docs/quick-start.html

在这里插入图片描述

5.2 启动Sentinel

Sentinel 控制台的运行依赖 JDK 1.8 及以上版本,在搭建环境前需确保本地已安装符合要求的 JDK。

Sentinel 控制台本质上是一个可执行的 jar 包,使用 Java 命令即可运行。在启动前,需要确认默认端口 8080 是否被占用,可通过以下命令进行查看:

linux版:lsof -i :8080
windows版:netstat -ano | findstr "8080"

若命令执行后无任何输出,表明 8080 端口未被占用,可直接使用以下命令启动 Sentinel 控制台:

java -jar sentinel-dashboard-1.8.7.jar

若 8080 端口已被占用,则需切换至其他端口,例如 8081,启动命令如下:

java -jar sentinel-dashboard-1.8.7.jar --server.port=8081

当控制台输出类似 “Starting DashboardApplication using Java” 等相关信息时,即表明 Sentinel 控制台启动成功。
在这里插入图片描述

5.3 访问管理界面​

启动成功后,可通过浏览器访问 Sentinel 管理界面,若使用默认 8080 端口,访问地址为 http://localhost:8080;若使用 8081 端口,则访问地址为 http://localhost:8081。默认的登录账号和密码均为 “sentinel”,登录后即可进入 Sentinel 控制台管理界面。
在这里插入图片描述
在这里插入图片描述

5.4 功能验证

为验证 Sentinel 环境搭建是否成功,可编写测试用例进行验证。

5.4.1 引入依赖​

在项目的 pom.xml 文件中引入 Sentinel 的核心依赖:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.8.6</version>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.8.6</version>
</dependency>

其中,sentinel-core 为 Sentinel 的核心包,sentinel-transport-simple-http 用于实现与控制台的连通。

5.4.2 编写测试代码​

新建一个测试类,示例代码如下:

class Demo {
    public static void main(String[] args) {
        // 配置规则
        initFlowRules();
        while (true) {
            // 1.5.0版本开始可以直接利用try-with-resources特性
            try (Entry entry = SphU.entry("HelloWorld")) {
                // 被保护的逻辑
                System.out.println("hello world");
            } catch (BlockException ex) {
                // 处理被流控的逻辑
                System.out.println("blocked!");
            }
        }
    }

    private static void initFlowRules() {
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置QPS限制为20
        rule.setCount(20);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}

上述代码通过 initFlowRules 方法配置了流量控制规则,将 “HelloWorld” 资源的 QPS 限制为 20,在 main 方法中通过 SphU.entry 方法尝试进入资源保护块,若超出流量限制,则会捕获 BlockException 并执行相应的处理逻辑。

5.4.3 运行测试​

以 debug 模式运行上述测试类,在控制台可观察到输出信息。
在这里插入图片描述

当循环次数达到 21 次时,由于超出了设定的 QPS 限制,将进入 BlockException 处理逻辑,输出 “blocked!”,这表明 Sentinel 的流量控制功能已正常生效,至此,PmHub 中 Sentinel 环境搭建成功。
在这里插入图片描述

6 Sentinel 配合 Gateway 实现网关限流

Sentinel 支持对 Spring Cloud Gateway、Zuul 等主流的 API Gateway 进行限流。在 1.6.0 版本,Sentinel 提供了 Gateway 的适配模块,支持两种维度的限流:

  1. route 维度:在配置文件中配置路由条目,资源名为对应的 routeId,常用于对某个微服务进行限流,PmHub 主要使用该维度。
  2. 自定义 API 维度:利用 Sentinel 提供的 API 自定义一些 API 分组,可针对 URI 进行限流,跨多个服务。

具体实现步骤如下:

6.1 引入 Sentinel 依赖

在需要 Sentinel 的微服务中引入 Sentinel 依赖,可在 PmHub 中搜索 alibaba-sentinel 关键字查看。

<!-- SpringCloud Alibaba Sentinel 核心依赖-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- SpringCloud Alibaba Sentinel Gateway,如果不是gateway可以不用引入 -->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

<!-- Sentinel Datasource Nacos 用来做持久化存储-->
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

6.2 修改 yml 配置

在 pmhub-gateway 的服务配置 bootstrap.yml 中,增加 Sentinel 的配置。其中

  • eager 用于取消控制台的懒加载;
  • dashboard 为 Sentinel 控制台地址;
  • port 为 Sentinel 客户端与 Sentinel 控制台通信的端口,用于上报网关的流量数据、接收动态规则配置、进行心跳检测等。
    在这里插入图片描述

6.3 使用 Nacos 对 Sentinel 进行持久化配置

Sentinel 的配置默认放在内存中,服务重启后配置会丢失。使用 Nacos 进行持久化配置,若 Nacos 已启动,可在 Nacos 的控制台找到 sentinel-pmhub-gateway
在这里插入图片描述
在这里插入图片描述

6.4 在 Sentinel 控制台查看 Gateway 的流量规则

在这里插入图片描述
Sentinel 之所以能够对流量进行控制,是因为它会监控应用的 QPS 流量或者并发线程数等指标,如果达到指定的阈值,就会进行流量控制,避免服务被瞬时的高并发流量击垮,从而保证服务的可靠性。

QPS 即每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。即每秒的响应请求数,也就是最大吞吐能力。

这里以 pmhub-gateway 网关流控规则为例:
在这里插入图片描述

在这里插入图片描述
这里 pmhub-system 配置的 1000,代表每秒最多可以处理 1000 个请求。

7 Sentinel 配合 OpenFeign 实现自定义 fallback 服务降级

7.1 @SentinelResource 注解

@SentinelResource 是 Sentinel 中重要的注解,能在代码层面对资源进行保护,结合控制台的规则配置,实现高效的限流与降级策略。

例如,在 PmHub 的系统服务中,可为获取用户信息的接口加上@SentinelResource 注解,blockHandler 参数用于限流,fallback 参数用于降级处理。

代码路径:com.laigeoffer.pmhub.system.controller.SysUserController#info

/**
 * 根据用户名获取当前用户信息
 */
@InnerAuth
@GetMapping("/info/{username}")
@SentinelResource(value = "infoSentinelResource",blockHandler = "handlerBlockHandler", fallback = "doActionFallback") // 演示SentinelResource细粒度管控服务流控和降级
public R<LoginUser> info(@PathVariable("username") String username) {
    SysUser sysUser = userService.selectUserByUserName(username);
    if (StringUtils.isNull(sysUser)) {
        return R.fail("用户名或密码错误");
    }
    // 角色集合
    Set<String> roles = permissionService.getRolePermission(sysUser);
    // 权限集合
    Set<String> permissions = permissionService.getMenuPermission(sysUser);
    LoginUser loginUser = new LoginUser();
    loginUser.setUser(sysUser);
    loginUser.setRoles(roles);
    loginUser.setPermissions(permissions);
    loginUser.setUserId(sysUser.getUserId());
    loginUser.setDeptId(sysUser.getDeptId());
    loginUser.setNickName(sysUser.getNickName());


    return R.ok(loginUser);
}

来看一下登录接口涉及到的服务交互,用户发起请求,网关服务(pmhub-gateway)接收到后进行服务转发,转发到认证服务(pmhub-auth),认证服务调用系统服务(pmhub-system)获取用户。
在这里插入图片描述

7.2 fallback 服务降级

fallback 服务降级是指当调用一个服务出现异常时,给访问者一个友好的反馈,降低服务负载,避免因异常请求引发其他服务崩溃。

7.3 通过 OpenFeign 进行过渡降级处理

对于用户的登录请求,认证服务不直接调用系统服务,PmHub 抽离出公共包 pmhub-api,将用户接口统一放入,认证服务通过 OpenFeign 调用系统服务,并在 pmhub-api 服务中进行统一的服务降级。
在这里插入图片描述

7.3.1 OpenFeign的概念

OpenFeign 是一个 声明式 HTTP 客户端,用于在 Spring Cloud 微服务架构 中简化服务之间的通信。它提供了一种声明式的方式来定义和调用 HTTP 服务,我们开发者无需手动构建 HTTP 请求,就能轻松实现服务调用。

7.3.2 具体实现步骤

  1. 使用 @FeignClient 注解:在 UserFeignService 中,在 @FeignClient 注解上添加自定义的 fallbackFactory
    代码路径:com.laigeoffer.pmhub.api.system.UserFeignService
@FeignClient(contextId = "userFeignService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = UserFeginFallbackFactory.class)
public interface UserFeignService {


    /**
     * 根据用户名获取当前用户信息
     */
    @GetMapping("/system/user/info/{username}")
    R<LoginUser> info(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

    /**
     * 根据 userId 获取用户信息
     */
    @GetMapping("/system/user/getInfoByUserId/{userId}")
    R<LoginUser> getInfoByUserId(@PathVariable("userId") Long userId, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);

    /**
     * 根据条件获取用户列表
     */
    @PostMapping("/system/user/listOfInner")
    R<List<SysUserVO>> listOfInner(@RequestBody SysUserDTO sysUserDTO, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);


    /**
     * 注册用户信息
     *
     * @param sysUser 用户信息
     * @param source 请求来源
     * @return 结果
     */
    @PostMapping("/system/user/register")
    R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
  1. 创建 UserFeginFallbackFactory:进行自定义的降级处理,在 FallbackFactory 中,不仅能捕获异常进行处理,还能通过 Throwable 获取详细的异常信息,处理复杂的限流逻辑。
    代码路径:com.laigeoffer.pmhub.api.system.factory.UserFeginFallbackFactory
@Component
public class UserFeginFallbackFactory implements FallbackFactory<UserFeignService>
{
    private static final Logger log = LoggerFactory.getLogger(UserFeginFallbackFactory.class);

    @Override
    public UserFeignService create(Throwable throwable)
    {
        log.error("用户服务调用失败:{}", throwable.getMessage());
        return new UserFeignService()
        {

            @Override
            public R<LoginUser> info(String username, String source) {
                return R.fail("根据用户名获取用户失败:" + throwable.getMessage());
            }

            @Override
            public R<LoginUser> getInfoByUserId(Long userId, String source) {
                return R.fail("根据userId获取用户失败:" + throwable.getMessage());
            }

            @Override
            public R<List<SysUserVO>> listOfInner(SysUserDTO sysUserDTO, String source) {
                return R.fail("根据调教获取用户列表失败:" + throwable.getMessage());
            }

            @Override
            public R<Boolean> registerUserInfo(SysUser sysUser, String source) {
                return R.fail("注册用户失败:" + throwable.getMessage());
            }

        };
    }
}

8 总结

本文围绕 PmHub,介绍 Sentinel 在微服务架构中熔断降级的必要性、基本概念、原理等,阐述其下载使用方法,以及配合 Gateway 实现网关限流、配合 OpenFeign 实现自定义 fallback 服务降级,助力开发者保障微服务架构稳定性。

9 参考链接

  1. PmHub集成 Sentinel+OpenFeign实现网关流量控制,以及自定义fallback服务降级
  2. 项目仓库(GitHub)
  3. 项目仓库(码云): (国内访问速度更快)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2375875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2025最新出版 Microsoft Project由入门到精通(八)

目录 查找关键路径方法 方法1:格式->关键任务 方法2:插入关键属性列 方法3&#xff1a;插入“可宽延的总时间”进行查看&#xff0c;>0不是关键路径&#xff0c;剩余的全是关键路径 方法4:设置关键路径的工作表的文本样式​编辑 方法5&#xff1a;突出显示/筛选器…

3.0/Q2,Charls最新文章解读

文章题目&#xff1a;Development of a visualized risk prediction system for sarcopenia in older adults using machine learning: a cohort study based on CHARLS DOI&#xff1a;10.3389/fpubh.2025.1544894 中文标题&#xff1a;使用机器学习开发老年人肌肉减少症的可视…

使用matlab进行数据拟合

目录 一、工作区建立数据 二、曲线拟合器(在"APP"中) 三、曲线拟合函数及参数 四、 在matlab中编写代码 一、工作区建立数据 首先&#xff0c;将数据在matlab工作区中生成。如图1所示&#xff1a; 图 1 二、曲线拟合器(在"APP"中) 然后&#xff0c;…

分布式1(cap base理论 锁 事务 幂等性 rpc)

目录 分布式系统介绍 一、定义与概念 二、分布式系统的特点 三、分布式系统面临的挑战 四、分布式系统的常见应用场景 CAP 定理 BASE 理论 BASE理论是如何保证最终一致性的 分布式锁的常见使用场景有哪些&#xff1f; 1. 防止多节点重复操作 2. 资源互斥访问 3. 分…

Myshell与清华联合开源TTS模型OpenVoiceV2,多语言支持,风格控制进一步增强~

项目背景 开发团队与发布 OpenVoice2 由 MyShell AI&#xff08;加拿大 AI 初创公司&#xff09;与 MIT 和清华大学的研究人员合作开发&#xff0c;技术报告于 2023 年 12 月发布 &#xff0c;V2 版本于 2024 年 4 月发布 。 项目目标是提供一个高效、灵活的语音克隆工具&…

YOLO11解决方案之热力图探索

概述 Ultralytics提供了一系列的解决方案,利用YOLO11解决现实世界的问题,包括物体计数、模糊处理、热力图、安防系统、速度估计、物体追踪等多个方面的应用。 使用YOLO11生成的热力图把复杂的数据转换成生动的彩色编码矩阵。这种可视化工具采用色谱来表示不同的数据值,暖色…

如何在终端/命令行中把PDF的每一页转换成图片(PNG)

今天被对象安排了一个任务&#xff1a; 之前自己其实也有这个需要&#xff0c;但是吧&#xff0c;我懒&#xff1a;量少拖拽&#xff0c;量大就放弃。但这次躲不过去了&#xff0c;所以研究了一下有什么工具可以做到这个需求。 本文记录我这次发现的使用 XpdfReader 的方法。…

计算机系统结构——Cache性能分析

一、实验目的 加深对Cache的基本概念、基本组织结构以及基本工作原理的理解。掌握Cache容量、相联度、块大小对Cache性能的影响。掌握降低Cache不命中率的各种方法以及这些方法对提高Cache性能的好处。理解LRU与随机法的基本思想以及它们对Cache性能的影响。 二、实验平台 实…

GESP2023年12月认证C++八级( 第三部分编程题(2)大量的工作沟通)

参考程序&#xff1a; #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <string> #include <map> #include <iostream> #include <cmath> #include <vector> #include <qu…

015枚举之滑动窗口——算法备赛

滑动窗口 最大子数组和 题目描述 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 原题链接 思路分析 见代码注解 代码 int maxSubArray(vector<int>& num…

新型深度神经网络架构:ENet模型

语义分割技术能够为图像中的每个像素分配一个类别标签&#xff0c;这对于理解图像内容和在复杂场景中找到目标对象至关重要。在自动驾驶和增强现实等应用中&#xff0c;实时性是一个硬性要求&#xff0c;因此设计能够快速运行的卷积神经网络非常关键。 尽管深度卷积神经网络&am…

【免杀】C2免杀技术(三)shellcode加密

前言 shellcode加密是shellcode混淆的一种手段。shellcode混淆手段有多种&#xff1a;加密&#xff08;编码&#xff09;、偏移量混淆、UUID混淆、IPv4混淆、MAC混淆等。 随着杀毒软件的不断进化&#xff0c;其检测方式早已超越传统的静态特征分析。现代杀软往往会在受控的虚…

WPF之集合绑定深入

文章目录 引言ObservableCollection<T>基础什么是ObservableCollectionObservableCollection的工作原理基本用法示例ObservableCollection与MVVM模式ObservableCollection的局限性 INotifyCollectionChanged接口深入接口定义与作用NotifyCollectionChangedEventArgs详解自…

(C语言)超市管理系统(测试2版)(指针)(数据结构)(清屏操作)

目录 前言&#xff1a; 源代码&#xff1a; product.h product.c fileio.h fileio.c main.c 代码解析&#xff1a; 一、程序结构概述 二、product.c 函数详解 1. 初始化商品列表 Init_products 2. 添加商品 add_product 3. 显示商品 display_products 4. 修改商品 mo…

编译openssl源码

openssl版本 1.1.1c windows 安装环境 perl 先安装perl&#xff0c;生成makefile需要 https://strawberryperl.com/releases.html nasm nasm 也是生成makefile需要 https://www.nasm.us/ 安装完perl输入一下nasm&#xff0c;看看能不能找到&#xff0c;找不到的话需要配…

OpenCV实现数字水印的相关函数和示例代码

OpenCV计算机视觉开发实践&#xff1a;基于Qt C - 商品搜索 - 京东 实现数字水印的相关函数 用OpenCV来实现数字水印功能&#xff0c;需要使用一些位操作函数&#xff0c;我们需要先了解一下这些函数。 1. bitwise_and函数 bitwise_and函数是OpenCV中的位运算函数之一&…

坐席业绩数据分析

豆包提示词&#xff1a; 使用papaparse.js&#xff0c;chart.js&#xff0c;tailwindcss和font-awesome&#xff0c;生成一个可以交互的简洁且可以运行的HTML代码&#xff0c;不要输出无关内容。 具体要求如下&#xff1a; 1、按坐席姓名输出业绩折线图。 2、系统导航区域&…

怎样将MM模块常用报表设置为ALV默认格式(MB52、MB5B、ME2M、ME1M等)

【SAP系统研究】 对SAP系统中的报表,最方便的格式就是ALV了,可排序、可导出,非常友好。 但有些常见报表却不是默认ALV界面的,譬如MB52: 是不是有点别扭?但其实是可以后台配置进行调整的。 现将一些常用报表修改为默认ALV的方法进行总结,便于大家使用。 一、MB52、MB5…

Arduino使用红外收发模块

目录 Arduino UNO连接红外发射模块&#xff1a; Arduino D1连接红外接收模块&#xff1a; 有一个Arduini UNO板子和一个Arduino D1板子&#xff0c;我想通过红外发射模块和红外接收模块让他们进行通信。 先看结果&#xff1a; Arduino UNO连接红外发射模块&#xff1a; 发射模…

机器学习 Day16 聚类算法 ,数据降维

聚类算法 1.简介 1.1 聚类概念 无监督学习&#xff1a;聚类是一种无监督学习算法&#xff0c;不需要预先标记的训练数据 相似性分组&#xff1a;根据样本之间的相似性自动将样本归到不同类别 相似度度量&#xff1a;常用欧式距离作为相似度计算方法 1.2 聚类vs分类 聚类&…