az cli 命令能否在出现 http 错误 429 时自动重试

can az cli command automatically retry in case of http error 429

我观察到 az 命令仅在 --debug 标志传递给它时才打印 http headers。 例如

az storage account list --debug

和 headers 被打印到 stderr 并且 stdout 不包含任何内容。

如果是 HTTP 429,错误太多,指导是在 Retry-After 响应 header 中提到的时间间隔后重试。

是否有任何机制可以让 az cli 在出现 HTTP 429 错误时自动重试 API?

编辑 -- az 命令中内置的重试

urllib3.util.retry : Incremented Retry for (url='/subscriptions/REMOVED/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01'): Retry(total=3, connect=4, read=4, redirect=None, status=None)
urllib3.util.retry : Incremented Retry for (url='/subscriptions/REMOVED/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01'): Retry(total=2, connect=4, read=4, redirect=None, status=None)
urllib3.util.retry : Incremented Retry for (url='/subscriptions/REMOVED/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01'): Retry(total=1, connect=4, read=4, redirect=None, status=None)
urllib3.util.retry : Incremented Retry for (url='/subscriptions/REMOVED/providers/Microsoft.Storage/storageAccounts?api-version=2019-06-01'): Retry(total=0, connect=4, read=4, redirect=None, status=None)

根据目前收到的回复,答案是“否”,调用者必须 运行 带有 --debug 选项的 az 命令并解析 stderr。这是示例 Groovy 代码。

def pat = /'Retry-After': '(\d+)'/
stderr.split("\n").each { line ->
    def m = line =~ pat
    if (m.size() > 0 && m.hasGroup()) {
       retryAfterDuration = Integer.parseInt(m[0][1])
       println("Found Retry-After header, value = ${retryAfterDuration}")
    }
}

这是示例响应。

                msrest.http_logger : Response status: 429
                msrest.http_logger : Response headers:
                msrest.http_logger :     'Cache-Control': 'no-cache'
                msrest.http_logger :     'Pragma': 'no-cache'
                msrest.http_logger :     'Content-Length': '207'
                msrest.http_logger :     'Content-Type': 'application/json'
                msrest.http_logger :     'Expires': '-1'
                msrest.http_logger :     'Retry-After': '17'
                msrest.http_logger :     'x-ms-request-id': 'c7102dca-4bb1-4d24-8333-0128b8b85b24'
                msrest.http_logger :     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
                msrest.http_logger :     'Server': 'Microsoft-Azure-Storage-Resource-Provider/1.0,Microsoft-HTTPAPI/2.0 Microsoft-HTTPAPI/2.0'
                msrest.http_logger :     'x-ms-ratelimit-remaining-subscription-reads': '11989'
                msrest.http_logger :     'x-ms-correlation-request-id': '3a7ba2e1-6908-414b-b162-d6f41dc10521'
                msrest.http_logger :     'x-ms-routing-request-id': 'EASTUS:20200830T234133Z:3a7ba2e1-6908-414b-b162-d6f41dc10521'
                msrest.http_logger :     'X-Content-Type-Options': 'nosniff'
                msrest.http_logger :     'Date': 'Sun, 30 Aug 2020 23:41:32 GMT'
                msrest.http_logger :     'Connection': 'close'
                msrest.http_logger : Response content:
                msrest.http_logger : {"error":{"code":"TooManyRequests","message":"The request is being throttled as the limit has been reached for operation type - List_PerHour. For more information, see - https://aka.ms/srpthrottlinglimits"}}
                msrest.exceptions : The request is being throttled as the limit has been reached for operation type - List_PerHour. For more information, see - https://aka.ms/srpthrottlinglimits