微服务保护

一. Sentinel

官网:sentinelguard.io/zh-cn/ 下载Sentinel: github.com/alibaba/Sen...
导入依赖

java 复制代码
<!--sentinel-->
<dependency>
    <groupId>com.alibaba.cloud</groupId> 
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

修改application.yaml文件

java 复制代码
spring:
  cloud: 
    sentinel:
      transport:
        dashboard: localhost:8090

cmd启动Sentinel的jar包:java -Dserver.port=8090 -Dcsp.sentinel.dashboard.server=localhost:8090 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar 输入:http://localhost:8090 账号和密码,默认都是:sentinel

二. 请求限流

请求限流,就是限制或控制接口访问的并发流量,避免服务因流量激增而出现故障。 请求限流往往会有一个限流器 ,数量高低起伏的并发请求曲线,经过限流器就变的非常平稳。这就像是水电站的大坝,起到蓄水的作用,可以通过开关控制水流出的大小,让下游水流始终维持在一个平稳的量。

添加限流

给予每秒10次的请求次数

可以看到大概6次通过,4次拒绝

三. 线程隔离

限流可以降低服务器压力,尽量减少因并发流量引起的服务故障的概率,但并不能完全避免服务故障。一旦某个服务出现故障,我们必须隔离对这个服务的调用,避免发生雪崩。 如图所示,我们给查询购物车业务限定可用线程数量上限为20,这样即便查询购物车的请求因为查询商品服务而出现故障,也不会导致服务器的线程资源被耗尽,不会影响到其它接口。

添加线程数控制,也是点击流控

每秒钟100个线程请求

大概5个通过,95个失败

四. Fallback

修改cart-service模块的application.yml文件,开启Feign的sentinel功能:

java 复制代码
feign:
  sentinel:
    enabled: true # 开启feign对sentinel的支持

给FeignClient编写失败后的降级逻辑有两种方式:

  • 方式一:FallbackClass,无法对远程调用的异常做处理
  • 方式二:FallbackFactory,可以对远程调用的异常做处理,我们一般选择这种方式。 在这里插入图片描述

在hm-api模块中给ItemClient定义降级处理类,实现FallbackFactory:

java 复制代码
package com.hmall.api.client.fallback;

import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.api.dto.OrderDetailDTO;
import com.hmall.common.utils.CollUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;

import java.util.Collection;
import java.util.List;

public class ItemClientFallbackFactory implements FallbackFactory<ItemClient> {
    private static final Logger log = LoggerFactory.getLogger(ItemClientFallbackFactory.class);

    @Override
    public ItemClient create(Throwable cause) {
        return new ItemClient() {
            @Override
            public List<ItemDTO> queryItemsByIds(Collection<Long> itemIds) {
                log.error("查询商品信息失败", cause);
                return CollUtils.emptyList();
            }

            @Override
            public void deductStock(List<OrderDetailDTO> items) {
                log.error("扣减商品库存失败", cause);
                throw new RuntimeException(cause);
            }
        };
    }
}

在hm-api模块中的com.hmall.api.config.DefaultFeignConfig类中将ItemClientFallback注册为一个Bean:

java 复制代码
  	@Bean
    public ItemClientFallbackFactory itemClientFallbackFactory() {
        return new ItemClientFallbackFactory();
    }

在hm-api模块中的ItemClient接口中使用ItemClientFallbackFactory:

java 复制代码
@FeignClient(value = "item-service",
        configuration = DefaultFeignConfig.class,
        fallbackFactory = ItemClientFallbackFactory.class)
public interface ItemClient {
    @GetMapping("/items")
    List<ItemDTO> queryItemsByIds(@RequestParam("ids") Collection<Long> itemIds);

    @PutMapping("/items/stock/deduct")
    public void deductStock(@RequestBody List<OrderDetailDTO> items);
}

发现被限流的请求不再报错,走了降级逻辑:

五. 服务熔断

查询商品的RT较高(模拟的500ms),从而导致查询购物车的RT也变的很长。这样不仅拖慢了购物车服务,消耗了购物车服务的更多资源,而且用户体验也很差。 对于商品服务这种不太健康的接口,我们应该停止调用,直接走降级逻辑,避免影响到当前服务。也就是将商品查询接口熔断。当商品服务接口恢复正常后,再允许调用。这其实就是断路器的工作模式了。 状态机包括三个状态:

  • closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到open状态
  • open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。Open状态持续一段时间后会进入half-open状态
  • half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。
    • 请求成功:则切换到closed状态
    • 请求失败:则切换到open状态

在控制台通过点击簇点后的熔断按钮来配置熔断策略:

  • RT超过200毫秒的请求调用就是慢调用
  • 统计最近1000ms内的最少5次请求,如果慢调用比例不低于0.5,则触发熔断
  • 熔断持续时长20s

在一开始一段时间是允许访问的,后来触发熔断后,查询商品服务的接口通过QPS直接为0,所有请求都被熔断了。而查询购物车的本身并没有受到影响。

相关推荐
GlobalInfo16 小时前
上新 | 全球及中国起重机摄像系统行业研究报告(2026版):市场现状、行业前景与占有率分析
大数据·分布式·微服务·ai·相机
利威尔xu1 天前
Go IM 源码实战(2):WebSocket 握手 11 步,少 1 个参数连不上
后端·websocket·微服务·面试·golang
samforce1 天前
为什么微服务会退化成“分布式单体”?——软件架构里的嵌套率传导定律
人工智能·分布式·微服务·架构·软件架构·结构认知
我不会起名字3221 天前
gRPC 拦截器写错:metadata 透传与超时注入的 3 个坑
微服务·go·grpc·拦截器
yz_aiks1 天前
RestTemplate 废弃后迁移 RestClient 实战:Spring Boot 4.2 升级指南
java·spring boot·后端·微服务·restclient
java_nnnn1 天前
分布式系统进阶:数据库分库分表、微服务与架构演进总结
数据库·redis·微服务·架构
code_slave(码畜)2 天前
微服务架构落地:分库分表实战(下) —— 分布式主键、跨分片查询与分页聚合防坑
数据库·spring boot·分布式·spring cloud·微服务·架构·分库分表
每天一道题2 天前
Kafka 为什么会重复消费?从 Producer ACK、Offset 到消息可靠性
后端·微服务
ん贤3 天前
温习微服务基础知识
微服务·云原生·架构
zzu123zsw3 天前
业务拆分后的治理深水区:解构企业级微服务六大核心设计模式与高可用落真实践
微服务·设计模式·架构·高可用·微服务架构设计