我们有一个用例,对于单个传入请求,微服务必须向其他微服务发出许多(在最坏情况下为1000次)传出HTTP调用,以获取一些详细信息。我们的服务是使用Scala、Http4s和Cats-Effect构建的,并且使用http4s-flze客户端库进行出站HTTP调用。
目前正在生产中,我们看到了失败的org.http4s.client.WaitQueueFullFailure: Wait queue is full和org.http4s.client.PoolManager: Max wait queue limit of 1024 reached, not scheduling。一旦服务进入这种状态,它就永远无法从它中恢复,我们就完全被封锁了。
下面是我们正在使用的Blaze客户端配置:
BlazeClientBuilder[F](global)
.withMaxWaitQueueLimit(1024)
.withRequestTimeout(20.seconds)
.resource
.map { client =>
ResponseLogger(logHeaders = false, logBody = true)(
RequestLogger(logHeaders = true, logBody = true, redactHeadersWhen = Middleware.SensitiveHeaders)(client)
)
}最初,我们使用最大等待队列限制的默认设置256,但随后决定增加到512,然后增加到1024。目前,即使是1024也无法工作。
我不确定当出站HTTP请求缓慢或超时时是否会发生这种情况。有时API响应可能很慢(但这仍然会在我们设置的20秒超时内返回)。但是,我没有足够的证据来声称这是事实。
我们目前使用的版本是http4s-blaze client_2.13:0.21.0-M6。
我不知道进一步增加轮候队伍是否有帮助。是否可以在服务中实现自定义逻辑,以检查等待队列大小,并在向客户端提交请求之前等待?请建议如何处理这个问题。任何帮助都会很感激的。
发布于 2022-05-19 21:16:54
根据评论,maxWaitQueueLimit只是“在任何特定时间等待连接的最大请求数”。那么,如果等待队列已满,检查等待队列大小和等待的意义是什么?http4s已经在等你了。主要的区别是,如果您自己实现等待(例如,每次执行HTTP请求时使用信号量并获得许可证),那么您可以等待的请求没有限制。这意味着当您的服务器上有高负载时,您将耗尽内存并崩溃。这大概是maxWaitQueueLimit最初应该阻止的事情。
现在,当您执行大量请求时,它们都在http4s等待队列中结束,除了那些可以找到连接的请求。maxTotalConnections的默认值是10,所以当您发出1000个请求时,990将在等待队列中结束。如果此时出现了另一个触发超过34个请求的请求,那么您已经溢出了等待队列。考虑到您的情况,进一步增加maxWaitQueueLimit在我看来是完全合理的。假设您无法以某种方式减少所需HTTP请求的数量,也就是说。
https://stackoverflow.com/questions/72291225
复制相似问题