Load Shedding reference guide
该技术被认为是 {extension-status}。 有关可能状态的完整列表,请查看我们的 FAQ entry. |
服务降级是指检测服务过载并拒绝请求。
在 Quarkus 中, quarkus-load-shedding
扩展提供了服务降级机制。
Use the Load Shedding extension
要使用服务降级扩展,您需要向项目添加 io.quarkus:quarkus-load-shedding
扩展:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-load-shedding</artifactId>
</dependency>
implementation("io.quarkus:quarkus-load-shedding")
虽然在下面描述了可能的配置选项,但不需要配置。
The load shedding algorithm
服务降级算法有两个部分:
-
overload detection
-
priority load shedding (optional)
Overload detection
要检测当前服务是否过载,使用 TCP Vegas 的改编版本。
该算法从 100 个允许的并发请求开始。对于每个请求,它将当前请求数与允许限制进行比较,如果超过限制,则表示过载情况。
如果未超过限制,或优先级服务降级确定不应拒绝该请求(见下文),则允许该请求。当它完成时,将它的持续时间与迄今为止看到的最低持续时间进行比较,以估计队列大小。如果队列大小低于 alpha ,则当前限制将增加,但仅限于给定的最大值(默认为 1000)。如果队列大小大于 beta ,则当前限制将减少。否则,当前限制保持不变。
Alpha 和 beta 是通过将可配置常数与当前限制的 10 个小数对数相乘来计算的。
在某些请求数后(可以通过配置 probe 因子进行修改),看到的最低持续时间将重置为请求最近看到的持续时间。
Priority load shedding
如果发出过载情况信号,则调用优先级负载卸载。
默认情况下,优先级负载卸载已启用,这意味着只有当前 CPU 负载足够高时才会拒绝请求。通过考虑以下 2 个属性来确定是否应该拒绝某个请求:
-
request priority
-
request cohort
共有 5 个静态定义的优先级和 128 个队列,总计 640 个请求组。
在将优先级和队列都分配给某个请求后,会计算出一个请求组号码:group = priority * num_cohorts + cohort
。接下来,将该组号码与当前 CPU 负载的一个简单三次函数进行比较,其中 load`是一个介于 0 到 1 之间的数:`num_groups * (1 - load^3)
。如果组号码较高,则拒绝该请求;否则,即使在过载情况下,该请求也会被允许。
如果禁用优先级负载卸载,则所有请求都将在过载情况下遭到拒绝。
Customizing request priority
优先级由一个 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`s, only the alternatives with the highest priority value are retained. If no implementation is an alternative, all implementations are retained and are sorted in descending `@Priority`顺序(优先级值最高者优先)。
Customizing request cohort
队列由一个 `io.quarkus.load.shedding.RequestClassifier`分配。共有 128 个静态定义的队列,其中最低号码为 1,最高号码为 128。分类器应返回该区间内的某个号码;如果未返回,则会自动调整该号码。
有一个默认分类器,它会根据远程 IP 地址和当前时间的哈希值分配一个队列,以便一个 IP 地址每大约 1 小时会更改一次其队列。它不声明任何 @Priority
。
可以定义 `RequestClassifier`界面的自定义实现。此类实现必须是 CDI Bean,否则它们将被忽略。必须遵循类型安全解析的 CDI 规则。也就是说,如果存在带有不同 `@Priority`值的多个实现,并且其中一些是 `@Alternative`s, only the alternatives with the highest priority value are retained. If no implementation is an alternative, all implementations are retained and are sorted in descending `@Priority`顺序(优先级值最高者优先)。
Limitations
目前,负载卸载扩展仅适用于 HTTP 请求,并且严重偏向于请求/响应网络交互。这意味着 gRPC、WebSocket 和通过 HTTP 进行的其他类型的流传输不受支持。其他 Quarkus 应用程序“入口点”,如消息传递,也不受支持。
此外,负载卸载实现目前相当基础,而且在生产环境中并未经过大量测试。可能需要改进。
Configuration reference
Unresolved include directive in modules/ROOT/pages/load-shedding-reference.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-load-shedding.adoc[]