我目前正在實施與阿卡-HTTP斷路器如下:斷路器Scala和阿卡-HTTP REST服務
def sendMail(entity: MyEntity): ToResponseMarshallable = {
Thread.sleep(5 * 1000)
validateEntity(entity).map[ToResponseMarshallable] {
case (body, subject) if !isEmpty(body, subject) => {
val mailResponse = sendMail(body, subject)
OK -> ProcessedEmailMessage(mailResponse)
}
case _ =>
BadRequest -> s"error: for $entity".toJson
}
} catch {
case e: DeserializationException => HttpResponse(BadRequest).withEntity(HttpEntity(s"error:${e.msg}").withContentType(ContentTypes.`application/json`))
}
}
val maxFailures: Int = 2
val callTimeout: FiniteDuration = 1 second
val resetTimeout: FiniteDuration = 30 seconds
def open: Unit = {
logger.info("Circuit Breaker is open")
}
def close: Unit = {
logger.info("Circuit Breaker is closed")
}
def halfopen: Unit = {
logger.info("Circuit Breaker is half-open, next message goes through")
private lazy val breaker = CircuitBreaker(
system.scheduler,
maxFailures,
callTimeout,
resetTimeout
).onOpen(open).onClose(close).onHalfOpen(halfopen)
def routes: Route = {
logRequestResult("email-service_aggregator_email") {
pathPrefix("v1") {
path("sendmail") {
post {
entity(as[EmailMessage]) { entity =>
complete {
breaker.withCircuitBreaker(Future(sendMail(entity)))
}
}
}
}
}
}
}
我的問題是,如果我使用breaker.withCircuitBreaker(Future(sendMail(entity)))
斷路器進入開放狀態但其餘的響應返回There was an internal server error
作爲響應
相反,如果我用breaker.withSyncCircuitBreaker(Future(sendMail(entity)))
然後斷路器永不熄滅處於打開狀態,但它返回預期HttpResponse
如何解決此問題以觸發斷路器並返回正確的HTTP響應?
也可以你發佈產生'斷路器'的代碼? –
當然,我編輯 –
你需要使用'onComplete'而不是'complete'。 'complete'指令要求響應立即準備就緒。在你的情況下,'withCircuitBreaker'返回'Future',所以'complete'將不是一個有效的選項。 'onComplete'指令設置爲與'Future'一起工作,所以在這裏更合適。然後在'onComplete'回調中你可以使用'complete'。 – cmbaxter