当前位置: 首页 > news >正文

【微服务架构设计】微服务不是魔术:处理超时

微服务很重要。它们可以为我们的架构和团队带来一些相当大的胜利,但微服务也有很多成本。随着微服务、无服务器和其他分布式系统架构在行业中变得更加普遍,我们将它们的问题和解决它们的策略内化是至关重要的。在本文中,我们将研究网络边界可能引入的许多棘手问题的一个示例:超时。

在你害怕“分布式系统”这个词之前,请记住,即使是一个带有 Node 后端的小型 React 应用程序,或者一个与 AWS Lambda 对话的简单 iOS 客户端,也代表一个分布式系统。当您阅读这篇博文时,您已经参与了一个分布式系统,其中包括您的 Web 浏览器、内容交付网络和文件存储系统。

在背景方面,我将假设您了解如何使用您选择的语言进行 API 调用并处理它们的成功和失败,但这些 API 调用是同步还是异步、HTTP 或不是。如果您遇到不熟悉的术语或想法,请不要担心!我很高兴在 Twitter 或其他地方进行更多讨论,并且我还尝试在适当的地方添加链接。

我们将要探讨的问题是:如果我们遇到一个非常非常慢的 API 调用最终超时,并且我们假设 (a) 它成功或 (b) 它失败,我们就会遇到错误。超时(或更糟糕的是,无限长的等待)是分布式系统的一个基本事实,我们需要知道如何处理它们。

问题


让我们从一个思想实验开始:你有没有给同事发邮件向他们要东西?

  • [星期二,上午 9:58] 你:“嘿,你能把我加到我们公司的潜在导师名单中吗?”

  • 同事:“……”

  • [星期五,下午 2:30] 你:[?]

你该怎么办?

如果您希望您的请求得到满足,您最终需要确定没有回复。你会等更长的时间吗?你想等多久?

那么,一旦你决定等待多长时间,你会采取什么行动?您是否再次尝试发送电子邮件?你尝试不同的传播媒介吗?你认为他们不会这样做吗?

好的,现在这里到底发生了什么?我们希望看到这种请求-响应行为:

05299aecbcbd799a98f6b626054ad491.png

但是出了点问题。有几种可能性:

  • 他们从来没有得到消息。

9e39a000a5bd4be590e7a13d61bc937c.png

  • 他们收到了邮件,成功处理了邮件,然后给您发回了一个从未收到您的回复(或转到您的垃圾邮件文件夹)。

fa52b63d6632b1ff09c90f0e9d5429a1.png

  • 他们得到了信息,但他们仍在思考,或者他们失去了它,或者[喘气!]他们忘记了。

396f44aba9b73bedaa30f2ea70254853.png

  • 最终,我们只是不知道!

44ea42fdc2caea02bb31f790c9a9281b.png

正是这个问题出现在分布式系统上的任何通信中。

我们可能会延迟我们的请求、处理或响应,而这些延迟可能是任意长的。因此,与电子邮件示例一样,我们需要确保“我们要等多久?”问题有答案,我们称该持续时间为超时。

如果您只从本文中学到一个教训,那就这样吧:使用超时。否则,您将面临永远等待永远不会完成的操作的风险。

但是一旦我们达到了超时,等待的上限,我们该怎么办?

方法


当人们在远程系统调用中遇到超时时,有几种常见的方法。我并不声称这份清单是详尽无遗的,但它确实涵盖了我见过的许多最常见的场景。

方法#1


当您遇到超时时,假设它成功并继续前进。

请不要这样做。[1]不幸的是,我不得不说这是一个常见的无意识选择,即使在生产应用程序中,也会有一些非常糟糕的用户体验结果。如果我们假设手术成功了,我们可怜的消费者就会合理地假设事情进展顺利——只是后来当他们发现结果时会感到失望和困惑。

任何时候你有一个网络呼叫,寻找成功和失败的案例。例如,如果你在 JavaScript 中通过 Promise.then(...) 使用异步 API,请问问自己对应的 .catch(...) 在哪里。如果它丢失了,你几乎肯定有一个错误。

在一些非常特殊的情况下,您可能理所当然地不在乎请求是成功还是失败。UDP 是具有此属性的非常成功的协议。另外,很多软件坏了,继续赚钱就好了!但请不要让这成为您的默认设置——先用尽您的其他选项。

方法#2


对于读取请求,请使用缓存或默认值。

