Azure 应用服务自动缩放无法缩小

Posted

技术标签:

【中文标题】Azure 应用服务自动缩放无法缩小【英文标题】:Azure App Service Autoscale Fails to Scale In 【发布时间】:2018-09-20 11:04:54 【问题描述】:

我的应用服务在横向扩展后未能横向扩展。这似乎是我几个月来一直试图排除故障的一种模式。

我尝试了以下方法,但都没有奏效:

我的缩放条件基于 CPU 和内存。但是,我从未见过 CPU 超过 12%,所以我假设它实际上是基于内存进行扩展的。

    将横向扩展条件设置为内​​存超过 90%,平均 5 分钟和 10 分钟。平均 5 分钟内,内存低于 70% 的冷却和扩展条件。这似乎没有意义,因为如果我的内存利用率已经达到 90%,那么我确实存在潜在的内存泄漏并且应该已经向外扩展了。

    将横向扩展条件设置为内​​存超过 80%,平均 60 分钟和 10 分钟。平均 5 分钟内,内存低于 60% 的冷却和扩展条件。这更有意义,因为我已经看到内存使用量在几个小时内突然下降。

预期行为:应用服务自动缩放将在内存使用率降至 60% 以下的 5 分钟后减少实例计数。

问题:

如果我的基准 CPU 大致保持在平均 6% 并且内存保持在 53%,那么平滑扩展的指标的理想阈值是多少?意思是,在不担心反模式(例如摆动)的情况下,可以缩小的最佳最小值和扩大的最佳最大值是多少? 20% 差异的较大阈值对我来说更有意义。

替代方案:

考虑到与“按钮缩放”一样简单的营销所涉及的故障排除数量,几乎不值得为配置模糊而头疼(如果没有自定义 powershell,您甚至无法使用连接计数等 IIS 指标脚本!)。我正在考虑禁用自动缩放,因为它的不可预测性,只保持 2 个实例运行以实现自动负载平衡和手动缩放。

自动缩放配置:


    "location": "East US 2",
    "tags": 
        "$type": "Microsoft.WindowsAzure.Management.Common.Storage.CasePreservedDictionary, Microsoft.WindowsAzure.Management.Common.Storage"
    ,
    "properties": 
        "name": "CPU and Memory Autoscale",
        "enabled": true,
        "targetResourceUri": "/redacted",
        "profiles": [
            
                "name": "Auto created scale condition",
                "capacity": 
                    "minimum": "1",
                    "maximum": "10",
                    "default": "1"
                ,
                "rules": [
                    
                        "scaleAction": 
                            "direction": "Increase",
                            "type": "ChangeCount",
                            "value": "1",
                            "cooldown": "PT10M"
                        ,
                        "metricTrigger": 
                            "metricName": "MemoryPercentage",
                            "metricNamespace": "",
                            "metricResourceUri": "/redacted",
                            "operator": "GreaterThanOrEqual",
                            "statistic": "Average",
                            "threshold": 80,
                            "timeAggregation": "Average",
                            "timeGrain": "PT1M",
                            "timeWindow": "PT1H"
                        
                    ,
                    
                        "scaleAction": 
                            "direction": "Decrease",
                            "type": "ChangeCount",
                            "value": "1",
                            "cooldown": "PT5M"
                        ,
                        "metricTrigger": 
                            "metricName": "MemoryPercentage",
                            "metricNamespace": "",
                            "metricResourceUri": "/redacted",
                            "operator": "LessThanOrEqual",
                            "statistic": "Average",
                            "threshold": 60,
                            "timeAggregation": "Average",
                            "timeGrain": "PT1M",
                            "timeWindow": "PT10M"
                        
                    ,
                    
                        "scaleAction": 
                            "direction": "Increase",
                            "type": "ChangeCount",
                            "value": "1",
                            "cooldown": "PT5M"
                        ,
                        "metricTrigger": 
                            "metricName": "CpuPercentage",
                            "metricNamespace": "",
                            "metricResourceUri": "/redacted",
                            "operator": "GreaterThanOrEqual",
                            "statistic": "Average",
                            "threshold": 60,
                            "timeAggregation": "Average",
                            "timeGrain": "PT1M",
                            "timeWindow": "PT1H"
                        
                    ,
                    
                        "scaleAction": 
                            "direction": "Decrease",
                            "type": "ChangeCount",
                            "value": "1",
                            "cooldown": "PT5M"
                        ,
                        "metricTrigger": 
                            "metricName": "CpuPercentage",
                            "metricNamespace": "",
                            "metricResourceUri": "/redacted",
                            "operator": "LessThanOrEqual",
                            "statistic": "Average",
                            "threshold": 40,
                            "timeAggregation": "Average",
                            "timeGrain": "PT1M",
                            "timeWindow": "PT10M"
                        
                    
                ]
            
        ],
        "notifications": [
            
                "operation": "Scale",
                "email": 
                    "sendToSubscriptionAdministrator": false,
                    "sendToSubscriptionCoAdministrators": false,
                    "customEmails": [
                        "redacted"
                    ]
                ,
                "webhooks": []
            
        ],
        "targetResourceLocation": "East US 2"
    ,
    "id": "/redacted",
    "name": "CPU and Memory Autoscale",
    "type": "Microsoft.Insights/autoscaleSettings"

