簡體   English   中英

用於在超時情況下將主后端 URL 故障轉移到輔助后端的 Azure APIM 策略

[英]Azure APIM Policy to failover primary backend URL to secondary in case of a time out

我的要求很簡單。 我有一個 APIM 端點,它使用預定義的超時調用后端 HTTP 服務。 如果請求超時或返回“錯誤請求”( Status Code > 400)以外的錯誤,則需要使用故障轉移 HTTP 服務重試該調用,直到成功或最多 5 次。 我正在嘗試使用 APIM 策略來實現這一點。 如果返回的狀態代碼高於 400,則重試和故障轉移會起作用,但如果請求只是超時,則不會發生這種情況。 如果請求只是超時,控件甚至不會進入<retry>塊。 我相當確定我輸入的重試條件無法捕獲超時條件。 有人可以幫我找出用於記錄超時的 APIM 策略嗎?

以下是 APIM 政策。

<policies>
    <inbound>
        <base />
        <set-variable name="isFlag" value="true" />
    </inbound>
    <backend>
        <choose>
            <when condition="@(context.Variables.GetValueOrDefault<string>("isFlag") == "true")">
                <set-backend-service base-url="<primary url>" />
                <forward-request timeout="5" />
                <retry condition="@(context.Response == null || context.Response.StatusCode > 400)" count="5" interval="1" first-fast-retry="true">
                    <set-backend-service base-url="<secondary url>" />                        
                </retry>
            </when>
        </choose>
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />        
    </on-error>
</policies>

以下是 APIM 跟蹤的摘錄

Inbound
(3.014 ms)
api-inspector (0.403 ms)
{
    "request": {
        "method": "GET",
        "url": "https://gpcshare-apim-gpc-dev-aes.azure-api.net/statcode/405?sleep=7000",
        "headers": [
            {
                "name": "Ocp-Apim-Subscription-Key",
                "value": "a02f7f4e18d54d84ba55d4f122548072"
            },
            {
                "name": "Sec-Fetch-Site",
                "value": "cross-site"
            },
            {
                "name": "Sec-Fetch-Mode",
                "value": "cors"
            },
            {
                "name": "X-Forwarded-For",
                "value": "103.111.183.78"
            },
            {
                "name": "Cache-Control",
                "value": "no-cache, no-store"
            },
            {
                "name": "Via",
                "value": "ICAP/1.0 bmg70302.ibosscloud.com (IBOSS/0.4.4 iboss ICAP service )"
            },
            {
                "name": "Content-Type",
                "value": "text/plain;charset=UTF-8"
            },
            {
                "name": "Accept",
                "value": "*/*"
            },
            {
                "name": "Accept-Encoding",
                "value": "gzip,deflate,br"
            },
            {
                "name": "Accept-Language",
                "value": "en-US,en;q=0.9"
            },
            {
                "name": "Host",
                "value": "gpcshare-apim-gpc-dev-aes.azure-api.net"
            },
            {
                "name": "Referer",
                "value": "https://apimanagement.hosting.portal.azure.net/apimanagement/Content/1.42.0.1/apimap//apimap-apis/index.html?clientOptimizations=undefined&l=en.en-us&trustedAuthority=https%3A%2F%2Fportal.azure.com&shellVersion=undefined"
            }
        ]
    }
}
api-inspector (0.004 ms)
{
    "configuration": {
        "api": {
            "from": "/statcode",
            "to": null,
            "version": null,
            "revision": "1"
        },
        "operation": {
            "method": "GET",
            "uriTemplate": "/{code}"
        },
        "user": "-",
        "product": "-"
    }
}
cors (2.601 ms)
"Origin header was missing or empty and the request was classified as not cross-domain. CORS policy was not applied."
cors (0.002 ms)
"Origin header was missing or empty and the request was classified as not cross-domain. CORS policy was not applied."
set-variable (0.003 ms)
{
    "message": "Context variable was successfully set.",
    "name": "isFlag",
    "value": "true"
}
Backend
(4,991.587 ms)↑ Back to top
choose (0.017 ms)
{
    "message": "Expression was successfully evaluated.",
    "expression": "context.Variables.GetValueOrDefault<string>(\"isFlag\") == \"true\"",
    "value": true
}
set-backend-service (0.007 ms)
{
    "message": "Backend service URL was changed.",
    "oldBackendServiceUrl": "",
    "newBackendServiceUrl": "https://httpstat.us/",
    "request": {
        "url": "https://httpstat.us/405?sleep=7000"
    }
}
forward-request (0.151 ms)
{
    "message": "Request is being forwarded to the backend service. Timeout set to 5 seconds",
    "request": {
        "method": "GET",
        "url": "https://httpstat.us/405?sleep=7000",
        "headers": [
            {
                "name": "Host",
                "value": "httpstat.us"
            },
            {
                "name": "Request-Id",
                "value": "|f595c50c66d7453c97a7dc14c9c1af9e.2b06f656cb6c4704_b907aebb."
            },
            {
                "name": "Ocp-Apim-Subscription-Key",
                "value": "a02f7f4e18d54d84ba55d4f122548072"
            },
            {
                "name": "Sec-Fetch-Site",
                "value": "cross-site"
            },
            {
                "name": "Sec-Fetch-Mode",
                "value": "cors"
            },
            {
                "name": "X-Forwarded-For",
                "value": "103.111.183.78,13.91.254.72"
            },
            {
                "name": "Cache-Control",
                "value": "no-cache, no-store"
            },
            {
                "name": "Via",
                "value": "ICAP/1.0 bmg70302.ibosscloud.com (IBOSS/0.4.4 iboss ICAP service )"
            },
            {
                "name": "Content-Type",
                "value": "text/plain;charset=UTF-8"
            },
            {
                "name": "Accept",
                "value": "*/*"
            },
            {
                "name": "Accept-Encoding",
                "value": "gzip,deflate,br"
            },
            {
                "name": "Accept-Language",
                "value": "en-US,en;q=0.9"
            },
            {
                "name": "Referer",
                "value": "https://apimanagement.hosting.portal.azure.net/apimanagement/Content/1.42.0.1/apimap//apimap-apis/index.html?clientOptimizations=undefined&l=en.en-us&trustedAuthority=https%3A%2F%2Fportal.azure.com&shellVersion=undefined"
            }
        ]
    }
}
forward-request (4,991.413 ms)
{
    "messages": [
        "Error occured while calling backend service.",
        "Request to the backend service timed out"
    ]
}
Outbound
(0.183 ms)↑ Back to top
transfer-response (0.067 ms)
{
    "message": "Response headers have been sent to the caller."
}
transfer-response (0.116 ms)
{
    "message": "Response body streaming to the caller is complete."
}

