重试

954 发布于: 2021-03-25 读完约需 3 分钟

默认情况下,只要客户端已知集群中有节点,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个节点的集群时,可能希望确保重试只发生固定的次数。这可以在ConnectionSettingsMaximumRetries(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 }
    }
);

版权声明:本作品系原创,版权归码友网所有,如未经许可,禁止任何形式转载,违者必究。

本文永久链接码友网 » Elasticsearch.NET/NEST中文文档(教程) » 重试 分享:

发表评论

登录用户才能发表评论, 请 登 录 或者 注册