【问题讨论】:

【参考方案1】:

对于 CpuPercentage 指标,当它超过 60 时您有一个 SCALE UP 操作,当它低于 40 时有一个缩减操作,两者之间的差异非常小。这可能会导致描述为 Flapping 的行为,这将导致 AutoScale 的缩放无法发挥作用。类似的问题是您配置的 MemoryPercent 规则。

您的扩展阈值和扩展阈值之间的差异至少应为 40,以避免抖动。更多关于Flapping的细节在https://docs.microsoft.com/en-us/azure/monitoring-and-diagnostics/insights-autoscale-best-practices#choose-the-thresholds-carefully-for-all-metric-types(搜索Flapping这个词)

【讨论】:

我有 40 的差异,它卡在了 7! dropbox.com/s/vsrphneob4ti7u7/…【参考方案2】:

我遇到了完全相同的问题,我开始相信像我们想要的那样自动缩放回一个实例目前是不可能的。

我目前的解决方法是使用每天 23:55 到 00:00 之间重复的第二个配置文件扩展到 1 个实例。

只是重申这个问题。我有以下情况。和你的基本一样。

应用服务的内存基线为 50% 当 avg(memory) > 80% 时横向扩展 1 个实例 当 avg(memory)

当平均内存百分比超过 80% 时,从 1 个实例扩展到 2 个实例将正常工作。但是因为内存基准太高,所以扩展到 1 个实例永远不会起作用。

看了Best Practices之后,我的理解是,在scale in的时候,它会估计得到的内存百分比,并检查是否没有触发scale out规则。

因此,如果两个实例的平均内存百分比下降到 50%,则会触发缩减规则,它会估计生成的内存使用量为 2 * 50% / 1 = 100%,这当然会触发扩展规则,因此它不会扩展在。

但是,当从 3 个实例扩展到 2 个实例时,它应该可以工作:3 * 50% / 2 = 75%,它小于向外扩展规则的 80%。

【讨论】:

是的,这种逻辑规模非常可怕。我有大约 3% 的 cpu,它一整天都坐在 7 个实例上。【参考方案3】:

我也有同样的问题。我的应用程序只需要一个实例,并且我有一个自动缩放配置,例如:

向外扩展 当 br-empresa (Average) CpuPercentage > 85 实例计数增加 1 或 Br-Empresa (Average) MemoryPercentage > 85 将实例计数增加 1

缩小 当 br-empresa (Average) CpuPercentage 和 Br-Empresa (Average) MemoryPercentage

内存的基线是 60%。

Scale Out 逻辑运行良好。但是即使内存下降到 60%,应用程序也永远不会缩小。 (60% * 2) / 1 = 120%

对于内存或 cpu 指标,实际的抖动估计没有意义。

【讨论】:

以上是关于Azure 应用服务自动缩放无法缩小的主要内容,如果未能解决你的问题,请参考以下文章

如何按计划扩大或缩小 Azure 应用服务实例的大小?

Azure - 无法自动缩放,因为未找到监控数据

Terraform 上的 Azure 应用服务自动缩放错误

在 azure 中使用 terraform 为应用服务创建自动缩放规则时出错

windows azure 自动缩放

如何基于 Azure 中的服务总线队列自动缩放 Python webjob?