2017-06-22 71 views
0

我有一個使Http調用到外部服務的actor。有時服務會使用Http 404進行響應,並且有時也會出現http連接錯誤。再次重試時,這些都會消失。重試來自Akka Actor的http調用的正確方法是什麼

什麼是由演員重試請求的最佳方式。

什麼,我能想到的是

  1. 使用主管戰略和重啓演員

  2. 使用在重試HTTP調用演員遞歸方法, 最大重試次數次

哪一個是正確的方法,1或2.我認爲方法1對於像重試一個Http調用那樣簡單的事情來說是過度的。請分享你的建議。

回答

1

在我看來,你的兩種方法都是有效的。

第一種方法是在我的眼睛擁抱失敗,讓演員只能做它應該做的(而不是讓它處理重試等)

有方面要做到這一點更被動的方式一個整潔的東西建在Akka監督:BackoffSupervisor

在我看來,這是一個完美的適合問題,其中演員由於外部因素失敗,它可能是有道理的等待一段時間再試一次(如在你的情況與http調用)。

從文檔:

val supervisor = BackoffSupervisor.props(
    Backoff.onFailure(
    childProps, 
    childName = "myEcho", 
    minBackoff = 3.seconds, 
    maxBackoff = 30.seconds, 
    randomFactor = 0.2 // adds 20% "noise" to vary the intervals slightly 
)) 

您可以定義一個最小和最大的補償和監管當局嘗試,直到達到最大重啓演員之前兩倍的等待時間。只有這樣它纔會停止嘗試。

如果你喜歡你的第二個選擇,我不會用遞歸方法去,但會schedule a message到演員本身在一段時間後再次嘗試HTTP調用:

system.scheduler.scheduleOnce(1 seconds, self, TryAgain) 
+0

感謝您的建議 –

0

我倒是建議使用「之後」模式。這可以讓你在失敗的情況下重複你的請求。類似這樣的:

def retryRequest(ref: ActorRef, attemptsNumber: Int, step: Int)(
    implicit ac: ActorSystem): Future[HttpResponse] = { 

    implicit val timeout = Timeout(5 seconds) 
    implicit val ec = ac.dispatcher 

    val s1 = after[HttpResponse](5 seconds, ac.scheduler) { 
    Http().singleRequest(HttpRequest(uri = "http://akka.io")) 
    } 
    s1 flatMap { res => 
    res match { 
     case HttpResponse(StatusCodes.NotFound, headers, entity, _) => { 
     if(step < attemptsNumber) 
      retryRequest(ref, attemptsNumber, (step + 1)) 
     else 
      s1 
     } 
     case HttpResponse(StatusCodes.OK, headers, entity, _) => s1 
    } 
    } 
} 
+0

這也是一個不錯的選擇 –

相關問題