如果您的请求是读取请求并且不打算对远程端产生任何影响,那么这可能是一个不错的选择。在这种情况下,您可以使用先前成功请求中的缓存值。或者,如果还没有成功的请求或者缓存在您的情况下没有意义,您可以使用默认值。这种方法相对简单:它不会增加太多的性能开销或实现复杂性。但请记住,如果您使用的是通过网络访问的进程外缓存(例如,memcached、Redis 等),那么您将回到类似的情况,即您的请求对缓存本身可能会超时

方法#3

当您遇到超时时,假设远程操作失败,然后自动重试。

这提出了更多的问题:

  • 如果重试不安全怎么办?网络连接另一端的服务获取重复项只是烦人吗?或者你是双重收取信用卡?(!)

  • 您应该同步重试还是异步重试

  • 如果您同步重试,从消费者的角度来看,这些重试会减慢您的速度——您是否有可能无法满足他们的期望?这在服务中尤其重要,而不是最终用户应用程序。

  • 如果你异步重试,你告诉你的消费者关于操作成功的什么?您是一次尝试一个,还是在一段时间内分批重试?

  • 您应该重试多少次?(一次?两次?10次?直到成功?)

  • 您应该如何在重试之间延迟?(指数退避[例如,1s、2s、4s、8s、16s,...] 以最大等待时间为界?使用抖动?)

  • 如果远程服务器由于过载而出现性能问题,重试是否会使他们的情况变得更糟?

如果远程 API 可以安全地重试,我们称之为幂等。如果没有幂等属性,您可能会创建重复数据(如信用卡费用的情况)或导致竞争条件(即,如果您尝试更改您的电子邮件地址两次,并且第一个在第二个完成后重试)。

在许多情况下,使自动重试安全可能需要大量的架构工作。但是,如果您可以安全地重试(例如,通过发送请求 UUID,并让远程端跟踪这些),事情就会变得非常非常简单。查看 Stripe API 以了解实际情况的一个很好的示例。

方法#4


检查请求是否成功,如果安全再试一次。

这里的想法是,在某些情况下,我们可以在超时请求之后跟上另一个请求,询问我们原始请求的状态。这种方法显然需要存在一个端点,可以为我们提供我们想要的信息。给定这样一个端点,如果端点说我们的请求成功,我们可以明确地说我们不需要重试。

但是这里有一个严重的问题,我们无法真正知道重试是否安全。因为通常我们的远程服务可以接收到请求,但仍在处理中,因此我们正在检查的查询端点将无法确认成功。当然,检查本身可能会超时!远程服务器可能由于与初始故障相同的原因而完全无法访问,但即使这是真的,我们仍然无法知道问题是在处理初始请求之前还是之后发生的。

方法#5


放弃并让用户弄清楚。

这需要最少的努力,并且可以说可以防止我们做出错误的决定,因此在许多情况下这可能是最佳选择。我们还需要问自己:我们的用户能找出正确的做法吗?他们是否有足够的信息和对其他系统的洞察力来确定如何前进

在某些情况下,让我们的消费者知道这个问题可能是最好的选择。对于任何涉及重试的方法,如果我们不想允许无限次数的重试,我们最终可能仍会退回到这条路径!

结论


所以在这一点上,事情可能看起来很黯淡。分布式系统很难,看来我们不能只选择其中一种解决方案作为灵丹妙药。如果您感到失败,请振作起来,不要让完美成为美好的敌人。

使用超时。


即使超时时间很长,比如 5 秒、10 秒或 [gulp!] 甚至更多,每个网络请求都应该有一些超时时间。选择超时可能很棘手——当请求最终成功时,您不希望有太多失败(误报),也不希望浪费太多时间并冒着不健康的应用程序的风险。您可以通过查看历史请求的分布和趋势以及您的应用程序自身的性能保证或风险概况来确定好的值。

在任何情况下,我们都不希望我们的应用服务器的队列、连接池、环形缓冲区或任何瓶颈被将永远等待的东西堵塞。您绝对可以根据您的生产需求研究并添加更高级的东西,例如断路器和隔板,但是超时很便宜并且库很好地支持。使用它们!

默认使重试安全。


除了让你的代码更简单、更安全之外,你还会说“幂等性”,这很有趣。

考虑以不同的方式委派工作。


异步消息传递在这里有一些吸引人的特性,因为您的远程服务不再需要保持快速和可用;只有您的消息代理可以。但是,消息传递/异步性并不是灵丹妙药——您仍然需要确保代理收到消息。不幸的是,这可能很难!消息代理也有权衡。您的用户对于何时需要重试会有自己的想法。例如,如果消息处理延迟,他们可能会决定重新提交,因为他们的订单尚未显示在订单历史记录中。分布式日志/流媒体平台也可能出现类似问题。如果您正在考虑消息传递路线(实际上,即使没有!),请仔细查看 Enterprise Integration Patterns — 尽管它年代久远,但其中的模式与当今的架构极为相关。

