微服务保护和分布式事务(3)

米饭10个月前行业资讯732

1.3 请求限流:

在簇点链路后面点击流控按钮,即可对其做限流配置:

image-20241121171200123

在弹出的菜单中填写:

image-20241121171816981

这样就把查询购物车列表这个簇点资源的流量限制在了每秒 6 个,也就是最大 QPS 为 6。


1.4 线程隔离:

限流可以降低服务器压力,尽量减少因并发流量引起的服务故障的概率,但并不能完全避免服务故障。一旦某个服务出现故障,我们必须隔离对这个服务的调用,避免发生雪崩。


1.4.1 OpenFeign 整合 Sentinel:

application.yml文件,开启 Feign 的 sentinel 功能:

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

然后重启对应微服务,可以看到调用另一个微服务 FeignClient 自动变成了一个簇点资源:

image-20241121184630705

1.4.2 配置线程隔离:

接下来,点击对应微服务接口的 FeignClient 对应的簇点资源后面的流控按钮:

image-20241121185214609

在弹出的表单中填写下面内容:

image-20241121185252386

注意,这里勾选的是并发线程数限制,也就是说这个查询功能最多使用 5 个线程,而不是 5 QPS。如果查询商品的接口每秒处理 2 个请求,则 5 个线程的实际 QPS 在 10 左右,而超出的请求自然会被拒绝。


1.5 服务熔断:

上面使用线程隔离导致了一些问题如下:


第一,超出的 QPS 上限的请求就只能抛出异常,从而导致购物车的查询失败。但从业务角度来说,即便没有查询到最新的商品信息,购物车也应该展示给用户,用户体验更好。也就是给查询失败设置一个降级处理逻辑。


第二,由于查询商品的延迟较高,从而导致查询购物车(购物车接口里面调用商品接口,涉及不同微服务之间的调用)的响应时间也变的很长。这样不仅拖慢了购物车服务,消耗了购物车服务的更多资源,而且用户体验也很差。对于商品服务这种不太健康的接口,我们应该直接停止调用,直接走降级逻辑,避免影响到当前服务。也就是将商品查询接口熔断。


1.5.1 编写降级逻辑:

触发限流或熔断后的请求不一定要直接报错,也可以返回一些默认数据或者友好提示,用户体验会更好。


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


方式一:FallbackClass,无法对远程调用的异常做处理

方式二:FallbackFactory,可以对远程调用的异常做处理,我们一般选择这种方式。

这里我们演示方式二的失败降级处理。


涉及 ItemClient 接口,该接口是 OpenFeign 客户端。


步骤一:给ItemClient定义降级处理类,实现FallbackFactory:

代码如下:

@FeignClient(value = "item-service",
        configuration = DefaultFeignConfig.class,
        fallbackFactory = ItemClientFallback.class)
public interface ItemClient {
    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam Collection<Long> ids);

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

}

// 实现FallbackFactory
@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);
            }
        };
    }
}

步骤二:将刚刚创建的实现了 FallbackFactory 接口的实现类,加入到 spring 容器中。

这里我使用方法注解创建。

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

步骤三:在ItemClient接口中使用ItemClientFallbackFactory

image-20241121191841015

1.5.2 服务熔断:

对于不太健康的接口,我们应该停止调用,直接走降级逻辑,避免影响到当前服务。也就是将商品查询接口熔断。当商品服务接口恢复正常后,再允许调用。这其实就是断路器的工作模式了。


Sentinel中的断路器不仅可以统计某个接口的慢请求比例,还可以统计异常请求比例。当这些比例超出阈值时,就会熔断该接口,即拦截访问该接口的一切请求,降级处理;当该接口恢复正常时,再放行对于该接口的请求。


断路器的工作状态切换有一个状态机来控制:

image-20241121192424546

状态机包括三个状态:


closed:关闭状态,断路器放行所有请求,并开始统计异常比例、慢请求比例。超过阈值则切换到 open 状态。

open:打开状态,服务调用被熔断,访问被熔断服务的请求会被拒绝,快速失败,直接走降级逻辑。open 状态持续一段时间后,会进入 half-open 状态。

half-open:半开状态,放行一次请求,根据执行结果来判断接下来的操作。

请求成功:则切换到 closed 状态。

请求失败:则切换到 open 状态。

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

image-20241121192842541

在弹出的表格中这样填写:

image-20241121192923322

这种是按照慢调用比例来做熔断,上述配置的含义是:

  • RT超过 200 毫秒的请求调用就是慢调用。

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

  • 熔断持续时长 20s。


  • 本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!  

    云掣基于多年在运维领域的丰富时间经验,编写了《云运维服务白皮书》,欢迎大家互相交流学习:

    《云运维服务白皮书》下载地址:https://fs80.cn/v2kbbq

    想了解更多大数据运维托管服务、数据库运维托管服务、应用系统运维托管服务的的客户,欢迎点击云掣官网沟通咨询:https://yunche.pro/?t=shequ

相关文章

解决虚拟机卡死且无法强制结束进程的问题

解决虚拟机卡死且无法强制结束进程的问题

【Linux虚拟机死机】有很多种情况,最常见的是系统负载过高导致的。可以是运行内存耗用极大的程序,也会迅速提升系统负载。由于系统负载过高导致的卡死,一定是解决的越快越好!不能再试图依赖任何图形界面的东...

如何为阿里云服务器配置域名

如何为阿里云服务器配置域名

域名是互联网上的门牌号,它将用户输入的网址转换为服务器的IP地址,从而让用户能够访问到服务器上托管的网站或应用。阿里云作为国内领先的云服务提供商,提供了强大的服务器和域名管理服务。本文将详细介绍如何为...

CentOS7 yum安装报错“Could not resolve host: mirrorlist.centos.org; Name or service not known“之解决办法(换源)

CentOS7 yum安装报错“Could not resolve host: mirrorlist.centos.org; Name or service not known“之解决办法(换源)

yum安装出现错误如下:yum install -y wget && wget -O install.sh https://download.bt.cn/install/install...

Linux--多路转接之epoll

Linux--多路转接之epoll

epoll 是 Linux 下多路复用 I/O 接口 select/poll 的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。它是 Linux 下多路复用 AP...

RabbitMQ 进阶1(发送者和MQ的可靠性)

RabbitMQ 进阶1(发送者和MQ的可靠性)

我们可以通过 MQ 异步调用,来使程序的性能更好和解耦合。但是如果 MQ 的消息没有成功的被对应的程序处理,那么这样不就会造成数据不一致的情况。因此,我们这里必须要尽可能的确保 MQ 消息的可靠性,即...

如何理解运维

如何理解运维

运维工程师(运营),负责维护并确保整个服务的高可用性,同时不断优化系统架构提升部署效率,优化资源利用率提高整体的投资回报率。运维工程师面对的最大挑战是大规模集群的管理问题,如何管理好几十万台服务器上的...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。