许多库包装了一些外部通信。 它可以是类似REST的API,消息队列,数据库,邮件服务器或其他东西。 因此,您必须有一些超时时间-用于连接,读取,写入或空闲。 遗憾的是,许多库的默认超时设置为“ 0”或“ -1”,这意味着“无穷大”。
这是一个非常无用甚至有害的默认设置。 没有实际的用例,您要永远等待资源。 在很多情况下都可能发生这种情况,例如另一端卡住了。 在过去的3个月中,我有2个库的默认超时时间为“ infinity”,最终导致生产问题,因为我们忘记正确配置它们。 有时,直到线程池用完为止,您甚至看不到问题。
因此,我向API /库设计人员提出了要求(就像我之前所做的那样- 针对属性映射和UTF-8以外的编码 )。 永远不要将“ infinity”作为默认超时。 因此,您的库将导致很多生产问题。
还要注意,有时它是底层HTTP客户端(或Socket),没有合理的默认值-打包时仍要解决此问题。
您应该提供什么默认值? 合理。 5秒? 您可能(正确)说您不想对用户强加任何超时。 在这种情况下,我有一个更好的建议:
明确要求超时来构建“客户端”(因为这些库通常是某些外部系统的客户端)。 例如Client.create(url, credentials, timeout)
。 如果未提供超时,则失败。 这使客户的用户可以积极地考虑什么是他们的用例的良好超时时间-不施加任何要求,最重要的是-不冒生产中卡死的风险。 此外,您仍然可以为他们提供“默认”选项,但仍然让他们明确选择它。 例如:
Client client = ClientBuilder.create(url)
.withCredentials(credentials)
.withTimeouts(Timeouts.connect(1000).read(1000))
.build();
// OR
Client client = ClientBuilder.create(url)
.withCredentials(credentials)
.withDefaultTimeouts()
.build();
上面的构建器应该要求设置“超时”,并且如果两个方法都未调用,则应该失败。 即使您不提供这些选项,至少也有一种指定超时的好方法–有些库需要进行反射以设置其基础客户端的超时。
我相信这是看起来很小的问题之一,但在现实世界中会引起很多问题。 并且它可以(并且应该)由库/客户端设计者解决。
但是由于并非总是如此,因此我们必须确保每次使用第三方库时都配置超时。
翻译自: https://www.javacodegeeks.com/2017/03/infinity-bad-default-timeout.html