浅聊一下微服务的服务保护

在微服务架构里,服务间调用关系错综复杂,一个服务出问题很可能引发连锁反应,也就是 “雪崩”。今天就带大家从零开始学习 Sentinel,这款阿里开源的微服务保护工具,帮你解决雪崩难题,做好流量控制、隔离降级。

一、初识 Sentinel:先搞懂雪崩和解决方案

1.1 雪崩问题到底是啥?

微服务中,一个服务往往依赖多个其他服务。比如服务 A 依赖服务 B,服务 B 又依赖服务 C。要是服务 C 故障了,服务 B 调用 C 时会阻塞,服务 A 调用 B 也会跟着阻塞。

服务器的线程和并发数是有限的,一旦大量请求阻塞,服务器资源很快就会耗尽,进而导致所有服务不可用。接着,依赖这些服务的其他服务也会陆续 “挂掉”,形成级联失败 —— 这就是雪崩。

1.2 解决雪崩的 4 种核心方案

既然雪崩这么可怕,那怎么防?主要有 4 种思路:

  • 超时处理:给请求设个超时时间,超过时间没响应就返回错误,别一直等。比如调用一个服务,超过 200ms 就直接提示 “请求超时”,避免线程一直占用。
  • 仓壁模式(线程隔离):像船舱的防水隔板一样,给每个业务分配独立的线程池。比如订单业务用 10 个线程,商品业务用 10 个线程,就算订单业务线程耗尽,也不影响商品业务。
  • 断路器:统计服务调用的异常比例,要是超过阈值(比如异常率 50%),就 “熔断”—— 暂时拦截所有访问该服务的请求,等服务恢复了再放行。
  • 限流:限制服务的 QPS(每秒请求数),比如每秒最多处理 100 个请求,超过的直接拒绝,避免突发流量把服务冲垮。

简单总结下:限流是 “预防”,提前挡住过多流量;超时、仓壁、断路器是 “补救”,故障发生时控制影响范围。

1.3 服务保护工具对比:为啥选 Sentinel?

Spring Cloud 里有 Hystrix、Resilience4J、Sentinel 等工具,国内用得最多的是 Sentinel,对比 Hystrix 优势很明显:

对比项SentinelHystrix
隔离策略信号量隔离线程池 / 信号量隔离
熔断策略慢调用 / 异常比例失败比率
流量整形支持预热、排队等待不支持
控制台开箱即用,秒级监控不完善
生态适配Spring Cloud、Dubbo 等主要适配 Spring Cloud Netflix

Sentinel 不仅功能全,还能承接阿里双十一大促的流量,稳定性有保障,这也是咱们选它的核心原因。

1.4 Sentinel 安装:3 步搞定

Sentinel 有个可视化控制台,能配置规则、看监控,安装特别简单:

  1. 下载 jar 包:去 GitHub 搜 “Sentinel”,下载最新的 dashboard jar 包(比如 sentinel-dashboard-1.8.1.jar)。
  2. 运行 jar 包:把 jar 包放到非中文目录,打开命令行执行:
    # 默认端口8080,账号密码都是sentinel
    java -jar sentinel-dashboard-1.8.1.jar
    # 想改端口的话,比如改到8090
    java -Dserver.port=8090 -jar sentinel-dashboard-1.8.1.jar
    
  3. 访问控制台:打开浏览器输http://localhost:8080,输入账号密码(都是 sentinel)就能进。刚进去是空白的,因为还没整合微服务。

1.5 微服务整合 Sentinel:以 order-service 为例

以订单服务(shop-order)为例,整合 Sentinel 就 3 步:

  1. 加依赖:在 pom.xml 里加 Sentinel 依赖:
    <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  2. 配控制台地址:在 application.yaml 里加配置,告诉服务控制台在哪:
    spring:cloud:sentinel:transport:dashboard: localhost:8080 # 控制台地址
    
  3. 触发监控:启动服务后,访问一个接口(比如http://localhost:8091/order/prod/19),再刷新控制台,就能看到服务的监控数据了。

二、流量控制:提前挡住突发流量

限流是预防雪崩的关键,Sentinel 的流量控制功能很强大,咱们从基础到进阶慢慢讲。

2.1 先认识 “簇点链路”

请求进微服务时,会走DispatcherServlet → Controller → Service → Mapper这样的调用链,这就是 “簇点链路”。链路上的每个接口(比如 Controller 的方法)都是一个 “资源”,Sentinel 默认会监控 SpringMVC 的所有接口。

在控制台的 “簇点链路” 菜单里,能看到所有资源,每个资源后面都有 “流控”“降级” 等按钮,点进去就能配置规则。

2.2 流控快速入门:给接口设 QPS 阈值

比如给/order/prod/{pid}这个接口设限流规则:QPS 不超过 5(每秒最多 5 个请求)。

  1. 加规则:在簇点链路里,找到/order/prod/{pid},点后面的 “流控”,配置:
    • 阈值类型:QPS
    • 单机阈值:5
    • 其他默认,点 “新增”。
  2. 用 Jmeter 测试:建个线程组,20 个用户、2 秒内发完(QPS=10,超过 5)。运行后看结果,每秒只会成功 5 个请求,超过的会被拒绝。

2.3 3 种流控模式:应对不同场景

流控模式是指 “什么时候触发限流”,Sentinel 支持 3 种,咱们结合场景讲:

2.3.1 直接模式:默认模式,对当前资源限流

刚才的快速入门就是直接模式 —— 只要当前资源的 QPS 超过阈值,就直接限流。适合简单的接口保护,比如普通查询接口。

2.3.2 关联模式:高优先级资源优先,限流低优先级

场景:比如订单的 “更新”(/order/update)和 “查询”(/order/query)都操作数据库,更新要优先保证,要是更新请求太多,就限流查询。

  1. 加接口:在 OrderController 里加两个接口:
    // 查询订单
    @GetMapping("/order/query")
    public String queryOrder() {return "查询订单成功";
    }
    // 更新订单
    @GetMapping("/order/update")
    public String updateOrder() {return "更新订单成功";
    }
    
  2. 配规则:给/order/query加关联流控规则:
    • 流控模式:关联
    • 关联资源:/order/update(当更新接口 QPS 超 5 时,限流查询)
    • 阈值:5
  3. 测试:用 Jmeter 压/order/update(QPS=10),再用浏览器访问/order/query,会提示 “Blocked by Sentinel (flow limiting)”—— 查询被限流了。
2.3.3 链路模式:只限流指定来源的请求

场景:查询订单(/order/query)和创建订单(/order/save)都要调用 “查询商品”(queryGoods)方法,只想限流从 “查询订单” 进来的请求。

  1. 加方法和接口
    • OrderService 加 queryGoods 方法,用@SentinelResource("goods")标记(让 Sentinel 监控):
      @SentinelResource("goods")
      public void queryGoods() {System.err.println("查询商品");
      }
      
    • OrderController 加/order/save,并让/order/query/order/save都调用 queryGoods:
      // 查询订单调用商品查询
      @GetMapping("/order/query")
      public String queryOrder() {orderService.queryGoods();return "查询订单成功";
      }
      // 新增订单调用商品查询
      @GetMapping("/order/save")
      public String saveOrder() {orderService.queryGoods();return "新增订单成功";
      }
      
  2. 关资源聚合:Sentinel 默认会把 SpringMVC 请求聚合到一个 root 资源,链路模式会失效,所以要在 application.yaml 里关了:

    yaml

    spring:cloud:sentinel:web-context-unify: false # 关闭context整合
    
  3. 配规则:给 “goods” 资源加链路流控规则:
    • 流控模式:链路
    • 入口资源:/order/query(只统计从查询订单进来的请求)
    • 阈值:2
  4. 测试:用 Jmeter 压/order/save(QPS=4),访问/order/save正常;压/order/query(QPS=4),超过 2 的请求会被限流。

2.4 3 种流控效果:超过阈值后怎么处理?

流控效果是指 “QPS 超阈值后,怎么处理新请求”,Sentinel 支持 3 种:

2.4.1 warm up(预热模式):应对服务冷启动

服务刚启动时,资源没初始化(比如连接池没建立),要是直接扛最大 QPS,可能会宕机。预热模式就是让阈值从一个小值慢慢涨到最大值,给服务 “预热” 时间。

比如给/order/prod/{pid}设规则:

  • 阈值类型:QPS
  • 单机阈值:10(最大 QPS)
  • 流控效果:warm up
  • 预热时长:5 秒

Sentinel 默认冷启动因子是 3,所以初始阈值是 10/3≈3。刚启动时,每秒只能过 3 个请求,5 秒后慢慢涨到 10 个。用 Jmeter 测试,刚开始失败率高,后来会越来越低。

2.4.2 排队等待:让请求平滑执行

快速失败和 warm up 都是直接拒绝超阈值请求,排队等待则是让请求排队,按固定间隔执行,避免流量波动。

比如给/order/prod/{pid}设规则:

  • 阈值类型:QPS
  • 单机阈值:10(每秒 10 个,即每 200ms 一个)
  • 流控效果:排队等待
  • 超时时间:5000ms(请求等待超过 5 秒就拒绝)

用 Jmeter 压 QPS=15(超阈值),结果所有请求都会通过,但响应时间会变长 —— 因为都在排队。控制台看 QPS 曲线会很平滑,一直保持在 10 左右,对服务器很友好。

2.4.3 快速失败:默认效果,直接拒绝

超过阈值后,新请求直接被拒绝,抛出FlowException,适合对响应时间敏感的场景(比如支付接口,不能让用户等)。

2.5 热点参数限流:对不同参数区别对待

之前的限流是统计整个资源的 QPS,热点参数限流则是按 “参数值” 统计。比如/order/prod/{pid}接口,pid=1 是秒杀商品(热点),pid=2 是普通商品,想给它们设不同的 QPS 阈值。

2.5.1 实战案例:给 pid 设不同阈值

需求:/order/prod/{pid}默认 QPS=2,pid=1 设 QPS=4,pid=19 设 QPS=10。

  1. 标记资源:给接口加@SentinelResource("hot")(热点限流要这个注解):
    @SentinelResource("hot")
    @GetMapping("/order/prod/{pid}")
    public String getOrderByPid(@PathVariable Integer pid) {// 业务逻辑
    }
    
  2. 加热点规则:控制台进 “热点规则”,点 “新增”:
    • 资源名:hot
    • 限流模式:QPS 模式
    • 参数索引:0(第一个参数,即 pid)
    • 单机阈值:2(默认阈值)
    • 高级选项→参数例外项:
      • 加 pid=1(long 类型),阈值 4
      • 加 pid=19(long 类型),阈值 10
  3. 测试:用 Jmeter 分别压 pid=1(QPS=5)、pid=19(QPS=12)、普通 pid(QPS=3):
    • pid=1:每秒成功 4 个
    • pid=19:每秒成功 10 个
    • 普通 pid:每秒成功 2 个

三、隔离和降级:故障发生时控制影响范围

限流是预防,隔离和降级是故障发生后的 “止损” 手段。Sentinel 主要通过线程隔离(仓壁模式)和熔断降级来实现。

3.1 Feign 整合 Sentinel:远程调用要保护

微服务远程调用大多用 Feign,所以要先整合 Feign 和 Sentinel,才能在远程调用时做隔离和降级。

3.1.1 开启 Feign 的 Sentinel 支持

在 order-service 的 application.yaml 里加配置:

feign:sentinel:enabled: true # 开启Feign对Sentinel的支持
3.1.2 写失败降级逻辑

远程调用失败时(比如服务宕机),不能直接报错,要返回友好提示。有两种方式:

方式 1:FallbackClass(不支持捕获异常)
  1. 写降级类,实现 Feign 接口:
    @Component
    public class ProductServiceFallback implements IProductService {@Overridepublic Product findByPid(Integer pid) {// 降级逻辑:返回默认值Product product = new Product();product.setPid(-1);product.setPname("暂无商品");return product;}
    }
    
  2. Feign 接口指定降级类:
    @FeignClient(value = "service-product", fallback = ProductServiceFallback.class)
    public interface IProductService {@GetMapping("/product/{pid}")Product findByPid(@PathVariable Integer pid);
    }
    
方式 2:FallbackFactory(支持捕获异常)

要是想知道调用失败的原因,就用 FallbackFactory:

  1. 写降级工厂类:
    @Component
    public class ProductServiceFallbackFactory implements FallbackFactory<IProductService> {@Overridepublic IProductService create(Throwable throwable) {// 打印异常信息System.out.println("调用失败:" + throwable.getMessage());// 返回降级逻辑return new IProductService() {@Overridepublic Product findByPid(Integer pid) {Product product = new Product();product.setPid(-1);product.setPname("暂无商品");return product;}};}
    }
    
  2. Feign 接口指定降级工厂:
    @FeignClient(value = "service-product", fallbackFactory = ProductServiceFallbackFactory.class)
    public interface IProductService {@GetMapping("/product/{pid}")Product findByPid(@PathVariable Integer pid);
    }
    

3.2 线程隔离(仓壁模式):避免资源耗尽

线程隔离是给每个远程调用分配独立的线程池(或信号量),就算某个调用故障,也只消耗该线程池的资源,不影响其他调用。

3.2.1 两种隔离方式对比
隔离方式原理优点缺点
信号量隔离计数器模式,统计线程数简单,开销小不能隔离慢调用
线程池隔离给每个调用分配独立线程池隔离彻底,支持慢调用线程切换开销大

Sentinel 默认用信号量隔离,要是需要隔离慢调用(比如调用一个慢服务),就用线程池隔离。

3.2.2 实战:给 Feign 接口设线程数阈值

需求:order-service 调用 product-service 的接口,线程数不超过 2(即同时最多 2 个线程调用)。

  1. 加规则:在簇点链路里找到 Feign 接口(比如/product/{pid}),点 “流控”:
    • 阈值类型:线程数
    • 单机阈值:2
    • 其他默认
  2. 测试:用 Jmeter 发 10 个并发请求(瞬间发完),会发现部分请求返回降级逻辑(“暂无商品”)—— 因为线程数超 2 了,超出的请求被限流。

3.3 熔断降级:故障服务暂时 “隔离”

要是一个服务调用失败率很高(比如 80% 的请求都失败),继续调用只会浪费资源,这时候就该 “熔断”—— 暂时拦截所有调用,等服务恢复了再放行。

Sentinel 的熔断策略有两种:

  • 慢调用比例:请求响应时间超过 “慢调用阈值” 的比例,超过阈值就熔断。
  • 异常比例:调用失败(抛异常)的比例超过阈值,就熔断。

配置方式和流控类似,在簇点链路里点 “降级”,选对应的策略和阈值即可。比如设 “异常比例”:异常率超过 50%,熔断时长 5 秒 ——5 秒内所有调用都会被拦截,5 秒后会放少量请求试探,要是恢复了就取消熔断。

总结

Sentinel 的核心功能就是 “流量控制” 和 “隔离降级”:

  • 流量控制:通过直接 / 关联 / 链路模式,结合快速失败 /warm up / 排队效果,提前挡住突发流量,预防雪崩。
  • 隔离降级:通过线程隔离(仓壁模式)和熔断降级,在服务故障时控制影响范围,避免级联失败。

实际项目中,要根据业务场景选择合适的规则 —— 比如秒杀接口用 warm up + 热点参数限流,慢服务调用用线程池隔离,核心接口用熔断降级。多测试、多调优,才能让微服务更稳定~

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

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

相关文章

ECharts Gallery:Apache官方数据可视化模板库,助你快速制作交互图表并实现深度定制

你有没有过这种时候&#xff1f;手里攥着一堆 Excel 数据&#xff0c;想做个直观的图表给同事看&#xff0c;用 Excel 自带的图表吧&#xff0c;样式丑不说&#xff0c;稍微复杂点的交互&#xff08;比如点击柱子显示详情&#xff09;根本做不了&#xff1b;想自己用代码写吧&a…

[数据结构——lesson3.单链表]

目录 引言 学习目标&#xff1a; 1.什么是链表 2.链表的分类 2.1 单向链表和双向链表 (1)单向链表 (2)双向链表 2.2 带头结点链表和不带头结点链表 (1)带头结点链表 (2)不带头结点链表 2.3 循环链表和不循环链表 (1)循环链表 &#xff08;2)非循环链表 3.链表的实…

从零深入理解嵌入式OTA升级:Bootloader、IAP与升级流程全解析

引言&#xff08;Opening&#xff09;想象一下&#xff0c;你开发的一款智能水杯、一个环境监测设备或者一台共享充电宝&#xff0c;已经部署到了成千上万的用户手中。突然&#xff0c;你发现了一个软件bug&#xff0c;或者需要增加一个酷炫的新功能。你不可能派人跑到每个设备…

【Ansible】实施 Ansible Playbook知识点

1.清单概念与静态清单文件是什么&#xff1f;答&#xff1a;Ansible 清单是被管理主机的列表&#xff0c;用于明确Ansible的管理范围&#xff0c;分为静态清单和动态清单。静态清单是通过手动编辑的文本文件来定义被管主机&#xff0c;文件格式可以是INI格式或YAML格式。在INI格…

【Linux】vim工具篇

目录一、vim的多模式1.1 命令模式1.1.1 光标移动1.1.2 复制及撤销1.1.3 剪切及删除1.1.4 替换1.1.5 批量化注释/去注释1.2 底行模式二、vim的配置个人主页<—请点击 Linux专栏<—请点击 一、vim的多模式 vim是一款功能强大的文本编辑器&#xff0c;它编辑代码主要围绕命…

Spark 核心原理:RDD, DataFrame, DataSet 的深度解析

Apache Spark 是一个强大的分布式计算系统&#xff0c;以其内存计算、速度快、易用性强等特点&#xff0c;在大数据处理领域占据重要地位。理解 Spark 的核心原理&#xff0c;特别是其三种核心抽象——RDD, DataFrame, DataSet——对于高效地使用 Spark 至关重要。本文将深入解…

Docker 命令行的使用

1.Docker 命令列表[roothost1 ~]# docker Usage: docker [OPTIONS] COMMANDA self-sufficient runtime for containersCommon Commands:run Create and run a new container from an imageexec Execute a command in a running containerps List cont…

Redis Stream:轻量级消息队列深度解析

&#x1f4e8; Redis Stream&#xff1a;轻量级消息队列深度解析 文章目录&#x1f4e8; Redis Stream&#xff1a;轻量级消息队列深度解析&#x1f9e0; 一、Stream 数据结构解析&#x1f4a1; Stream 核心概念&#x1f4cb; Stream 底层结构⚡ 二、消息生产与消费&#x1f68…

Android studio的adb和终端的adb互相抢占端口

在Android Studio调试时&#xff0c;有时候也需要借助终端的adb命令&#xff0c;他们互相抢占端 口&#xff0c;导致调试麻烦解决如下&#xff1a;① 终端adb的版本是&#xff1a;1.0.39路径是:/usr/lib/android-sdk/platform-tools/adb② Android Studio使用的adb来源于Androi…

GEO服务商推荐:移山科技以划时代高精尖技术引领AI搜索优化新纪元

引言&#xff1a;AI搜索生态重塑与GEO优化战略地位跃升AI技术对信息检索范式的颠覆GEO优化在企业增长中的核心作用第一章&#xff1a;AI搜索新纪元的企业营销挑战与机遇生成式AI成为用户主要信息入口的行业趋势企业在AI搜索中的“答案主权”争夺战GEO优化服务商的核心能力模型&…

Android SystemServer 系列专题【AttentionManagerService】

AttentionManagerService是framework中用来实现屏幕感知的一个系统级服务&#xff0c;他继承于systemserver。我们可以通过dumpsys attention来获取他的一些信息。如下针对屏幕感知的功能的引入来针对这个服务进行一个介绍。1、屏幕感知Settings UI实现屏幕感知的功能在A14上面…

nginx 反向代理使用变量的坑

nginx采用反向代理的时候使用变量的坑 正常情况&#xff1a; location ~ ^/prod-api(?<rest>/.*)?$ {# 假设 $mes_backend 形如: http://127.0.0.1:16889proxy_pass $mes_backend$rest$is_args$args;proxy_http_version 1.1;proxy_set_header Host $host;…

Origin绘制径向条形图|科研论文图表教程

数据排列格式截图&#xff0c;请查看每张图↘右下角水印 目录 数据排列格式截图&#xff0c;请查看每张图↘右下角水印 本 期 导 读 No.1 理解图形 1 定义 2 特点 3 适用场景 No.2 画图教程 1 导入数据&#xff0c;绘制图形 2 设置绘图细节 本 期 导 读 径…

MySQL InnoDB 的 MVCC 机制

前言 多版本并发控制&#xff08;MVCC&#xff09;是 MySQL InnoDB 存储引擎实现高性能事务的核心机制。它通过创建数据快照&#xff0c;使得读写操作可以无锁并发&#xff0c;极大地提升了数据库的并发性能。本文将深入探讨 MVCC 的工作原理、实现细节以及它与事务隔离级别的紧…

景区负氧离子气象站:引领绿色旅游,畅吸清新每一刻

在绿色旅游成为消费主流的今天&#xff0c;游客对 “清新空气” 的需求不再是模糊的期待&#xff0c;而是可感知、可选择的具体体验。景区负氧离子气象站的出现&#xff0c;正以科技之力重塑绿色旅游格局&#xff0c;让 “畅吸清新每一刻” 从口号变为触手可及的现实&#xff0…

Pytorch笔记一之 cpu模型保存、加载与推理

Pytorch笔记一之 cpu模型保存、加载与推理 1.保存模型 首先&#xff0c;在加载模型之前&#xff0c;我们需要了解如何保存模型。PyTorch 提供了两种保存模型的方法&#xff1a;保存整个模型和仅保存模型的状态字典&#xff08;state dict&#xff09;。推荐使用第二种方式&…

当AI在代码车间组装模块:初级开发者的创意反成「核心算法」

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录当AI在…

技术视界 | 跨域机器人通信与智能系统:打破壁垒的开源探索

8 月 16 日&#xff0c;在 OpenLoong 社区举办的第九期线下分享会上&#xff0c;国家地方共建人形机器人创新中心的软件开发负责人 Amadeus 博士带来了一场主题为“跨域机器人通信与智能系统&#xff1a;打破行业壁垒的创新方案”的演讲。深入探讨了当前机器人领域的一个关键痛…

Android入门到实战(八):从发现页到详情页——跳转、传值与RecyclerView多类型布局

一. 引言在上一篇文章里&#xff0c;我们从零开始实现了 App 的 发现页面&#xff0c;通过网络请求获取数据&#xff0c;并使用 RecyclerView 展示了剧集列表。但光有发现页还不够&#xff0c;用户在点击一部剧时&#xff0c;自然希望进入到一个更详细的页面&#xff0c;去查看…

【工具】41K star!网页一键变桌面应用

项目中遇到了一个需要将现有的 web 页面打包成一个 桌面应用 的需求。 最一开始想到的是 Electron&#xff0c;但是它还需要一些开发工作并且打包后的应用体积比较大&#xff0c;调研后发现了开源工具 Pake。 它能让你用最轻量的方式&#xff0c;把任何网页一键打包成跨平台桌…