重试,让程序更健壮

这篇具有很好参考价值的文章主要介绍了重试,让程序更健壮。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

任何通过网络与其它应用通讯地的程序,都应该有足够的灵活性,来应对短暂的临时性故障。因为这些故障很多时候是可以自恢复的。

例如,为了避免服务过载,很多应用会采取某些限流措施,在并发请求达到一定数量时,暂时性的拒绝新的请求加入。这种情况下,尝试使用该应用的程序,一开始可能会被拒绝连接,但下一刻就好了。

因此,在设计系统时,应该考虑到此种故障。并且在条件允许时,加入重试机制,自动再次发起相应的请求。在某些情况下,可能会显著的改善应用程序的用户体验。

重试,让程序更健壮

能否发起重试,最重要的前提之一是,对同一资源的发起多次相同的请求,能否得到相同的结果。即资源接口是否具有幂等性。

标准 REST API 中,GET/HEAD/OPTIONS 通常是不会更改服务器上的资源的,因此大多是可重试的。

换个说法就是,如果能够确定,下次请求有可能成功,那就可以尝试重试。否则的话,就不必浪费时间、精力以及系统资源了。

例如,在请求 HTTP 服务时,收到 503 或 408 这样的状态码,则重试可能会有效;但是如果收到了 401 或 403 之类的状态码,则简单的重试肯定不起作用。

确定了什么情况下发起重试后,还有另外一个问题值得考虑。即在什么时间、以什么样的频率发起重试。尽管可以,但通常并不会是请求失败后,立即发起重试,而是需要根据具体的场景,选择合适的重试
时机。

假如说我们请求失败的原因,是服务端请求过载。则立即发起重试,除了给服务端添乱外,不会有其它结果。严重情况下,可能会加剧服务器的负担,直到耗尽服务器资源。

为了避免上述问题,常见的做法是在重试之前增加一些延迟。但是如何增加这些延迟,又有多种策略,比较多使用的有两种:

  • 固定间隔。即每次请求失败后,都等待固定的时间后,再次发起下次重试请求;
  • 指数递增。即多次请求之间的延时,成倍增加;

如果失败是由服务端过载引起的,则后一种策略可能会更好。假如它的初始请求在 0ms 发出,则第二次请求在失败 200ms 后发出,第三次请求在失败 400ms 后发出,第四次在 800ms... 以此类推。这种分散的请求和重试机制,可能有助于减缓客户端及服务器的负载,提高我们最终获取到成功结果的机会。

但是假如所有的请求都从同一时刻发起,并按照同样的机制延时重试,则两种策略是一样的,并不会有所改进。这种情况下,可能需要加入一些随机因素。

扯的有点多,接下来搞些实际的,上一点儿代码。简单起见,这里演示一下在 JavaScript 中的实现,使用诸位都了解的 axios。Axios 提供了拦截器机制,用来处理通用的重试逻辑正合适。

const SLEEP_TIME = 200;
const RETRY_TIMES = 3;
const RETRY_STATUS = [408, 503, 504];

function getSleepTime(i = 0) {
  const wTime = Math.min(SLEEP_TIME * 2 ** i);
  return Math.random() * wTime;
}

async function fakeSleep(ms) {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, ms);
  });
}

async function onError(error) {
  const { status } = error.response;
  let { retryCount = 0 } = error.response.config;

  if (RETRY_STATUS.includes(status) && retryCount < RETRY_TIMES) {
    retryCount += 1;
    sleep_ms = getSleepTime(retryCount);
    await fakeSleep(sleep_ms);

    error.config.retryCount = retryCount;
    return await axios(error.config);
  }
}

axios.interceptors.response.use(onError);

代码不多,应该不需要额外的解释。其它编程语言,实现思路大致也差不多。相信您肯定可以写出更好的。

欢迎批评指正。

作者:袁首京

原创文章,转载时请保留此声明,并给出原文连接。文章来源地址https://www.toymoban.com/news/detail-410532.html

