grpc - http2 的适当 MAX_CONCURRENT_STREAMS 值

标签 grpc http2 grpc-go

我有一种情况需要在使用 grpc-go 时设置 max_concurrent_streams 选项。 所以我读了这个RFC7540 document .

我阅读了这篇文章并进行了搜索,但我有一个问题仍未得到解答。

  1. 我正在尝试将 MAX_CONCURRENT_STREAMS 设置为最大 uint64。这样做会有什么问题吗?
  2. 如果 CONCURRENT_STREAM 增加时出现问题,什么样的 问题是什么?
  3. 如果没有问题,为什么默认值为 100?

最佳答案

HTTP/2 的设计,如果你原谅我的简化,主要是为了改善浏览体验。

网页变得越来越丰富,HTTP/1.1 迫使许多“技巧”来克服一个页面可以引用同一域中的数十个其他资源这一事实——想想 *.css、*.js、*。等.png 下载index.html,然后浏览器必须再发出10-60次请求来下载index.html引用的依赖资源。

考虑到这一点,HTTP/2 的 max_concurrent_streams 比 6-8(HTTP/1.1 可以实现的并行度)大得多,但显然不需要是 2^32-1。值 100 是当前网页的最大值的一个很好的近似值。

目前尚不清楚您是否“必须设置 max_concurrent_streams”只是因为它是必需的,但该值并不重要,只要它是一个合理的值并且您想更好地理解它即可。

或者,如果您必须将其设置为特定值,甚至可能是动态设置,因为这是您的应用程序所需要的,所以该值确实很重要。

无论哪种情况,2^32-1 都不是一个好的值,因为它很容易成为恶意客户端的攻击向量。 他们将打开一个连接,看到您的服务器允许 2^32-1 个流,并强制创建这么多流,可能会耗尽服务器的内存。 如果一个连接不足以炸毁服务器,他们将打开更多连接,并且每个连接 2^32-1 个流。不好。

此外,由于 HTTP/2 是一种多路复用协议(protocol),因此需要流量控制。 HTTP/2 定义了连接流量控制窗口和流流量控制窗口。 流流控窗口接入连接流控窗口。

这意味着较小的 max_concurrent_streams 值允许每个流使用连接流控制窗口的较大部分进行下载(从服务器到客户端)。对于每个客户端并发下载不多的文件服务器来说,这可能是一个很好的配置。

相反,较大的 max_concurrent_streams 值允许更多的并发请求,但每个流的流量控制窗口更小。对于网页服务器来说,这可能是一个很好的配置,其中应该同时提供许多资源,但它们可能相当小。

gRPC 作为一个通用的 RPC 协议(protocol),通常不需要像网页那样同时请求许多依赖的小资源;因此,gRPC 服务器的 max_concurrent_streams 值通常由特定于应用程序的因素决定。

总而言之,没有确切的答案:您必须测量并查看,或者您必须知道您的应用程序是如何工作的。

如果您知道单个客户端永远不会发出并发 gRPC 请求,那么您可以保留默认值 100,或者相反将其减少为 1。该连接中唯一存在的流将能够进入整个连接流量控制窗口(除非流配置了较小的每流流量控制窗口)。

如果您知道单个客户端将发出并发 gRPC 请求,您将必须知道或测量将交换多少数据以及多少数据,并为此进行调整。

我会从默认的一切开始,监控服务器并查看它是如何工作的。可能默认值就很好,您无需执行任何操作。

关于grpc - http2 的适当 MAX_CONCURRENT_STREAMS 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68781943/

相关文章:

c# - gRPC(.net 核心实现)可以消费 WCF 服务吗?

node.js - gRPC:14 UNAVAILABLE:无法连接到所有地址

java - 什么是 Http2 中的 GoAway 框架以及它如何链接到重定向?

Google Chrome 中的 HTTP/2 响应 header 字段不是 Pascal 大小写

protocol-buffers - 如何从 protobuf (.proto) 文件在 (.json/.yaml) 中生成 swagger3 (OpenAPI3) 规范?

python - gRPC套接字关闭消息

ssl - 使用 Golang 在 Nginx 后面运行的 GRPC 服务的 TLS

http - 使用 Last-Modified header 使已存储的响应无效

go - 使用 gRPC 状态包中的 WithDetails() 传递自定义原型(prototype)消息

go - protoc-gen-go struct xxx 隐蔽到 map[string]interface{}