当前位置: 首页 > 科技观察

微服务系统RPC超时重试,你确定你懂?

时间:2023-03-17 16:15:13 科技观察

今天给大家分享一个知识点,我们平时开发RPC通信的系统时,经常会设置两个参数,timeout和retry。如果这两个参数设置不当,我们的系统可能会被破坏,但是这里的问题可能很多人都不知道,所以今天就来说说。业务系统架构图首先我们先从一个话题说起,就是我们平时开发什么样的系统?其实简单来说就是用SpringBoot+SSM开发一套业务代码,然后用Nacos+Dubbo来RPC调用其他系统。这个架构图很简单,如下图:微服务项目技术难点一:RPC超时机制所以两个系统在进行RPC调用的时候,其实有两个参数很关键,一个是timeout超时时间,一个是retry重试次数。这个timeout超时一般用于什么样的场景?你可以想象一个场景。如果我们不设置timeout超时时间,有没有可能你调用的系统可能会失败,或者挂掉,或者它的性能突然很慢,导致你调用他好几秒回不来。如下图所示:如果你调用一个系统很长时间无法返回,会导致什么问题?我们需要知道你自己的系统是依赖线程来接收外部请求的。假设我们通过SpringBoot内嵌的Tomcat接收外部请求,那么Tomcat实际上会开启很多线程。每一个Http请求都来了,每一个请求都是要交给一个线程去处理的。如下图所示:一个线程拿到请求并开始处理后,会调用其他系统。如果在调用其他系统的过程中失败,调用时间会过长,有好几秒没有反应。响应,此时会发生什么?那可不容易,会导致Tomcat的一个线程阻塞几秒,无法处理其他请求。那么这个时候如果因为调用一个服务所有的线程都阻塞了,会不会导致没有线程去处理新的请求呢?如下图所示:所以,一般来说,我们一般要为其他服务RPC调用设置一个超时时间。比如设置timeout=1s,就是说如果我们调用其他系统超过1s没有响应,我们就会抛出异常返回,这样就可以避免我们的Tomcat线程长时间阻塞。如下图所示:微服务项目技术难点二:RPC重试机制除了timeout超时,还有一个参数就是retry,也就是说如果你的RPC调用一个服务失败了,这时候你可以自动做一个通过重试设置重试。比如可以自动重试2次。如果此时由于偶尔的网络抖动导致调用失败,重试2次即可成功完成。如下图所示:生产项目中的超时和重试一般有哪些设置?好了,超时和重试这两个参数说完了,我们就来说说这两个参数设置不当会导致系统故障。先说超时。设置这个超时时间一定要小心,因为如果设置不小心,可能会导致你的系统无故直接崩溃。比如你把这个timeout设置得太长,比如5s或者10s,那么在极端情况下,比如对方系统故障,每次请求返回需要5s或者10s,这样会导致上面提到的问题吗?也就是Tomcat的每个线程在返回之前都要阻塞5s或者10s,这让你的系统无法处理新的请求。如下图所示:那么超时时间设置得太短怎么办?比如设置timeout=500ms,嗯,这也可能有很大的问题。因为有可能有一天,由于活动流量比较大,你调用的系统压力大,导致CPU负载高,然后平时的请求300~400ms就可以返回,但是今天是500~600毫秒。超时时间刚刚过去。这时候,当大量请求即将处理完,想要返回时,结果一到500ms就抛出超时异常,一到500ms就抛出超时异常。如下图所示:所以,timeout超时参数设置一般都是这样设置的。对于你要调用的系统,你需要看看通常需要多长时间才能返回,然后比正常的耗时设置长50%。.比如正常时间一般是100~200ms,偶尔峰值会是500ms,所以可以设置timeout=800ms或者1s。然后是retry参数,不能随意设置,尤其是一些调用其他系统写数据的接口。如果你在其他服务的写接口上设置了重试,可能会出现某个写接口时间稍长的场景,导致超时错误,你重新尝试重试。这可能会导致数据重复。所以一般建议读接口可以设置retry参数,写接口最好不要设置。好了,今天关于RPC超时和重试参数的分享就到这里了。