到了这里,关于重试,让程序更健壮的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序

    虚拟桌宠模拟器:VPet-Simulator,一个开源的桌宠软件, 可以内置到任何WPF应用程序

    虚拟桌宠模拟器 一个开源的桌宠软件, 可以内置到任何WPF应用程序 获取虚拟桌宠模拟器 OnSteam(免费) 或 通过[Nuget]内置到你的WPF应用程序 虚拟桌宠模拟器是一款桌宠软件,支持各种互动投喂等. 开源免费并且支持创意工坊. 反正免费为啥不试试呢( 该游戏为 [虚拟主播模拟器] 内

    2024年02月08日
    浏览(17)
  • 通过一次线上问题,讲下Ribbon重试机制

    通过一次线上问题,讲下Ribbon重试机制

    前段时间,产品经理在线上验证产品功能的时候,发现某个功能不符合需求预期,后来测试验证发现是服务端的一个接口大概率偶现超时,前端做了兜底处理,所以对线上用户么有太大影响。 由于服务端的接口偶现超时,并且网关设置了30s超时熔断,所以前端请求就直接报错

    2024年02月15日
    浏览(12)
  • 提高程序的健壮性:异常处理机制可以避免程序因错误而崩溃,让程序在某些情况下可以沉默”,从而保证程序的运行安全;

    作者:禅与计算机程序设计艺术 在软件开发过程中,随着应用的不断迭代更新、功能的增加、人员的变动等原因,软件的质量会逐渐下降,出现各种各样的bug、缺陷、漏洞等。这些bug或许能够影响系统的正常运行,或者导致系统崩溃甚至数据丢失。因此,如何在软件的设计中

    2024年02月11日
    浏览(7)
  • [禁止登录]登录失败,建议升级最新版本后重试,或通过问题反馈与我们联系。(错误码:45)

    [禁止登录]登录失败,建议升级最新版本后重试,或通过问题反馈与我们联系。(错误码:45)

    token失效:[禁止登录]登录失败,建议升级最新版本后重试,或通过问题反馈与我们联系。(错误码:45。 [禁止登录]登录失败,建议升级最新版本后重试,或通过问题反馈与我们联系。 使用go-cqhttp开发QQ机器人的时候遇到的问题,登录的时候报错。 新版的go-cqhttp说的是不需要签名

    2024年02月16日
    浏览(7)
  • 【网络问题】微软商店无法打开:重试该操作,无法加载页面。请稍后重试

    【网络问题】微软商店无法打开:重试该操作,无法加载页面。请稍后重试

    有的时候,明明我们的网络连接是正常的,但是却出现诸如某些应用的网络是是正常的,但是网页却打不开的情况。也有可能像下面这种情况一样,别的应用网络正常,但是微软商店打不开,显示“重试该操作,无法加载页面。请稍后重试”的提示或者onenote for windows 10打不开

    2024年02月12日
    浏览(13)
  • HarmonyOS 通过Web组件嵌套网络应用

    HarmonyOS 通过Web组件嵌套网络应用

    我们今天来说说 在程序中嵌套一个网址地址 HarmonyOS中是通过一个简单的WEB组件来实现 网络应用就是相当于网址地址 通过链接将应用嵌入到手机当中 WEB组件需要两个参数 一个是 src 地址 要嵌套的网址 另一个是 控制器 我们可以先编写代码如下 这里 我们导入了 webview 然后通

    2024年01月23日
    浏览(10)
  • java通过http头部信息如何判断是ipad、安卓手机还是苹果手机 或者是其它设备...

    在Java中使用HttpServletRequest对象的getHeader(\\\"User-Agent\\\")方法可以获取到客户端发送过来的User-Agent信息。根据这个信息,可以判断客户端是哪种设备。 对于iPad,User-Agent信息通常包含\\\"iPad\\\"字样;对于安卓手机,包含\\\"Android\\\"字样;对于苹果手机,包含\\\"iPhone\\\"字样。 代码示例: 注意:不

    2024年02月13日
    浏览(16)
  • 【分布式应用】zabbix:代理服务器、及监控其它应用

    【分布式应用】zabbix:代理服务器、及监控其它应用

    分布式监控的作用: 分担 server 的集中式压力 解决多机房之间的网络延时问题 agent -- proxy -- server 配置 Mariadb yum源 初始化数据库 创建数据库并指定字符集 创建 zabbix 数据库用户并授权 导入数据库信息 修改 zabbix-proxy 配置文件 在所有主机上配置 hosts 解析 点击左边菜单栏【配

    2024年02月13日
    浏览(53)
  • 移动应用安全策略不足:未对通过移动应用访问网络的安全进行适当管理

    移动应用安全策略不足:未对通过移动应用访问网络的安全进行适当管理

    随着移动互联网的快速发展,越来越多的企业和个人选择通过移动应用来访问网络资源。然而,移动应用安全策略的不足,往往导致数据泄露、恶意攻击等问题。本文将针对这一问题进行分析并提出相应的解决方案。 1. 数据泄露 由于移动设备缺乏与PC机一样的物理隔离机制,

    2024年02月01日
    浏览(16)
  • Windows 通过端口占用查找应用程序

    Windows 通过端口占用查找应用程序

    对于开发人员在启动项目的过程中也许会遇到程序使用 端口被占用的情况;如下: 遇到这种情况我们可以换一个端口,也可以查找是哪个程序暂用了这个端口;在Windows上我们可以通过如下方式去查找对应的端口程序信息。 1、打开dos命令窗口 开始—-运行—-cmd,或者是wind

    2024年02月12日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包