安装-部署

这里我们采用docker部署

docker run -d \   
--name sentinel-dashboard \   
-p 8858:8858 \     
--restart=always \   
bladex/sentinel-dashboard:1.8.9

访问登录, 账号密码都是sentinel

引入依赖

给需要的服务引入依赖(一般都要得啦)

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

配置application.yml, 需要配置sentinel服务地址, 默认监控接口只监控路径, 如果接口是restul风格的话最好开启http-method-specify(请求方式)

spring:
  cloud:
    sentinel:
      transport:
        dashboard: 192.168.10.2:8858
      # 开启请求方式前缀
      http-method-specify: true

重启服务后, 需要再访问接口让Sentinel监控到, 然后可以在簇点链路看到访问的接口

请求限流

主要是限制QPS大小, 达到保护服务的效果, 点击流控按钮, 阈值类型为QPS, 这里为方便展示, 把阈值设置的小一点, 然后点击新增

然后, 疯狂刷新浏览器, 会发现有好几条请求, 都报了429, 这是服务端限流的状态码

舱壁模式

一个正常的服务可能需要调用别的服务, 但如果某个慢接口 / 烂接口卡死、阻塞、超时,会占满所有线程, 导致原来正常的服务会因为调用这个慢接口而崩掉, 这时候需要针对调用服务接口做限制(限制其最多只能用5条线程, 这样即使卡死原服务也不会宕机); 既然是针对调用服务接口的, 那就是让openfeign的接口被监控

在给feign加上这个配置, 使得feign接口能被监控到

feign:
  sentinel:
    # 开启feign对sentinel的支持
    enabled: true 

重启服务后再请求, 就可以发现有feign调用的簇点链路

然后点击流控, 阈值类型选择并发线程数, 这里还是设置少一点, 使该请求最多只能有三条线程并发, 这里如果每秒能处理两个请求的话, 并发线程为3, 则QPS为6

配置好之后疯狂刷新浏览器, 可以看到平均每五条请求拒绝2条

但是直接拒绝的话, 对用户体验很不好, 这时候就需要降级策略来兜底

服务降级-Fallback

1. 实现FallbackFactory接口

比如这是个调用查询商品的接口

@FeignClient("item-service")
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

那么要这么实现FallbackFactory接口:

@Slf4j
public class ItemFallbackFactory implements FallbackFactory<ItemClient> {
    @Override
    public ItemClient create(Throwable cause) {
        return new ItemClient() {
            @Override
            public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
                log.error("++++++查询商品信息失败", cause);
                return List.of();
            }
        };
    }
}

2. 将该类注册为bean

// 这里不能加@Configuration !!!
public class FeignConfig {

    @Bean
    public ItemFallbackFactory itemFallbackFactory(){
        return new ItemFallbackFactory();
    }
}

3. 将该对象绑定到对应feign接口

@FeignClient(value = "item-service", fallbackFactory = ItemFallbackFactory.class)
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

通过@FeignClient注解中的fallbackFactory属性指定降级处理工厂类的字节码

重启服务后依旧疯狂刷新浏览器, 发现不会报错了, 并且原有请求耗时1秒多, 现在偶尔有请求耗时才几毫秒; 但是几毫秒的请求中数据有缺失, 证明了耗时几毫秒的请求调用别的服务时被限制了, 走了降级逻辑

没被限制
被限制

这样就解决了被限制的请求直接报错而导致用户体验差的问题, 不过没被限制的请求就不会影响用户体验吗? 

服务熔断

很显然, 这种慢接口或坏接口调用都会耗时很久, 很影响体验, 所以我们应该一旦发现这是个不好的接口就应该直接舍弃它(即熔断, 像空气开关一样), 直接走降级策略, 从而提高原服务的体验

1. 原理

服务熔断是Sentinel中的断路器来完成的, 它可以设置几种阈值来判断是否应该熔断, 还可以设置熔断时间隔多长时间试探一次服务接口是否可用, 若不可用则保持熔断状态;

该断路器主要由一个状态机来控制工作模式

状态 状态行为 流转规则
closed(关闭) 正常放行所有请求,持续统计异常比例、慢请求比例 指标超出设定阈值,切换为 open 状态
open(打开) 熔断拦截请求,直接快速失败,执行降级逻辑 等待熔断时间后,自动进入 half-open 半开状态
half-open(半开) 仅放行少量探测请求试探服务健康

探测请求成功 → 切回 closed

探测请求失败 → 切回 open

2. 控制面板设置

选择调用别的服务接口的簇点链路, 点击熔断按钮, 这里阈值类型慢调用比例作为示例, 其他阈值类型也差不多

  • RT(Response Time)超过200毫秒的请求调用就是慢调用

  • 统计最近1000ms内的最少5次请求,如果慢调用比例不低于0.5,则触发熔断

  • 熔断持续时长5s(5秒太短的, 这里方便演示而已)

这里大小为121B的请求请忽略, 这是put请求

可以发现, 请求了5次都超过1秒, 但这之后的请求就都只有几毫秒而已, 且信息不全(走了降级), 但等了5秒后再请求就又是1秒多(这是在试探服务接口能不能用), 之后请求就又回到几毫秒的响应

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