【SpringCloud】4.Sentinel微服务保护

专栏目录
0.docker快速入门
1.初识微服务
2.Gateway网关路由
3.Nacos配置管理
4.Sentinel微服务保护

微服务保护

处理业务时,微服务只见相互调用过程中,存在一些问题:

首先是业务健壮性问题:

例如在之前的查询购物车列表业务中,购物车服务需要查询最新的商品信息,与购物车数据做对比,提醒用户。大家设想一下,如果商品服务查询时发生故障,查询购物车列表在调用商品服务时,是不是也会异常?从而导致购物车查询失败。但从业务角度来说,为了提升用户体验,即便是商品查询失败,购物车列表也应该正确展示出来,哪怕是不包含最新的商品信息。

还有级联失败问题:

还是查询购物车的业务,假如商品服务业务并发较高,占用过多Tomcat连接。可能会导致商品服务的所有接口响应时间增加,延迟变高,甚至是长时间阻塞直至查询失败。

此时查询购物车业务需要查询并等待商品查询结果,从而导致查询购物车列表业务的响应时间也变长,甚至也阻塞直至无法访问。而此时如果查询购物车的请求较多,可能导致购物车服务的Tomcat连接占用较多,所有接口的响应时间都会增加,整个服务性能很差, 甚至不可用。

1. 服务保护方案

1.1 请求限流

该方案解决的是由于并发过高引起的服务故障,通过该方案将限制或控制接口访问的并发流量,避免服务因流量激增而出现故障。

请求限流往往会有一个限流器,数量高低起伏的并发请求曲线,经过限流器就变的非常平稳。

这就像是水电站的大坝,起到蓄水的作用,可以通过开关控制水流出的大小,让下游水流始终维持在一个平稳的量。

1.2 线程隔离

务接口响应时间长,而且并发高时,就可能耗尽服务器的线程资源,导致服务内的其它接口受到影响。

为了避免某个接口故障或压力过大导致整个服务不可用,我们可以限定每个接口可以使用的资源范围,也就是将其“隔离”起来。

简单说就是将蛋糕切成多块,即使一块弄脏了,其他的还能吃,而不是整块弄脏都吃不了了。

1.3 服务熔断

线程隔离虽然避免了雪崩问题,但故障服务依然会拖慢接口响应速度。而且故障依然会导致功能出现故障,使得业务不可用所以,我们要做两件事情:

  • 编写服务降级逻辑:就是服务调用失败后的处理逻辑,根据业务场景,可以抛出异常,也可以返回友好提示或默认数据。
  • 异常统计和熔断:统计服务提供方的异常比例,当比例过高表明该接口会影响到其它服务,应该拒绝调用该接口,而是直接走降级逻辑。

1.4 总结

降级处理就是为了在服务接口出错等情况下,不让其进行异常报错,提高用户的体验。

服务熔断就是通过编写逻辑判断接口何时进行降级处理,并在降级处理后何时进行恢复从而再次被调用,以此来提高服务接口的响应时间。

2. Sentinel框架

Sentinel是阿里巴巴开源的一款服务保护框架。

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

  • 核心库(Jar包):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。在项目中引入依赖即可实现服务限流、隔离、熔断等功能。
  • 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等

2.1 相关网站

官方网站

jar包下载地址

服务启动后的控制台网址:http://localhost:8090

账号和密码,默认都是:sentinel

2.2 快速入门

①引入依赖

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

②配置控制台

spring:
  cloud: 
    sentinel:
      transport:
        dashboard: localhost:8090

③启动后在进行服务接口访问时,sentinel客户端就会将服务访问的信息提交到控制台并展示

2.3 优化

默认情况下Sentinel会把路径作为簇点资源的名称,无法区分路径相同但请求方式不同的接口,查询、删除、修改等都被识别为一个簇点资源,因此可以选择打开Sentinel的请求方式前缀,把请求方式 + 请求路径作为簇点资源名

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

3. 请求限流

直接使用控制台在簇点链路的操作区域选择流控对齐进行限流

4. 线程隔离

使用OpenFeign整和Sentinel

①在相关服务的application文件中开启feign的sentinel功能

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

②重启服务即可

③使用控制台在FeignClient对应的簇点链路的操作区域选择流控

④阈值选择并发线程数

5. 服务熔断

5.1 编写降级处理逻辑

以OpenFeign的FeignClient编写失败,使用FallbackFactory进行处理为例:

  • FallbackClass,无法对远程调用的异常做处理
  • FallbackFactory,可以对远程调用的异常做处理

①在相关模块中定义FallbackFactory并实现

import ...;

@Slf4j
public class ItemClientFallback implements FallbackFactory<ItemClient> {
    @Override
    public ItemClient create(Throwable cause) {
        return new ItemClient() {
            @Override
            public List<ItemDTO> queryItemByIds(Collection<Long> ids) {
                log.error("远程调用ItemClient#queryItemByIds方法出现异常,参数:{}", ids, cause);
                // 查询购物车允许失败,查询失败,返回空集合
                return CollUtils.emptyList();
            }

            @Override
            public void deductStock(List<OrderDetailDTO> items) {
                // 库存扣减业务需要触发事务回滚,查询失败,抛出异常
                throw new BizIllegalException(cause);
            }
        };
    }
}

②在DefaultFeignConfig类中将ItemClientFallback注册为一个Bean

public ItemClientFallback itemClientFallback(){
    return new ItemClientFallback();
}

③在Feign的定义接口类中使用

@FeignClient(value="",
	configuration=DefaultFeignConfig.class,
    fallbackFactory=ItemClientFallback.class)
public interface Client{}

得到的效果反馈是,请求的延迟依旧很高,但是异常比例为0,即不再报错异常

5.2 服务熔断

①使用控制台在对应接口的操作区域选择熔断

②填写相关规则即可

  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值