我的服务是DService,我是服务链中的第四个环节,即呼叫流程是在线用户-> AService -> BService -> CService -> DService -> EService。
当我从EService调用DService时,它可以抛出可检索的异常,比如HttpTimeoutException。我通常会三次重试2-3次,如果它在2-3次重试后失败,我会抛出一个异常。
我的问题是,我向CService抛出的例外,是可检索的还是不可检索的?请在下面找到我对两种选择的Pros & Cons的评估
Cons从DService抛出可检索异常--如果DService抛出可检索异常,按照相同的约定,CService也可能重试DService 2-3次,而在and的每次调用中,D将再次尝试2-3次对E服务调用。同样,随着调用链的上升,最终对EService的调用将呈指数级增长。因此,如果EService网络确实长期瘫痪,我们谈论的是大量不必要的呼叫。这可以通过对链中的每个调用进行超时来缓解,但仍不确定这是否足以缓解不必要数量的调用。
从DService抛出可检索异常的DService Pros--在以后的重试中,我们可能会得到正确的值(在时限内)--特别是如果客户端是一些后端作业,那么在放弃之前,它们可以成倍地重试很长一段时间。抛出不可检索的异常将排除此选项。
请提供您对此的意见和建议。
谢谢你,哈里什
发布于 2016-03-11 11:26:44
如果不知道服务是做什么,DService应该重试还是CService应该重试,我就不能肯定地说。然而,我的哲学是,被召唤的服务不应该是重新尝试的,永远不会。在这种情况下,EService会愚蠢地抛出异常,而不需要任何处理。这背后的原因是,链的末端应该是无状态的,不应该代表调用方做出决定。
调用者可以在一定程度上在什么是可接受的范围内,什么不是关于是否应该重新尝试错误的范围内。换句话说,如果EService试图执行到数据库的连接,而DService正在执行查找服务,那么它可能在DService的范围内说,如果某个特定的信息没有在某个表中找到,那么就可以在另一个表中签入。但是,EService无法连接到数据库就超出了DService的范围,其范围只是返回CService请求的信息。
CService调用了检索某些信息,这取决于它所做的工作,然后可能会接收到数据库连接,并在延迟之后尝试多次重试,因为它正在对该数据执行批处理工作,并且将继续重试,直到数据库恢复联机为止。或者,如果它正在检索要在网页上向用户显示的信息,则必须快速失败,并通过向用户提供一个很好的错误消息来处理数据库连接错误。
这完全取决于你的服务做什么和他们的责任在哪里。同样,异常是否可检索同样取决于调用方的需要,而不是服务本身。向调用方呈现一个只尝试一次的可检索异常是完全可行的。
希望这能帮上忙!
发布于 2016-03-11 11:24:06
我认为如果在链上定义指数增长的重试周期,抛出可检索异常是一种可行的方法。
发布于 2016-03-11 11:22:51
我想说的是,您不应该在DService中重新尝试,因为,正如您所说的,如果每个服务都这样做了,您可能会遇到麻烦。因此,让异常鼓起调用堆栈,并让它在尽可能多的外部服务中处理;甚至可以是用户。
理由:为什么要由DService来决定CService、BService或AService是否愿意重试?
然而,我认为这也取决于例外的频率和重审的成功率。如果异常频繁发生,但调用通常在第一次或第二次重试时成功,则与每天发生一次的异常相比,这是另一回事,而且/或重新尝试在大多数情况下都是徒劳的。
https://stackoverflow.com/questions/35938683
复制相似问题