首页 > 其他分享 >十一、消息发送重试和流控机制

十一、消息发送重试和流控机制

时间:2023-07-16 19:13:37浏览次数:31  
标签:发送 流控 触发 重试 消息 客户端

消息发送重试机制

背景

Apache RocketM Q的消息发送重试机制主要解答如下问题:

  • 部分节点异常是否影响消息发送?

  • 请求重试是否会阻塞业务调用?

  • 请求重试会带来什么不足?

概念

Apache RocketMQ 客户端连接服务端发起消息发送请求时,可能会因为网络故障、服务异常等原因导致调用失败。为保证消息的可靠性, Apache RocketMQ 在客户端SDK中内置请求重试逻辑,尝试通过重试发送达到最终调用成功的效果。

同步发送和异步发送模式均支持消息发送重试。

重试触发条件

触发消息发送重试机制的条件如下:

  • 客户端消息发送请求调用失败或请求超时

  • 网络异常造成连接失败或请求超时。

  • 服务端节点处于重启或下线等状态造成连接失败。

  • 服务端运行慢造成请求超时。

  • 服务端返回失败错误码

    1、系统逻辑错误:因运行逻辑不正确造成的错误。

    2、系统流控错误:因容量超限造成的流控错误。

注意:对于事务消息,只会进行透明重试(transparent retries),网络超时或异常等场景不会进行重试。

 

当发生上面场景时,RocketMQ会在一直重试发送消息,直到达到重试最大次数或发送成功并在最后一次重试失败后返回错误码。

重试间隔
  • 除服务端返回系统流控错误场景,其他触发条件触发重试后,均会立即进行重试,无等待间隔。

  • 若由于服务端返回流控错误触发重试,系统会按照指数退避策略进行延迟重试。指数退避算法通过以下参数控制重试行为:

    INITIAL_BACKOFF: 第一次失败重试前后需等待多久,默认值:1秒。

    MULTIPLIER :指数退避因子,即退避倍率,默认值:1.6。

    JITTER :随机抖动因子,默认值:0.2。

    MAX_BACKOFF :等待间隔时间上限,默认值:120秒

    MIN_CONNECT_TIMEOUT :最短重试间隔,默认值:20秒。

 

建议算法如下:

current_backoff = INITIAL_BACKOFF
current_deadline = now() + INITIAL_BACKOFF
while (TryConnect(Max(current_deadline, now() + MIN_CONNECT_TIMEOUT))!= SUCCESS)
  SleepUntil(current_deadline)
  current_backoff = Min(current_backoff * MULTIPLIER, MAX_BACKOFF)
  current_deadline = now() + current_backoff + UniformRandom(-JITTER * current_backoff, JITTER * current_backoff)

除了第一次重试外,之后每次的等待间隔时间等于上一次的间隔时间 * 指数退避因子 和 等待间隔时间上限之中的最大值 ,计算出结果后, 在加上 计算后的结果 * 负的随机抖动因子 到 计算后的结果 * 随机抖动因子 之间的一个随机数。每次的重试时间都不会超过MIN_CONNECT_TIMEOUT。

功能约束
  • 链路耗时阻塞评估:从上述重试机制可以看出,在重试流程中生产者仅能控制最大重试次数。若由于系统异常触发了SDK内置的重试逻辑,则服务端需要等待最终重试结果,可能会导致消息发送请求链路被阻塞。对于某些实时调用类场景,您需要合理评估每次调用请求的超时时间以及最大重试次数,避免影响全链路的耗时。

  • 最终异常兜底: Apache RocketMQ 客户端内置的发送请求重试机制并不能保证消息发送一定成功。当最终重试仍然失败时,业务方调用需要捕获异常,并做好冗余保护处理,避免消息发送结果不一致。

  • 消息重复问题:因远程调用的不确定性,当Apache RocketMQ客户端因请求超时触发消息发送重试流程,此时客户端无法感知服务端的处理结果,客户端进行的消息发送重试可能会产生消息重复问题,业务逻辑需要自行处理消息重复问题。

消息流控机制

背景

Apache RocketMQ 的流控机制主要为您解答如下问题:

  • 系统在什么情况下会触发流控?

  • 触发流控时客户端行为是什么?

  • 应该如何避免触发流控,以及如何应对突发流控?

概念

消息流控指的是系统容量或水位过高, Apache RocketMQ 服务端会通过快速失败返回流控错误来避免底层资源承受过高压力。

触发条件

Apache RocketMQ 的消息流控触发条件如下:

  • 存储压力大:参考消费进度管理的原理机制,消费者分组的初始消费位点为当前队列的最大消费位点。若某些场景例如业务上新等需要回溯到指定时刻前开始消费,此时队列的存储压力会瞬间飙升,触发消息流控。

  • 服务端请求任务排队溢出:若消费者消费能力不足,导致队列中有大量堆积消息,当堆积消息超过一定数量后会触发消息流控,减少下游消费系统压力。

流控行为

当系统触发消息发送流控时,客户端会收到系统限流错误和异常,错误码信息如下:

  • reply-code:530

  • reply-text:TOO_MANY_REQUESTS

客户端收到系统流控错误码后,会根据指数退避策略进行消息发送重试。

处理建议
  • 如何避免触发消息流控:触发限流的根本原因是系统容量或水位过高,您可以利用可观测性功能监控系统水位容量等,保证底层资源充足,避免触发流控机制。

  • 突发消息流控处理:如果因为突发原因触发消息流控,且客户端内置的重试流程执行失败,则建议业务方将请求调用临时替换到其他系统进行应急处理。

标签:发送,流控,触发,重试,消息,客户端
From: https://www.cnblogs.com/shigongp/p/17557997.html

相关文章

  • spring boot flowable 参数配置 重试参数配置
    SpringBootFlowable参数配置及重试参数配置概述在使用SpringBootFlowable框架开发工作流应用时,我们可能会遇到需要进行参数配置和重试参数配置的情况。本文将为刚入行的开发者介绍如何实现SpringBootFlowable参数配置及重试参数配置,并提供详细的步骤和代码示例。参数配置......
  • VUE WebSocket连接成功后,立即发送一个token
    ws=newWebSocket(ws://${location.host}/xxx)ws.onopen=()=>{ws.send(JSON.stringify({headers:{Authorization:Bearer${token}}}));isConnected.value=true;}查看方法:在消息数据里(不是标头里)......
  • compattelrunner.exe 进程会定期运行,扫描系统以收集应用程序、硬件和设备的兼容性数据
    compattelrunner.exe是Windows容错报告工具(WindowsCompatibilityTelemetry)Windows容错报告工具是Microsoft开发的一项功能,旨在帮助改进Windows的稳定性和兼容性。而compattelrunner.exe是容错报告工具的一个组成部分,它负责收集系统的兼容性数据以及硬件和驱动程序信......
  • Python如何实现自动生成报表并以邮件发送
    Python如何实现自动生成报表并以邮件发送首先来介绍下实现自动报表要使用到的Python库:pymysql一个可以连接MySQL实例并且实现增删改查功能的库datetimePython标准库中自带的关于时间的库openpyxl一个可以读写07版以后的Excel文档(.xlsx格式也支持)的库smtplibSMTP即简单......
  • java代码向stream消息队列发送消息失败
    如何实现Java代码向Stream消息队列发送消息失败作为一名经验丰富的开发者,您可以教会刚入行的小白如何实现Java代码向Stream消息队列发送消息失败。本文将按照以下流程展示步骤,并提供相应的代码和注释。流程图以下是实现该功能的整体流程图:步骤动作1.创建Stream连接......
  • get请求与post请求发送普通参数
        ......
  • 发送请求忘记指定协议方式,日志com.jcraft.jsch.JSchException: java.net.ConnectExcep
      2023-07-1319:06:51.487-ERROR17629---[http-nio-192.168.2.206-36093-exec-8]c.t.b.p.b.c.common.util.sftp.SftpPool:com.jcraft.jsch.JSchException:java.net.ConnectException:拒绝连接(Connectionrefused)_atcom.jcraft.jsch.Util.createSocket(......
  • Email代表发送
    一、代表发送1、需实现如图所示的功能: 答复时直接答复被代表者 2、参考资料https://stackoverflow.com/questions/44402582/send-email-using-on-behalf-of-using-apache-common-emailhttps://stackoverflow.com/questions/27343725/com-sun-mail-smtp-smtpsenderfailede......
  • gitlab 发送邮件配置
    通过docker安装gitlab后配置邮箱```vim/etc/gitlab/gitlab.rb``` ```gitlab-ctlreconfigure``````gitlab-railsconsoleNotify.test_email('[email protected]','邮件标题','邮件正文').deliver_now```  结束......
  • 云服务器的连接,客户端出现“服务器发送了一个意外的数据包。received: 3,expected: 2
    云服务器的连接,客户端出现“服务器发送了一个意外的数据包。received:3,expected:20的解决方案编辑/etc/ssh/sshd_config文件并添加四行代码ClientAliveInterval60ClientAliveCountMax3PermitRootLoginyesKexAlgorithmscurve25519-sha256@libssh.org,ecdh-sha2-......