八张架构图告诉你如何优雅地设置RPC超时重试

开发 架构
今天给大家分享一知识点,是关于我们平时开发系统做 RPC 通信的时候,经常会设置超时和重试两个参数。

目录

  • 业务系统架构图
  • 微服务项目技术难点 1:RPC 的超时机制
  • 微服务项目技术难点 2:RPC 的重试机制
  • 生产项目中 timeout 和 retry 一般设置成多少呢?

今天给大家分享一知识点,是关于我们平时开发系统做 RPC 通信的时候,经常会设置超时和重试两个参数。

关于这两个参数要是没有设置好的话,很可能会导致我们的系统被搞垮,但是可能很多人都不知道这里面的问题,所以今天给大家好好讲讲。

业务系统架构图

首先,我们还是先引出一个话题,那就是平时我们开发的系统是什么样的?其实往简单了说,就是用 SpringBoot+SSM 开发一套业务代码,然后用 Nacos+Dubbo 去 RPC 调用别的系统。

这个架构图非常简单,如下所示:

微服务项目技术难点 1:RPC 的超时机制

那么在两个系统进行 RPC 调用的时候,有两个参数其实是至关重要的,一个是 timeout 超时时间,一个是 retry 重试次数,这个 timeout 超时通常用于什么场景呢?

大家可以想象一个场景,如果说我们不设置 timeout 超时时间,是否可能出现这样一种情况,就是你调用的那个系统可能故障了,或者是挂了,或者是他的性能突然很慢很慢,导致你调用他好几秒都没法返回。

如下图:

如果要是你调用一个系统时间很久都没法返回,此时会导致什么问题?

我们要知道,你自己这个系统对外接收请求靠的是线程,假设我们是 通过 SpringBoot 内嵌 Tomcat 对外接收请求的,那么其实 Tomcat 就会开很多线程,每个 Http 请求过来了,每个请求都是要交给一个线程来处理的。

如下图所示:

那么一个线程拿到了一个请求开始处理之后,他就会去调用别的系统,如果要是调用别的系统这个过程中因为他故障了,导致调用时间超长,好几秒都没个响应,这个时候会怎么样呢?

那还不简单,这会导致 Tomcat 一个线程一直阻塞好几秒都没法去处理别的请求。那么这个时候,如果所有线程都因为调用一个服务被阻塞住了,是不是就导致新的请求过来没有一个线程可以处理了?

如下图:

所以说,往往来说,我们对于别的服务 RPC 调用一般都得设置一个超时时间,比如说,设置 timeout=1s,那么意思就是说,我们调用别的系统如果超过 1s 没有响应,就直接抛个异常就返回了,这样就可以避免我们的 Tomcat 线程 长时间阻塞了。

如下图:

微服务项目技术难点 2:RPC 的重试机制

那么除了这个 timeout 超时时间以外,还有另外一个参数是 retry,这个 retry 的意思,就是说如果你 RPC 调用一个服务要是失败了,此时就可以通过 retry 设置自动做一个重试。

比如说自动可以重试 2 次,那么这个时候如果是因为网络偶然抖动导致的调用失败,就可以通过重试 2 次让他能够成功完成调用了。

如下图:

生产项目中 timeout 和 retry 一般设置成多少呢?

好了,现在 timeout 和 retry 两个参数讲完了,下面就可以讲这两个参数设置不当是如何导致系统出现故障的了。

先来说这个 timeout,这个 timeout 设置可一定要慎重啊,因为如果要是设置的不谨慎,可能导致你的系统莫名其妙就直接跨掉了。

比如说,这个 timeout 你要是设置的时间太长了,好比说 5s,10s,那么可能在极端情况下,比如对方系统故障了,你每个请求都要 5s、10s 才能返回,那不就会导致刚才上面说的问题了?

就是 Tomcat 每个线程都得阻塞 5s、10s 才能返回,这就导致你的系统没法处理新的请求了。

如下图:

那么如果要是 timeout 设置的太短了呢?比如说设置 timeout=500ms,那好,这可能也有很大问题了。

因为有可能某一天因为搞活动流量比较大,你调用的系统因为压力比较大,导致他的 CPU 负载很高,然后平时一般请求都是 300~400ms 可以返回,结果今天搞成 500~600ms 了,刚好超过了 timeout 时间。

此时就会导致,你大量的请求即将处理完毕要返回的时候,结果一到 500ms 就超时异常抛出,一到 500ms 就超时异常抛出。

如下图:

所以说,timeout 超时参数设置,通常是这么设置的,对于你要调用的系统你要看看他平时调用要多久能返回,然后比正常的耗时设置的多个 50% 就可以了。

比如平时一般正常在 100~200ms,偶尔高峰会在 500ms,那你设置个 timeout=800ms 或者 1s 其实都可以。

然后就是 retry 这个参数,这个参数也是不能胡乱设置的,尤其是对于一些调用别的系统写入数据的接口。

如果你要是对别的服务的写接口设置了 retry,就可能有这样一种场景,某一次写入接口可能耗时稍微长了一些,导致了超时出错,结果你又 retry 再次重试写入,就可能导致数据会有重复的问题。

所以说通常都建议 retry 参数对读接口可以设置一下,但是对写接口最好是不要设置。

好了,今天关于 RPC 超时和重试参数的分享就到这里了。

责任编辑:姜华 来源: 石杉的架构笔记
相关推荐

2020-06-15 08:54:46

架构图 EA业务建模

2022-11-11 17:09:55

微服务RPC

2021-11-22 10:38:23

架构运维技术

2021-01-20 06:02:24

数据分析驱动

2020-06-22 08:23:42

阿里技术架构图

2024-01-05 07:55:39

Linux虚拟内存

2021-12-06 07:15:47

Pulsar地域复制

2021-03-24 10:20:50

Fonts前端代码

2020-10-29 07:08:44

架构数据技术

2023-09-19 08:28:32

DiagramsPython工具

2019-03-14 15:59:44

前端开发编程

2020-07-07 07:30:33

技术IT架构

2023-07-26 00:40:25

AI工具备忘录

2020-09-04 09:55:25

TikTok程序禁令

2024-11-13 16:37:00

Java线程池

2020-09-09 08:30:42

内网隐蔽端口

2022-06-07 08:59:58

hookuseRequestReact 项目

2020-03-26 11:04:00

Linux命令光标

2021-01-18 13:17:04

鸿蒙HarmonyOSAPP

2022-05-13 21:20:23

组件库样式选择器
点赞
收藏

51CTO技术栈公众号