负载分流参考指南
此技术被认为是实验性的。 在实验性模式下,我们希望得到早期反馈,以便完善这个想法。在解决方案成熟之前,我们不保证平台的稳定性或长期存在。欢迎您在我们的邮件列表或我们的GitHub issue tracker上提供反馈。 有关可能的完整状态列表,请查看我们的常见问题解答条目。 |
负载分流是检测服务过载并拒绝请求的做法。
在 Quarkus 中,quarkus-load-shedding
扩展提供了一种负载均衡机制。
1. 使用负载均衡扩展
要使用负载均衡扩展,您需要将 io.quarkus:quarkus-load-shedding
扩展添加到您的项目中
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-load-shedding</artifactId>
</dependency>
implementation("io.quarkus:quarkus-load-shedding")
虽然可能的配置选项在下面进行了描述,但不需要任何配置。
2. 负载均衡算法
负载均衡算法分为两个部分
-
过载检测
-
优先级负载均衡(可选)
2.1. 过载检测
为了检测当前服务是否过载,我们使用了 TCP Vegas 的一种变体。
该算法从 100 个允许的并发请求开始。对于每个请求,它会将当前请求的数量与允许的限制进行比较,如果超过限制,则发出过载信号。
如果未超过限制,或者优先级负载均衡确定不应拒绝该请求(见下文),则允许该请求。当请求完成时,将其持续时间与目前为止看到的最低持续时间进行比较,以估算队列大小。如果队列大小小于alpha,则当前限制会增加,但最多增加到给定的最大值,默认为 1000。如果队列大小大于beta,则当前限制会减小。否则,当前限制保持不变。
Alpha 和 beta 是通过将可配置常量乘以当前限制的以 10 为底的对数来计算的。
在一定数量的请求之后,该数字可以通过配置probe因子来修改,所看到的最低持续时间将重置为最后看到的请求持续时间。
2.2. 优先级负载均衡
如果发出过载信号,则会调用优先级负载均衡。
默认情况下,优先级负载均衡处于启用状态,这意味着只有在当前 CPU 负载足够高时才会拒绝请求。为了确定是否应该拒绝请求,需要考虑 2 个属性
-
请求优先级
-
请求群组
有 5 个静态定义的优先级和 128 个群组,总共有 640 个请求组。
在将优先级和群组分配给请求后,会计算请求组编号:group = priority * num_cohorts + cohort
。然后,将组编号与当前 CPU 负载的简单三次函数进行比较,其中 load
是介于 0 和 1 之间的数字:num_groups * (1 - load^3)
。如果组编号较高,则拒绝该请求,否则即使在过载情况下也允许该请求。
如果禁用优先级负载均衡,则在过载情况下将拒绝所有请求。
2.2.1. 自定义请求优先级
优先级由 io.quarkus.load.shedding.RequestPrioritizer
分配。在 io.quarkus.load.shedding.RequestPriority
枚举中有 5 个静态定义的优先级:CRITICAL
、IMPORTANT
、NORMAL
、BACKGROUND
和 DEGRADED
。默认情况下,如果没有请求优先级分配器适用,则优先级被假定为 NORMAL
。
有一个默认的优先级分配器,它将 CRITICAL
的优先级分配给非应用程序端点的请求。它没有声明任何 @Priority
。
可以定义 RequestPrioritizer
接口的自定义实现。这些实现必须是 CDI bean,否则会被忽略。必须遵循 CDI 的类型安全解析规则。也就是说,如果存在具有不同 @Priority
值的多个实现,并且其中一些是 @Alternative
,则仅保留具有最高优先级值的备选项。如果任何实现都不是备选项,则保留所有实现,并按降序 @Priority
顺序排序(最高优先级值排在第一位)。
2.2.2. 自定义请求群组
群组由 io.quarkus.load.shedding.RequestClassifier
分配。有 128 个静态定义的群组,最小的数字是 1,最大的数字是 128。分类器应返回此间隔中的数字;如果没有,则自动调整数字。
有一个默认的分类器,它基于远程 IP 地址和当前时间的哈希值分配群组,以便 IP 地址大约每小时更改一次其群组。它没有声明任何 @Priority
。
可以定义 RequestClassifier
接口的自定义实现。这些实现必须是 CDI bean,否则会被忽略。必须遵循 CDI 的类型安全解析规则。也就是说,如果存在具有不同 @Priority
值的多个实现,并且其中一些是 @Alternative
,则仅保留具有最高优先级值的备选项。如果任何实现都不是备选项,则保留所有实现,并按降序 @Priority
顺序排序(最高优先级值排在第一位)。
3. 局限性
负载均衡扩展目前仅适用于 HTTP 请求,并且严重偏向于请求/响应网络交互。这意味着 gRPC、WebSocket 和其他类型的 HTTP 流式传输不受支持。Quarkus 应用程序的其他“入口点”,例如消息传递,也不受支持。
此外,负载均衡的实现目前相当基础,并且没有在生产环境中进行大量测试。可能需要改进。
4. 配置参考
构建时固定的配置属性 - 所有其他配置属性都可以在运行时覆盖
配置属性 |
类型 |
默认 |
---|---|---|
是否应启用负载均衡。目前,这仅适用于传入的 HTTP 请求。 环境变量: 显示更多 |
布尔值 |
|
整数 |
|
|
Vegas 过载检测算法的 环境变量: 显示更多 |
整数 |
|
Vegas 过载检测算法的 环境变量: 显示更多 |
整数 |
|
Vegas 过载检测算法的 probe 因子。 环境变量: 显示更多 |
double |
|
整数 |
|
|
是否应启用优先级负载均衡。 环境变量: 显示更多 |
布尔值 |
|