您可以在retry策略中包含您的邏輯。 您可以參考一個策略片段示例 具體這條線

這是相同的政策供參考

<!--
    This policy routes calls to the closest of two backend services, and fails over to the secondary if an HTTP 404 is returned.

    It assumes that the API Manager is deployed in 'East US' and 'West Europe'. Similarly the policy (as is) assumes two backend services, in the same regions, vis:
        https://hello-eus.azurewebsites.net/  (for East US); and
        https://hello-weu.azurewebsites.net/  (for West Europe)

    If a failure (HTTP 404) is returned from the backend service, the policy will re-route the call to the fail-over region.
    The policy uses cached values to track which service has returned an error in the last 10 seconds, to avoid routing new requests to a backend which will likely fail.
-->
<policies>
    <inbound>
        <base />
        <set-backend-service base-url="https://hello-eus.azurewebsites.net/" />
        <choose>
            <when condition="@(context.Deployment.Region.Equals("east us", System.StringComparison.InvariantCultureIgnoreCase))">
                <set-backend-service base-url="https://hello-eus.azurewebsites.net/" />
                <cache-lookup-value key="@("eus-down")" variable-name="is-eus-down" />
                <choose>
                    <when condition="@(context.Variables.GetValueOrDefault<bool>("is-eus-down"))">
                        <set-backend-service base-url="https://hello-weu.azurewebsites.net/" />
                    </when>
                </choose>
            </when>
            <when condition="@(context.Deployment.Region.Equals("west europe", System.StringComparison.InvariantCultureIgnoreCase))">
                <set-backend-service base-url="https://hello-weu.azurewebsites.net/" />
                <cache-lookup-value key="@("weu-down")" variable-name="is-weu-down" />
                <choose>
                    <when condition="@(context.Variables.GetValueOrDefault<bool>("is-weu-down"))">
                        <set-backend-service base-url="https://hello-eus.azurewebsites.net/" />
                    </when>
                </choose>
            </when>
        </choose>
    </inbound>
    <backend>
        <retry condition="@(context.Response.StatusCode == 404)" count="2" interval="1" max-interval="10" delta="1" first-fast-retry="true">
            <choose>
                <when condition="@(context.Response != null && (context.Response.StatusCode == 404))">
                    <choose>
                        <when condition="@(context.Request.Url.Host.Contains("hello-eus.azurewebsites.net"))">
                            <set-backend-service base-url="https://hello-weu.azurewebsites.net" />
                            <cache-store-value key="@("eus-down")" value="@(true)" duration="10" />
                        </when>
                        <otherwise>
                            <set-backend-service base-url="https://hello-eus.azurewebsites.net" />
                            <cache-store-value key="@("weu-down")" value="@(true)" duration="10" />
                        </otherwise>
                    </choose>
                </when>
            </choose>
            <forward-request />
        </retry>
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM