配置应用程序缩放
通过 IBM Cloud® Code Engine,您无需考虑扩展应用程序,因为应用程序的运行实例数会根据传入工作负载自动向上或向下扩展 (为零)。 通过自动缩放,您不会为未使用的资源付费。
Code Engine 监视系统中的请求数,并向上和向下扩展应用程序实例以满足入局请求 (包括与应用程序的任何 HTTP 连接) 的负载。 这些 HTTP 连接可以是来自项目外部,项目中运行的其他工作负载或您可能预订的事件生产者 (无论这些生产者位于何处) 的请求。Code Engine 自动复制应用程序实例并配置网络基础结构以在所有实例之间对请求进行负载均衡。
缩放的工作方式
Code Engine 监视系统中的请求数,并在应用程序并行设置的约束内扩展应用程序实例。
要从 Code Engine 控制台 观察应用程序缩放,请浏览至特定应用程序页面。 应用程序正在运行时,根据指定的最大实例数,正在运行的实例数为 1
或更大。 当应用程序处理的请求少于其配置的目标并行性时,应用程序会将正在运行的实例数向下扩展至配置的最小实例数。 如果最小实例数设置为 0
(缺省值),那么应用程序将向下扩展为零,并且应用程序的实例数将反映
0
个实例。 在缩减应用程序并将请求路由到应用程序时,Code Engine 会向上扩展应用程序并将请求路由到新创建的应用程序实例。
要使应用程序能够完全缩减,应用程序代码必须处理 SIGTERM 信号。 当 Code Engine 自动向下缩放时,会向应用程序发送 SIGTERM 信号。 如果应用程序未处理 SIGTERM 信号,那么应用程序实例将在请求超时值配置的时间 (缺省值为 300 秒) 内保持 Terminating
状态。 在请求超时的持续时间之后,Code Engine 发送 SIGKILL 信号以强制停止处于 Terminating
状态的应用程序实例。
缩放边界
您可以通过设置 Code Engine 自动缩放应用程序的运行实例数的最小和最大实例数的值范围来配置缩放边界。 在创建或更新应用程序时配置此范围。
-
最小实例数-始终处于运行状态的应用程序的最小实例数,即使未处理任何请求也是如此。 设置为
0
(缺省值) Code Engine 将在没有流量到达应用程序时除去所有实例。 要始终保持应用程序的运行实例,请将此值设置为大于0
。 从控制台使用 Code Engine 创建或更新应用程序时,请在 资源和缩放 选项卡的“自动缩放”部分中设置最小实例数值。 通过 CLI,在app create
和app update
命令上指定--min-scale
选项。 -
最大实例数-可以为应用程序运行的最大实例数。 自动缩放将达到此限制。 如果将此值设置为
0
,那么应用程序将根据需要进行缩放,并且应用程序缩放仅受应用程序项目的每个资源配额的实例限制。 请参阅 Code Engine的限制和配额。 从控制台使用 Code Engine 创建或更新应用程序时,请在 资源和缩放 选项卡的“自动缩放”部分中设置最大实例数值。 通过 CLI,在app create
和app update
命令上指定--max-scale
选项。 此选项的缺省值为10
。
将应用程序连接到事件生产者时,请记住在设置缩放边界时,要考虑来自这些生产者的事件的频率和数量。 例如,如果您期望同时接收许多事件,并且每个事件的处理可能需要几分钟时间,那么您可能需要比可以快速处理每个事件更高的最大规模值。 如果将该值设置得太低,那么在接收事件时可能会迂到延迟,甚至在等待处理资源空闲时由于超时而删除事件。
并行和计时的自动缩放设置
使用以下配置设置来控制应用程序缩放。
-
并行-此值指示应用程序的每个实例一次可以处理的请求数。 例如,货币值 100 表示您的代码可以同时处理 100 个并发请求。 此值为“硬限制”,表示 Code Engine 不允许超过请求数 (通过并行设置指定) 来访问应用程序的任何一个实例。 因此,如果您的代码是单线程的,并且一次只能处理一个请求,请考虑将并行设置为
1
。 将指定数量的请求发送到应用程序的所有正在运行的实例时,Code Engine 会增加实例数,以准备更多请求。 从控制台使用 Code Engine 创建或更新应用程序时,请在 资源和缩放 选项卡的“自动缩放”部分中设置最大并行值。 通过 CLI,在app create
和app update
命令上指定--concurrency
选项。 -
目标并行性-此值充当“软限制”或您希望装入的系统中每个实例的请求数。 例如,如果将
concurrency
指定为100
,并将target concurrency
指定为70
,那么 Code Engine 会尝试将每个实例的请求数限制为 70。 指定此选项并不能确保每个实例的请求不会超过 70 个,因为在流量增加的过程中很可能发生此情况。 但是,70 到 100 之间的缓冲区使系统能够创建新实例,以将每个实例的负载降低到每个实例的 70 (或更低)。 如果未指定target concurrency
,那么缺省值为concurrency
的值。 从控制台使用 Code Engine 创建或更新应用程序时,请在 资源和缩放 选项卡的“自动缩放”部分中设置目标并行值。 通过 CLI,在app create
和app update
命令上指定--concurrency-target
选项。 -
请求超时-应用程序必须响应请求或失败的时间量 (以秒为单位)。 从控制台使用 Code Engine 创建或更新应用程序时,请在 资源和缩放 选项卡的“自动缩放”部分中设置请求超时值。 通过 CLI,在
app create
和app update
命令上指定--request-timeout
选项。 -
缩减延迟-在应用程序缩减之前必须在降低的并行性时经过的时间量 (以秒为单位)。 如果您知道向应用程序发出的入局请求的模式,那么可以选择指定大于缺省值
0
的值以延迟应用程序的缩减。 如果对此选项使用高值,那么同时运行的应用程序实例的平均数目可能会增加,这将产生额外的成本。 即使使用0
的缩减延迟设置,系统也会在应用程序缩减实例数之前等待短时间,以确保请求并行性的下降足以保证缩减。 从控制台使用 Code Engine 创建或更新应用程序时,请在 资源和缩放 选项卡的“自动缩放”部分中设置缩减延迟值。 通过 CLI,在app create
和app update
命令上指定--scale-down-delay
选项。
例如,如果最大实例数值设置为 10
,并且并行性设置为 100
,那么应用程序可以先处理 1000 个并发请求,然后才可能进行潜在的请求排队。 如果您同时期望超过 1000 个请求,那么可以考虑增加应用程序的最大实例数值。
有关 Code Engine 工作方式的更多信息,请参阅 IBM Cloud Code Engine: 优化应用程序缩放,等待时间和吞吐量,以及 调整 IBM Cloud Code Engine Scale-Down Delay 以减少应用程序响应时间。
如果将最小实例数设置为等于最大实例数,那么不会进行缩放,并且不会应用目标货币和缩减延迟值。 但是,并行值仍有效。
自动缩放的示例方案
假设您有一个使用以下自动缩放设置配置的应用程序。
- 最小实例数 = 4
- 最大实例数 = 20
- 并行 = 2
通过这些设置,应用程序可以同时处理 2 个并发请求。 当没有流量时,应用程序会自动向下扩展至 4 实例。 4 实例只能处理 4 * 2 (货币) = 8 请求。 应用程序最多可扩展至 20 个实例,这样 20 个实例可以处理 20 个 * 2 (货币) = 40 个请求,假定应用程序有足够的 CPU 和内存设置。
假定应用程序是静态 Web 应用程序,需要对应用程序进行 6 调用以装入登录页面。 假定 10 个人同时登录到应用程序登录页面 (10 * 6 = 60 个调用)。 由于 60 个调用会产生超过 40 个可由应用程序处理的请求,因此应用程序的用户可能会在呼叫排队时观察到速度很慢。
在没有针对应用程序的流量的大约一分钟后,Code Engine 将开始自动缩减。 当应用程序向下扩展时,某些实例将设置为 Terminating
状态。Code Engine 向应用程序发送 SIGTERM 信号,您的代码必须处理此信号并关闭。 如果应用程序未处理此信号,那么应用程序实例将在请求超时值 (缺省值为 300 秒) 配置的时间内保持 Terminating
状态。 在请求超时的持续时间之后,Code Engine
发送 SIGKILL 信号以强制停止处于 Terminating
状态的应用程序实例。
如果有 8 个活动实例和 12 个实例处于 Terminating
状态 300 秒 (5 分钟)。 这 12 个实例不接收任何请求。 如果超过 8 * 2 (货币) = 16 个请求,那么 Code Engine 会扩展新实例。
在此示例中,对于此静态内容,2
的并行值较低。 您必须确定要为应用程序设置的自动缩放值,这取决于应用程序的实现可以使用其分配的 CPU 和内存资源来处理的内容。
优化延迟和吞吐量
要优化应用程序等待时间和吞吐量,请了解一些公共模型和最佳实践的优缺点,以配置容器并行性。
使用并行设置来指定在创建或更新应用程序时每个实例可并发处理的最大请求数。 从 Code Engine 控制台,在“运行时”部分中设置并行值。 通过 CLI,将 --concurrency
选项 (别名 --cn
) 与 app create
或 app update
命令配合使用。
模型 | 优势 | 劣势 |
---|---|---|
单并行,--cn=1 |
当应用程序为内存密集型或 CPU 密集型工作负载提供服务时,请选择单一并行配置,因为一次只有一个请求进入应用程序实例,从而获取为该实例配置的完整 CPU 和内存量。 | 快速使用单并行模型向外扩展的应用程序。 向外扩展可能会引入额外的等待时间和更低的吞吐量,因为创建新应用程序实例比复用现有应用程序实例更昂贵。 如果可以并发处理请求并且等待时间是应用程序的关键方面,请不要选择此模型。 |
高并行度,--cn=100 (缺省值) 或更高版本 |
如果应用程序处理大量非 CPU 密集型或内存密集型的 HTTP 请求或响应工作负载,并且可以等待资源,请选择此配置。 您可以为 API 后端选择此并行配置,以将有关创建,检索,更新和删除操作的数据读写到远程数据库。 当某些请求在 I/O 上等待时,可以在不影响总体等待时间和吞吐量的情况下处理其他请求。 | 当并发请求争夺 CPU,内存或 I/O 时,此设置不是最佳设置,因为争夺资源可能会延迟执行,并对等待时间和吞吐量产生负面影响。 |
最佳并行性,--cn=N |
如果您知道单个请求所需的资源量以满足应用程序所需的响应时间,请选择最佳并行配置。 如果应用程序是自然语言翻译应用程序,其中用于语言转换的机器学习模型为 32 GB,并且每个请求需要有关 0.7 vCPU 的单个翻译计算,那么可以选择此配置。 您可以为每个实例选择 9 vCPUs 和 32 GB 内存的配置。 最佳容器并行性约为 13 (9 vCPU/0.7 vCPU )。 |
如果您不知道应用程序的资源需求,请不要选择最佳并行配置。 设置错误的容器并行可能会导致过于激进或过于懒惰的缩放,这可能会影响应用程序的等待时间,错误率和成本。 有关更多信息,请参阅 确定应用程序容器的并行性。 |
无限并行,--cn=0 (已禁用) |
已禁用 | 在 Code Engine中不支持无限并行配置。 无限并行配置将尽可能多的请求转发到单个应用程序实例,这可能会延迟其他应用程序实例的缩放。 |
确定应用程序容器的并行性
最佳容器并行值由应用程序可以使用可接受的请求等待时间处理的最大并发请求数确定。
容器并行性直接影响应用程序的成功率,等待时间和吞吐量。 当容器并行值过高而应用程序无法处理时,等待时间和吞吐量会受到负面影响,您可能会观察到 502
和 503
错误响应。
当容器并行值对于应用程序而言过低时,系统会更快地向外扩展应用程序,并在许多应用程序实例之间传播请求,从而引入额外的成本和等待时间。 在负载脉冲串期间,当系统的内部缓冲区运行时,较低的并行值也会导致临时 502
响应。
要确定应用程序的容器并行配置,请检查请求和等待时间。
-
创建应用程序并将其并行性设置为
1000
(max),并将min-scale
和max-scale
都设置为1
。ibmcloud ce application create --name APPNAME --image APPIMAGE --min-scale=1 --max-scale=1 --concurrency=1000
-
首先发送高速率的请求。 如果发生
502
错误,请降低此比率,直到结果显示 100% 的成功率为止。 -
查找步骤 2 的输出的请求等待时间。 如果请求等待时间不可接受,请进一步降低请求速率,直到请求等待时间看起来可接受为止。 请注意,如果请求的计算需要
2
秒或100
毫秒,那么请求持续时间也很重要,因为它会产生差异。可接受的请求速率和等待时间根据应用程序特征和缩放配置而有所不同。 例如,如果应用程序内的计算大约需要 100 毫秒,并且并行设置为 10,那么一个应用程序实例能够每秒处理大约 100 个请求,等待时间大约为 100 毫秒 (忽略网络等待时间)。
-
要计算应用程序的容器并行值,请采用步骤 2 中的 rate (在
req/s
中),并除以步骤 3 的 latency (以秒计):CC = RATE/LATENCY
。 例如,如果速率为每秒80
个请求,并且等待时间为2
秒,那么生成的并行性为 concurrency =80 req/s / 2 s = 40
。 -
更新应用程序以将容器并行性设置为您在上一步中找到的值,然后重新运行工作负载以检查成功率和等待时间是否可接受。
-
通过增加容器并行值并观察成功率和等待时间来试验应用程序。
-
使用最佳容器并行值更新应用程序,并除去
min-Scale
和max-scale
边界以允许应用程序自动缩放。
观察应用程序如何使用 CLI 进行扩展
您可以使用 CLI 来观察应用程序的运行实例数。
-
使用
app create
命令创建应用程序。ibmcloud ce application create --name myapp --image icr.io/codeengine/helloworld
-
调用应用程序。 您可以从
app create
命令的输出中获取应用程序的 URL,也可以运行ibmcloud ce app get --name myapp --output url
。curl https://myapp.4svg40kna19.us-south.codeengine.appdomain.cloud
-
运行
application get
命令以显示应用程序的状态。 查找Running instances
的值。 在此示例中,应用程序具有正在运行的1
实例。 例如ibmcloud ce application get --name myapp
示例输出
[...] OK Name: myapp [...] URL: https://myapp.4svg40kna19.us-south.codeengine.appdomain.cloud Cluster Local URL: http://myapp.4svg40kna19.svc.cluster.local Console URL: https://cloud.ibm.com/codeengine/project/us-south/01234567-abcd-abcd-abcd-abcdabcd1111/application/myapp/configuration Status Summary: Application deployed successfully Environment Variables: Type Name Value Literal CE_API_BASE_URL https://api.us-south.codeengine.cloud.ibm.com Literal CE_APP myapp Literal CE_DOMAIN us-south.codeengine.appdomain.cloud Literal CE_PROJECT_ID abcdefgh-abcd-abcd-abcd-1a2b3c4d5e6f Literal CE_REGION us-south Literal CE_SUBDOMAIN abcdabcdab Image: icr.io/codeengine/helloworld Resource Allocation: CPU: 1 Ephemeral Storage: 400M Memory: 4G Revisions: myapp-ds8fn-1: Age: 6m25s Traffic: 100% Image: icr.io/codeengine/helloworld (pinned to fe0446) Running Instances: 1 Runtime: Concurrency: 100 Maximum Scale: 10 Minimum Scale: 0 Timeout: 300 Conditions: Type OK Age Reason ConfigurationsReady true 6m10s Ready true 5m56s RoutesReady true 5m56s Events: Type Reason Age Source Messages Normal Created 6m28s service-controller Created Configuration "myapp" Normal Created 6m28s service-controller Created Route "myapp" Instances: Name Revision Running Status Restarts Age myapp-ds8fn-1-deployment-79bdd76749-khtmw myapp-ds8fn-1 2/2 Running 0 32s
等待几分钟,因为应用程序可能需要几分钟才能缩放到零。
-
再次运行
application get
命令,并注意Running instances
的值已缩放为零。 当应用程序处理的请求少于其配置的目标并行性时,应用程序会将正在运行的实例数向下扩展至配置的最小实例数。 在此方案中,正在运行的实例数会自动缩放为零。 当--min-scale
选项设置为0
(缺省值) 时,正在运行的实例数将自动缩放为零。等待几分钟,因为应用程序可能需要几分钟才能缩放到零。
ibmcloud ce application get -n myapp
示例输出
OK Name: myapp [...] URL: https://myapp.4svg40kna19.us-south.codeengine.appdomain.cloud Cluster Local URL: http://myapp.4svg40kna19.svc.cluster.local Console URL: https://cloud.ibm.com/codeengine/project/us-south/01234567-abcd-abcd-abcd-abcdabcd1111/application/myapp/configuration Image: icr.io/codeengine/helloworld Resource Allocation: CPU: 1 Ephemeral Storage: 400M Memory: 4G Revisions: myapp-ds8fn-1: Age: 12m Traffic: 100% Image: icr.io/codeengine/helloworld (pinned to 548d5c) Running Instances: 0 Runtime: Concurrency: 100 Maximum Scale: 10 Minimum Scale: 0 Timeout: 300 Conditions: Type OK Age Reason ConfigurationsReady true 3m7s Ready true 2m54s RoutesReady true 2m54s Events: Type Reason Age Source Messages Normal Created 3m21s service-controller Created Configuration "myapp" Normal Created 3m20s service-controller Created Route "myapp"
-
再次调用应用程序以从零开始扩展。
curl https://myapp.4svg40kna19.us-south.codeengine.appdomain.cloud
-
再次运行
application get
命令,并注意Running instances
的值已从零扩展。 例如ibmcloud ce application get -n myapp
示例输出
OK Name: myapp [...] URL: https://myapp.4svg40kna19.us-south.codeengine.appdomain.cloud Cluster Local URL: http://myapp.4svg40kna19.svc.cluster.local Console URL: https://cloud.ibm.com/codeengine/project/us-south/01234567-abcd-abcd-abcd-abcdabcd1111/application/myapp/configuration Status Summary: Application deployed successfully Environment Variables: Type Name Value Literal CE_API_BASE_URL https://api.us-south.codeengine.cloud.ibm.com Literal CE_APP myapp Literal CE_DOMAIN us-south.codeengine.appdomain.cloud Literal CE_PROJECT_ID abcdefgh-abcd-abcd-abcd-1a2b3c4d5e6f Literal CE_REGION us-south Literal CE_SUBDOMAIN abcdabcdab Image: icr.io/codeengine/helloworld Resource Allocation: CPU: 1 Ephemeral Storage: 400M Memory: 4G Revisions: myapp-00001: Age: 42s Latest: true Traffic: 100% Image: icr.io/codeengine/helloworld (pinned to 1cee99) Running Instances: 1 Runtime: Concurrency: 100 Maximum Scale: 10 Minimum Scale: 0 Scale Down Delay: 0 Timeout: 300 Conditions: Type OK Age Reason ConfigurationsReady true 25s Ready true 12s RoutesReady true 12s Events: Type Reason Age Source Messages Normal Created 44s service-controller Created Configuration "myapp" Normal Created 43s service-controller Created Route "myapp" Instances: Name Revision Running Status Restarts Age myapp-00001-deployment-d59b87654-xkqh7 myapp-00001 3/3 Running 0 43s
设置应用程序的最小和最大实例数
您可以通过更新应用程序实例数的最小值和最大值来更改应用程序的运行实例数。
应用程序的最小实例数的缺省值为 0
。 如果应用程序未接收到任何流量,那么它会扩展到 0
,并且应用程序的任何实例都不会运行。 在这种情况下,当应用程序再次接收流量时,它的响应速度可能较慢,而它会进行扩展。 您可以通过在控制台或 CLI 中更新应用程序并将最小规模设置为 1
来更改此行为。
应用程序的最大实例数的缺省值为 0
,这允许应用程序根据需要进行扩展。 有关更多信息,请参阅 缩放边界。
从控制台更改自动缩放范围
要更改 Code Engine 从控制台自动缩放应用程序的运行实例数的范围,请执行以下步骤。
- 浏览至应用程序。
- 选择 配置 选项卡。
- 选择 资源和缩放 选项卡。
- 设置应用程序的最小实例数和最大实例数。
- (可选) 复审并设置用于自动缩放应用程序的请求并行设置和计时设置。
- 单击 部署 以保存更改并部署应用程序修订版。
更新应用程序时,应用程序将创建新的修订版并将流量路由到该实例。
使用 CLI 更改自动缩放范围
要更改 Code Engine 使用 CLI 自动缩放应用程序的运行实例数的范围,请运行 application update
命令并将 --min-scale
和 --max-scale
选项设置为应用程序所需的实例数。
您可以选择为应用程序设置请求并行设置和计时设置。 这些选项包括 --concurrency
,--concurrency-target
,--request-timeout
和 --scale-down-delay
。 有关设置这些自动缩放值的更多信息,请参阅 缩放边界 和 用于并行和计时的自动缩放设置。
更新应用程序时,应用程序将创建新的修订版并将流量路由到该实例。