并且冒着成为派对大便的风险,不要忘记您可能能够完全移动或删除该网络边界!把一个难题变成一个简单的问题并没有什么可耻的。因此,也许您可以使用一个网络请求而不是五个,或者您可以将两个服务内联在一起。或者,也许您采用上述方法之一以可靠和安全的方式处理超时。无论您选择哪种方式,请记住,您的用户并不关心您是否使用微服务——他们只是想让事情正常工作。

本文 :https://architect.pub/microservices-arent-magic-handling-timeouts
讨论:知识星球【首席架构师圈】或者加微信小号【ca_cto】或者加QQ群【792862318】
公众号
 
【jiagoushipro】
【超级架构师】
精彩图文详解架构方法论,架构实践,技术原理,技术趋势。
我们在等你,赶快扫描关注吧。
微信小号
 
【ca_cea】
50000人社区,讨论:企业架构,云计算,大数据,数据科学,物联网,人工智能,安全,全栈开发,DevOps,数字化.
 

QQ群
 
【285069459】深度交流企业架构,业务架构,应用架构,数据架构,技术架构,集成架构,安全架构。以及大数据,云计算,物联网,人工智能等各种新兴技术。
加QQ群,有珍贵的报告和干货资料分享。

视频号【超级架构师】
1分钟快速了解架构相关的基本概念,模型,方法,经验。
每天1分钟,架构心中熟。

知识星球【首席架构师圈】向大咖提问,近距离接触,或者获得私密资料分享。 

喜马拉雅【超级架构师】路上或者车上了解最新黑科技资讯,架构心得。【智能时刻,架构君和你聊黑科技】
知识星球认识更多朋友,职场和技术闲聊。知识星球【职场和技术】
领英Harryhttps://www.linkedin.com/in/architect-harry/
领英群组领英架构群组https://www.linkedin.com/groups/14209750/
微博‍‍【超级架构师】智能时刻‍
哔哩哔哩【超级架构师】

抖音【cea_cio】超级架构师

快手【cea_cio_cto】超级架构师

小红书【cea_csa_cto】超级架构师 

网站CIO(首席信息官)https://cio.ceo
网站CIO,CTO和CDOhttps://cioctocdo.com
网站架构师实战分享https://architect.pub   
网站程序员云开发分享https://pgmr.cloud
网站首席架构师社区https://jiagoushi.pro
网站应用开发和开发平台https://apaas.dev
网站开发信息网https://xinxi.dev
网站超级架构师https://jiagou.dev
网站企业技术培训https://peixun.dev
网站程序员宝典https://pgmr.pub    
网站开发者闲谈https://blog.developer.chat
网站CPO宝典https://cpo.work

谢谢大家关注,转发,点赞和点在看。

相关文章:

【微服务架构设计】微服务不是魔术:处理超时

微服务很重要。它们可以为我们的架构和团队带来一些相当大的胜利,但微服务也有很多成本。随着微服务、无服务器和其他分布式系统架构在行业中变得更加普遍,我们将它们的问题和解决它们的策略内化是至关重要的。在本文中,我们将研究网络边界可…...

天下风云出我辈,AI准独角兽实在智能获评“十大数字经济风云企业

