Azure Политика APIM для отработки отказа первичного внутреннего URL-адреса на вторичный в случае истечения времени ожидания - PullRequest
0 голосов
/ 26 февраля 2020

Мое требование довольно простое. У меня есть конечная точка APIM, которая вызывает бэкэнд-сервис HTTP с предопределенным временем ожидания. Если запрос истекает или возвращает ошибку, отличную от «Плохой запрос» (Status Code > 400), вызов должен быть повторен с помощью службы HTTP при сбое до достижения успеха или не более 5 раз. Я пытаюсь прийти с политикой APIM для ccessli sh this. Хотя повтор и отработка отказа работают, если возвращенный код состояния выше 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."
}

1 Ответ

0 голосов
/ 03 марта 2020

Вы можете иметь свои логи c в политике retry. Существует пример фрагмента политики *1003*, к которому вы можете обратиться. В частности, это строка .

Вот та же политика для справки

<!--
    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>
...