天天看點

【API管理 APIM】APIM內建内部VNet後,自我通路出現(Unable to connect to the remote server)問題,而Remote Server正是APIM它自己

問題描述

在使用APIM配置内部VNET後,如API-1正常配置通路後端伺服器的一個接口,而API-2則是通過調用APIM中的API-1來作為backendUrl,會出現500錯誤。 經過測試,目前這種配置内部內建VNET的情況下,會出現錯誤。這是一個已知的問題。

錯誤消息為:Unable to connect to the remote server

而在APIM的開發者門戶中測試跟蹤接口,則會擷取到如下的錯誤資訊:

【API管理 APIM】APIM內建内部VNet後,自我通路出現(Unable to connect to the remote server)問題,而Remote Server正是APIM它自己

異常日志

System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond xxx.xxx.xxx.xxx:443
   at System.Net.Sockets.Socket.InternalEndConnect(IAsyncResult asyncResult)
   at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Handlers.DefaultServiceRequestExecutor.<ExecuteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.ApiManagement.Proxy.Runtime.Configuration.Models.DefaultHttpBackend.<ProcessAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.IO.CallServiceHandler.<ProcessAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.PipelineWalker.<ExecuteAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.Policies.PipelineWalker.<ExecuteAsync>d__1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.WindowsAzure.ApiManagement.Proxy.Gateway.PipelineExecutor.<ExecuteAsync>d__15.MoveNext()      

問題原因

因為APIM 後端執行個體中, 所有傳出流量(包含請求到自己的流量)都被路由到APIM Load Balancer,而不是直接環回接口(Loopback)。 由于SLB的一個局限性,即如果它映射到相同的VM,則不允許建立從後端池中的VM到SLB IP的連接配接。最終結果是,請求發送到同一APIM服務的API調用開始失敗。

解決辦法

使用127.0.0.1來代替APIM的域名,并且在API的inbound政策中設定host header,指定值為該APIM的域名。 操作步驟如下:

1:使用127.0.0.1替換APIM域名

【API管理 APIM】APIM內建内部VNet後,自我通路出現(Unable to connect to the remote server)問題,而Remote Server正是APIM它自己

2:添加Host header,設定值為APIM域名

【API管理 APIM】APIM內建内部VNet後,自我通路出現(Unable to connect to the remote server)問題,而Remote Server正是APIM它自己

設定後全部的 API Policy 為:

<policies>
    <inbound>
        <set-header name="Host" exists-action="override">
            <value>your apim url here</value>
        </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>      

當在複雜的環境中面臨問題,格物之道需:濁而靜之徐清,安以動之徐生。 雲中,恰是如此!

繼續閱讀