了解 AWS 开发工具包 Java 2.x(异步与同步)HTTP 客户端

Understanding AWS SDK Java 2.x (Async vs Sync) HTTP Clients

提问人:Nick 提问时间:10/12/2023 最后编辑:Nick 更新时间:11/15/2023 访问量:131

问:

AWS Java 2.x 开发工具包提供了许多不同的 http 客户端替代方案。其中两个是:

  1. 基于 Apache 的同步 HTTP 客户端
  2. AWS 基于 CRT 的异步 HTTP 客户端

为了帮助我了解 Sync 和 Async 之间的区别,我试图了解此处找到的 AWS 文档中描述的差异。

例如,在浏览他们关于使用哪种的建议时,我发现以下内容非常奇特:

建议使用基于 Apache 的同步 HTTP 客户端,以实现“低延迟 高吞吐量“,而基于 CRT 的 AWS 异步 HTTP 客户端是 建议用于“低延迟的高吞吐量”。

简而言之,基于 Apache 的同步 HTTP 客户端到底如何比异步 HTTP 客户端具有更低的延迟?我希望延迟基于网络延迟,因此您使用哪个客户端(无论是同步还是异步)完全无关紧要。

另外,异步客户端怎么可能比同步 HTTP 客户端具有更高的吞吐量,这对我来说也没有意义?我的预期恰恰相反,因为同步客户端将忙于等待响应可用,而异步客户端将在此期间执行其他操作,因此可能还没有准备好在响应到达时处理响应。

以下是上述想法的更多内容。

我的理解是,高吞吐量和低延迟是负相关的。如果增加一个,通常会减少另一个,反之亦然。当然,可能还有其他因素可能会降低吞吐量,同时保持延迟稳定。尽管如此,我看不出任何一个客户端将如何影响网络吞吐量或延迟。

对我来说,运行包装在 promise 中的基于 Apache 的同步 HTTP 客户端与直接使用异步 HTTP 客户端之一(例如 netty 或基于 CRT 的异步客户端)有什么区别,这对我来说有点令人困惑 - 我相信我理解这些差异,但让我在下面说明。

它们都使用线程池(至少,如果您使用的是基于 Apache 的同步客户端,则用于同步),它们都必须等待响应。

我猜想,当使用基于 Apache 的同步 HTTP 客户端创建 HTTP 客户端请求时,它通常会从线程池中抽取一个线程,使用该线程创建 HTTP 连接,发起请求,然后忙于等待响应,该响应将不断消耗 CPU 时间,以便线程继续轮询以查看响应是否可用。

同时,对于异步 HTTP 客户端,它遵循与上述相同的过程,只是它不忙于等待响应,它会在此期间将该线程用于其他目的,或者如果没有找到其他目的,它将在不消耗 CPU 时间的情况下休眠,直到响应传入;响应将通过某种操作系统机制触发 JVM 唤醒休眠线程以处理响应。

根据我的理解,我不明白基于 Apache 的同步 HTTP 客户端如何比基于 AWS CRT 的异步 HTTP 客户端具有更低的延迟?我不明白基于 CRT 的 AWS 异步 HTTP 客户端如何具有更高的吞吐量?在我看来,两者之间的区别主要决定了程序使用 CPU 的效率。

java amazon-web-services 多线程 http aws-sdk

评论


答:

2赞 abler98 11/15/2023 #1

基于 CRT 的 AWS HTTP 客户端仅适用于 S3,它使用分段上传 API 和字节范围提取。这就是为什么它可以处理更高的吞吐量。使用这些机制的开销会导致更高的延迟。

https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/crt-based-s3-client.html

基于 AWS CRT 的 S3 客户端(基于 AWS Common Runtime (CRT) 构建)是另一种 S3 异步客户端。它通过使用 Amazon S3 的分段上传 API 和字节范围提取自动将对象传入和传出 Amazon Simple Storage Service (Amazon S3),从而增强了性能和可靠性。

基于 AWS CRT 的 S3 客户端可提高发生网络故障时的传输可靠性。通过重试文件传输的各个失败部分,而无需从头开始重新启动传输,可以提高可靠性。

此外,基于 CRT 的 AWS S3 客户端提供增强的连接池和域名系统 (DNS) 负载均衡,这也提高了吞吐量。

您可以使用基于 CRT 的 AWS S3 客户端代替开发工具包的标准 S3 异步客户端,并立即利用其改进的吞吐量。

基于 Netty 的 HTTP 客户端和基于 AWS CRT 的 HTTP 客户端使用非阻塞 I/O,与基于 Apache 的同步 HTTP 客户端相比,它允许您拥有几个线程来处理许多并发请求,在该客户端中,您需要拥有与并发请求一样多的线程。

https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/asynchronous.html

AWS SDK for Java 2.x 具有真正无阻塞的异步客户端,可在多个线程之间实现高并发性。AWS SDK for Java 1.x 具有异步客户端,这些客户端是线程池的包装器,并阻止同步客户端,这些客户端不提供非阻塞 I/O 的全部优势。

评论

0赞 Nick 11/16/2023
是的,您的逻辑涉及使用,并且似乎肯定会在他们的文档中解释更高吞吐量和更高延迟之间的差异。但是我发现文档仍然缺乏和令人困惑,因为通常仅在上传至少 100 mb 时使用,所以在这些情况下,吞吐量/延迟仍然存在差异吗?谁知道呢。大多数请求小于 100 mb,因此我认为这很重要。multipart uploadbyte-rangemultipart upload
0赞 abler98 11/16/2023
@Nick 100MB 只是推荐大小,您可以配置最小部分大小。部件尺寸越小,请求越多,延迟越高
0赞 Nick 11/16/2023
是的,@abler98,我理解这一点,但我认为基于 AWS CRT 的异步客户端不会使用低于他们自己的建议,所以我的评论并不重要。即使他们这样做了,用于小文件似乎也是愚蠢的。所以我仍然不相信他们在文档中的描述是清楚的 - 如果他们要声称基于 AWS CRT 的异步客户端具有更高的吞吐量/更低的延迟,他们应该澄清这仅适用于非常大的文件。这已经是一个令人困惑和困难的话题(并发等等),所以我认为清晰度很重要。multipart upload
0赞 Nick 11/20/2023
而且您知道,该功能实际上与异步客户端无关。该功能可以同时存在于所谓的“同步”客户端或“异步”客户端上。因此,如果原因在某种程度上是由于 .multipart uploadmultipart uploadmultipart upload
1赞 Nick 11/20/2023
这是一个很好的信息,很高兴知道,但对于谈话主题,我个人认为它不相关,但我并不是真的在抱怨,我很高兴发现了所引用的 aws 文档的含义 - 因为我相信你。