默认情况下,只要客户端已知集群中有节点,NEST
就会对请求进行多次重试。
然而,重试仍然遵循请求超时规则,这意味着如果有100个节点的集群和20秒的请求超时,客户端将重试尽可能多的次数,然后在20秒的请求超时时放弃。
重试行为仍然可以使用NEST
的虚拟集群测试框架来演示。在下面的示例中,定义了一个有10个节点的集群,该集群在除端口9209外的所有客户端调用上总是失败:
var audit = new Auditor(() => VirtualClusterWith
.Nodes(10)
.ClientCalls(r => r.FailAlways())
.ClientCalls(r => r.OnPort(9209).SucceedAlways())
.StaticConnectionPool()
.Settings(s => s.DisablePing())
);
对客户端调用的跟踪显示,从节点9200到9208接收到一个错误的响应,最终从端口9209上的节点返回一个正常的响应
audit = await audit.TraceCall(
new ClientCall {
{ BadResponse, 9200 },
{ BadResponse, 9201 },
{ BadResponse, 9202 },
{ BadResponse, 9203 },
{ BadResponse, 9204 },
{ BadResponse, 9205 },
{ BadResponse, 9206 },
{ BadResponse, 9207 },
{ BadResponse, 9208 },
{ HealthyResponse, 9209 }
}
);
最大重试次数(Maximum number of retries)
例如,当拥有100个节点的集群时,可能希望确保重试只发生固定的次数。这可以在ConnectionSettings
的MaximumRetries(n)
来配置。
实际的请求次数将是
最初的请求次数 + 设置的重试次数
var audit = new Auditor(() => VirtualClusterWith
.Nodes(10)
.ClientCalls(r => r.FailAlways())
.ClientCalls(r => r.OnPort(9209).SucceedAlways())
.StaticConnectionPool()
.Settings(s => s.DisablePing().MaximumRetries(3))
);
audit = await audit.TraceCall(
new ClientCall {
{ BadResponse, 9200 },
{ BadResponse, 9201 },
{ BadResponse, 9202 },
{ BadResponse, 9203 },
{ MaxRetriesReached }
}
);
在前面的示例中,我们模拟了瞬时的失败调用请求,但在现实世界中,调用可能需要一秒钟以上。
在下一个示例中,我们将模拟一个需要10秒才能失败的特别复杂的搜索请求,并将请求超时设置为20秒。我们看到请求被尝试了两次,并且在尝试第三次调用之前就放弃了,因为调用需要10秒,因此可以在请求超时之前尝试两次(初始调用和一次重试)。
var audit = new Auditor(() => VirtualClusterWith
.Nodes(10)
.ClientCalls(r => r.FailAlways().Takes(TimeSpan.FromSeconds(10)))
.ClientCalls(r => r.OnPort(9209).SucceedAlways())
.StaticConnectionPool()
.Settings(s => s.DisablePing().RequestTimeout(TimeSpan.FromSeconds(20)))
);
audit = await audit.TraceCall(
new ClientCall {
{ BadResponse, 9200 },
{ BadResponse, 9201 },
{ MaxTimeoutReached }
}
);
最大重试超时时间(Maximum retry timeout)
可以通过MaxRetryTimeout
来单独配置最大重试超时时间。下面模拟调用时间为3秒,请求超时时间为2秒,最大重试超时时间为10秒。我们将看到执行该查询的5次尝试,测试我们的请求超时是否缩短了查询,以及10秒的最大重试超时是否超过了配置的请求超时
var audit = new Auditor(() => VirtualClusterWith
.Nodes(10)
.ClientCalls(r => r.FailAlways().Takes(TimeSpan.FromSeconds(3)))
.ClientCalls(r => r.OnPort(9209).FailAlways())
.StaticConnectionPool()
.Settings(s => s.DisablePing().RequestTimeout(TimeSpan.FromSeconds(2)).MaxRetryTimeout(TimeSpan.FromSeconds(10)))
);
audit = await audit.TraceCall(
new ClientCall {
{ BadResponse, 9200 },
{ BadResponse, 9201 },
{ BadResponse, 9202 },
{ BadResponse, 9203 },
{ BadResponse, 9204 },
{ MaxTimeoutReached }
}
);
如果重试策略超出了可用节点的数量,客户端将不会重试同一节点两次
var audit = new Auditor(() => VirtualClusterWith
.Nodes(2)
.ClientCalls(r => r.FailAlways().Takes(TimeSpan.FromSeconds(3)))
.ClientCalls(r => r.OnPort(9209).SucceedAlways())
.StaticConnectionPool()
.Settings(s => s.DisablePing().RequestTimeout(TimeSpan.FromSeconds(2)).MaxRetryTimeout(TimeSpan.FromSeconds(10)))
);
audit = await audit.TraceCall(
new ClientCall {
{ BadResponse, 9200 },
{ BadResponse, 9201 },
{ MaxRetriesReached },
{ FailedOverAllNodes }
}
);
发表评论
登录用户才能发表评论, 请 登 录 或者 注册