时值盛夏,各地全力拼经济的氛围同样热火朝天。在浙江省经济强区余杭区这片创业热土上,人工智能助力数字经济建设正焕发出蓬勃生机。 7月28日,经专家评审、公开投票,由中共杭州市余杭区委组织部(区委两新工委&#xff…...

SpringBoot2学习笔记

信息来源:https://www.bilibili.com/video/BV19K4y1L7MT?p5&vd_source3969f30b089463e19db0cc5e8fe4583a 作者提供的文档:https://www.yuque.com/atguigu/springboot 作者提供的代码:https://gitee.com/leifengyang/springboot2 ----…...

安达发|APS生产派单系统对数字化工厂有哪些影响和作用

数字化工厂是当今制造业的热门话题,而APS软件则是这一领域的颠覆者。它以其独特的影响和作用,给制造业带来了巨大的改变。让我们一起来看看APS软件对数字化工厂有哪些影响和作用吧! 提高生产效率的神器 1.APS软件作为数字化工厂的核心系统&a…...

状态机的介绍和使用 | 京东物流技术团队

1 状态机简介 1.1 定义 我们先来给出状态机的基本定义。一句话: 状态机是有限状态自动机的简称,是现实事物运行规则抽象而成的一个数学模型。 先来解释什么是“状态”( State )。现实事物是有不同状态的,例如一个自…...

tinkerCAD案例:32. 使用对齐工具构建喷泉

tinkerCAD案例:32. 使用对齐工具构建喷泉 In this lesson, you will practice the basics in Tinkercad, such as move, rotate, and scale. You will also learn how to use the Align Tool. 在本课中,您将练习 Tinkercad 中的基础知识,例如…...

一起学数据结构(2)——线性表及线性表顺序实现

目录 1. 什么是数据结构: 1.1 数据结构的研究内容: 1.2 数据结构的基本概念: 1.2.1 逻辑结构: 1.2.2 存储结构: 2. 线性表: 2.1 线性表的基本定义: 2.2 线性表的运用: 3 .线性…...

mqtt协议流程图

转载于...

7、单元测试--测试RestFul 接口

单元测试–测试RestFul 接口 – 测试用例类使用SpringBootTest(webEnvironment WebEnvironment.RANDOM_PORT)修饰。 – 测试用例类会接收容器依赖注入TestRestTemplate这个实例变量。 – 测试方法可通过TestRestTemplate来调用RESTful接口的方法。 测试用例应该定义在和被测…...

国家留学基金委(CSC)|发布2024年创新型人才国际合作培养项目实施办法

2023年7月28日,国家留学基金委(CSC)发布了《2024年创新型人才国际合作培养项目实施办法》,在此知识人网小编做全文转载。详细信息请参见https://www.csc.edu.cn/chuguo/s/2648。 2024年创新型人才国际合作培养项目实施办法 第一章…...

找好听的配乐、BGM就上这6个网站,免费商用。

推荐几个音乐素材网站给你,各种类似、风格的都有,而且免费下载,还可以商用,建议收藏起来~ 菜鸟图库 https://www.sucai999.com/audio.html?vNTYxMjky 站内有上千首音效素材,网络流行的音效素材这里都能找到&#xf…...

【前端知识】React 基础巩固(三十五)——ReduxToolKit (RTK)

React 基础巩固(三十五)——ReduxToolKit (RTK) 一、RTK介绍 Redux Tool Kit (RTK)是官方推荐的编写Redux逻辑的方法,旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题。 RTK的核心API主要有如下几个: confi…...

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案

android Android Studio Giraffe | 2022.3.1 版本Lombok不兼容 解决方案 1.查看当前的android studio 版本 Android Studio Giraffe | 2022.3.1 Build #AI-223.8836.35.2231.10406996, built on June 29, 2023 2.打开 idea 官网下载页面 idea下载历史版本 找到对应的版本编号…...

前端框架学习-基础前后端分离

前端知识栈 前端三要素:HTML、CSS、JS HTML 是前端的一个结构层,HTML相当于一个房子的框架,可类比于毛坯房只有一个结构。CSS 是前端的一个样式层,有了CSS的装饰,相当于房子有了装修。JS 是前端的一个行为层&#xff…...

数据中心电子电气设备常见的五种地线种类和做法

数据中心机房计算机系统的集成化程度很高,其正常工作对环境的要求很严格。接地,是指电力系统和电气装置的中性点、电气设备的外露导电部分和装置外导电部分经由导体与大地相连。其作用主要是防止人身遭受电击、设备和线路遭受损坏、预防火灾和防止雷击、…...

重学C++系列之STL库

一、什么是STL库 STL是“Standard Template Library”的缩写,中文翻译为“标准模板库”。CSTL是一套功能强大的C模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如字符串操作、链表、队…...

JAVA SE -- 第十四天

(全部来自“韩顺平教育”) 泛型 一、泛型 1、基本介绍 ①泛型又称参数类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题 ②在类声明或实例化时只要指定好需要的具体的类型即可 ③Java泛型可以保证如果程序在编译时没有发…...

微信小程序监测版本更新

在index.js里面 不放到app.js里面是因为有登录页面,在登录页面显示更新不太友好 onShow() {const updateManager wx.getUpdateManager()// 请求完新版本信息的回调updateManager.onCheckForUpdate(res > {if (res.hasUpdate) {// 新版本下载成功updateManage…...

《Java面向对象程序设计》学习笔记——第 2 章 基本数据类型、数组和枚举类型

专栏:《Java面向对象程序设计》学习笔记...

TDesign中后台管理系统-访问后端服务

目录 1 修改后端服务地址2 解决跨域问题3 动态获取菜单4 测试后端接口5 前后端联调总结 目前我们已经搭建了TDesign的前端和express的后端,目前是两个独立的应用。通常我们需要把前后端集成在一起,TDesign已经配置了相关的信息,只需要修改后端…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

MMaDA: Multimodal Large Diffusion Language Models

CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...