6

软件设计中你考虑过重试了吗? - 刘牌

 1 year ago
source link: https://www.cnblogs.com/steakliu/p/17439460.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

你好,我是刘牌!

人生做事情失败了,拍拍裤子,站起来再试试,那么为啥软件中请求失败了为何就放弃了,而不是不再试试呢!

今天分享一下重试操作,我们知道网络是不可靠的,那么在进行网络请求时,难免会出现请求失败,连接失败等情况,为了保证软件的稳定性和良好的体验,很多时候我们不应该将程序内部出现的问题都抛出给用户,而是应该尽最大可能将软件内部不可抗拒的问题在程序内部处理掉,那么很多时候我们会采取重试操作。

背景和问题

程序产生网络故障或者其他一些故障是无法避免的,可能因为一些原因导致某些服务在短时间或者一段时间断连,可能是服务器负载过高而导致的,也可能是数据库导致故障从而影响服务,也可能是GC过于频繁而导致服务很不稳定等等,总之,导致服务不可用的因素很多很多。

对于程序的出错,如果不属于业务上的异常,不应该抛给用户,比如抛出“无法连接远程服务”,“服务器负载过高”,“数据库异常”这类异常给用户实际上没有任何意义,反而会影响用户用户体验,因为用户并不关心这些,他们也读不懂这些领域词汇,所以应该去避免这些问题。

程序发生异常是无法避免的,我们只有采取一些补救措施,在最大程度上提高程序的稳定性和用户体验,对于程序产生的问题,有一些可能只是瞬时的,系统能够很快恢复,有一些需要一定的时间,而有一些需要介入人工,所以需要花费的时间更多,那么就需要根据不同的情况来处理,下面对其进行分类。

当系统中的异常是暂时无法处理的,这时候就应该直接取消任务,因为如果不取消,而是让用户一直等待,那么就会导致用户的操作无法进行下一步,而是一直等待,用户体验就会变得很差,这时候应该给用户友好的提示,提醒他们稍后再进行办理,浪费别人的时间等于谋财害命。

如果请求因为网络原因或者服务短暂的不可用,这种故障时间很短,很快就能恢复,比如一些服务是多实例部署,刚好请求到的那个服务出现网络故障而没能请求成功,如果我们直接返回异常,那么肯定不合适,因为其他服务实例还能提供服务,所以应该对请求进行重试,重试后可能请求到了其他正常的服务,即使请求到了之前的服务,那么可能它已经恢复好了,能够正常提供服务了,这里重试是没有时间间隔的,是不间断地请求,直到请求成功,这种适用于服务很够很快恢复的场景。

间隔重试就是不会一下进行重试,而是隔一个时间段再进行重试,比如一些服务因为过于繁忙导致负载过高而暂时对外提供服务,那么这时候如果不断发起重试,只会导致服务负载更高,我们应该隔个时间段再进行重试,让服务处理堆积的任务,等服务负载降下来再重试,这个时间间隔需要我们进行考量,按照合适的值去设置,比如1s,这完全根据实际场景去衡量。

上面对三种方案进行描述,我们只描述了重试,但是重试次数也是我们要去考量的一个值,如果一个服务20s才恢复,那么我们重试20秒肯定不太合适,不过也要看具体业务,面向客户的话肯定大多客户接受不了,这时候我们应该设置重试次数,比如重试了三次还不能成功,那么久取消任务,而不是一直重试下去。

重试次数也要根据实际情况来设置,如果一直重试,而服务一直无法恢复,那么也会消耗资源,并且用户导致用户请求一直在等待,用户体验不好,设置设置次数过少,那么可能会导致没有足够重试,从而导致浪费了一些重试次数,最后还没有成功,如下,第三次就重试成功,如果设置为两次,那么前两次没有成功就返回,用户还需重新再发起请求。

从上面可以看出,这些设置都没有黄金值,而是需要我们根据业务和不断地测试才能找出合适的值。

怎么重试,参数怎么管理

上面对重试进行一些理论的讲解,那么在实际场景中我们应该如果去做呢,首先要考虑我们的业务中是否真的有必要重试,如果没必要,那么就完全没必要去增加复杂度,如果需要,那么就需要进行良好的设计,保证其优雅和扩展性。

不同的业务有不同的重试逻辑,所以我们需要在不同的地方实现不同的逻辑,但是重试次数和重试时间间隔这些参数应该是需要可动态配置的,比如今天服务负载过高,那么时间间隔可以设置稍微长一点,次数可以设置多一点,然后负载较低的时候,参数可以设置小一点,这些配置信息可以写入配置中心中。

也有一些重试框架供我们使用,比如spring-retry,我们可以借助一些框架来管理我们的重试任务,更方便管理。

以上对重试的一些介绍就完了,我们介绍了重试的场景,重试产生的背景,还有一些解决方案,还对重试的一些管理进行介绍,重试的方案很多,实现方式也有很多,它不是固定的技术,而是一种思想,也是我们在软件设计中应该考虑的一个点,它能提高软件的稳定性和用户体验,但是也需要我们进行考量。

今天的分享就到这里,感谢你的观看,我们下期见!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK