2016-05-26 24 views
2

Azure Search SDK(1.1.1-1.1.2)を使用して検索を実行している間にこのエラーメッセージが表示されています。通常、各ソケットアドレス(プロトコル/ネットワークアドレス/ポート)の1つの使用しか許可されていません。

検索SDKは、トラフィックに基づいてスケールアップする内部API(Azure Web Appsとしてデプロイされます)を使用します(検索を実行するAPIのインスタンスが1つ以上ある可能性があります)。

私たちのAPIは、5種類のインデックスを照会し、各インデックスに対応SearchIndexClientオブジェクトのメモリ内のコピーを維持し、非常に単純な実装は次のようになります。

public class AzureSearchService 
{ 
    private readonly SearchServiceClient _serviceClient; 

    private Dictionary<string, SearchIndexClient> _clientDictionary; 

    public AzureSearchService() 
    { 
     _serviceClient = new SearchServiceClient("myservicename", new SearchCredentials("myservicekey")); 
     _clientDictionary = new Dictionary<string, SearchIndexClient>(); 
    } 

    public SearchIndexClient GetClient(string indexName) 
    { 
     try 
     { 
      if (!_clientDictionary.ContainsKey(indexName)) 
      { 
       _clientDictionary.Add(indexName, _serviceClient.Indexes.GetClient(indexName)); 
      } 
      return _clientDictionary[indexName]; 
     } 
     catch 
     { 
      return null; 
     } 
    } 

    public async Task<SearchResults> SearchIndex(SearchIndexClient client, string text) 
    { 
     var parameters = new SearchParameters(); 
     parameters.Top = 10; 
     parameters.IncludeTotalResultCount = true; 
     var response = await client.Documents.SearchWithHttpMessagesAsync(text, parameters, null, null); 
     return response.Body; 
    } 
} 

そして、APIは、サービスを呼び出します。 :私たちは、カスタムHTTPヘッダの代わりSearchAsync方法を受け取ることにより、要求にSearchWithHttpMessagesAsyncを使用している

public class SearchController : ApiController 
{ 
     private readonly AzureSearchService service; 

     public SearchController() 
     { 
      service = new AzureSearchService(); 
     } 


     public async Task<HttpResponseMessage> Post(string indexName, [FromBody] string text) 
     { 
      var indexClient = service.GetClient(indexName); 
      var results = await service.SearchIndex(indexClient, text); 
      return Request.CreateResponse(HttpStatusCode.OK, results, Configuration.Formatters.JsonFormatter);    
     } 

} 

このようにして、トラフィックバーストの下でクライアントを開閉することは避けてください。このメモリキャッシュを使用する前に(そして各クライアントをusing節でラップする)、Azure App Servicesでポート枯渇アラートが発生します。

これは良いパターンですか?複数のインスタンスが並行して実行されているため、このエラーが発生する可能性がありますか?

それが必要とされる場合には、スタックトレースを示しています

System.Net.Http.HttpRequestException: Only one usage of each socket address (protocol/network address/port) is normally permitted service.ip.address.hidden:443 


[SocketException:Only one usage of each socket address (protocol/network address/port)is normally permitted service.ip.address.hidden:443] 

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) 



[WebException:Unable to connect to the remote server] 

at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult,TransportContext& context) 

at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) 

はEDIT:あなたのコードで実装さ

System.Net.Http.HttpRequestException: 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 service.ip.address.hidden:443 


[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 service.ip.address.hidden:443] 

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) 



[WebException:Unable to connect to the remote server] 

at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult,TransportContext& context) 

at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar) 
+0

明確にする - 「各ソケットアドレスの1つの使用法」に関するエラーメッセージは、SearchIndexClientsのキャッシュの有無に関係なく発生していますか? –

+0

こんにちはブルース。メッセージはキャッシュにあります。 –

+0

説明をありがとう。私は自分の答えを投稿しました。 「接続に失敗しました」というエラーが表示される場合は、サービスの可用性に問題がある可能性があるので、直接私に連絡してください。 –

答えて

1

:私たちは、このエラーA connection attempt failed because the connected party did not properly respond after a period of timeを受けていますキャッシュがポートの消耗を防ぎません。これは、要求ごとに1回作成されるApiControllerのフィールドとしてインスタンス化するためです。ポートが枯渇しないようにするには、すべての要求でキャッシュを共有する必要があります。これを同時実行可能にするには、Dictionaryの代わりにConcurrentDictionaryのようなものを使用してください。

「接続試行に失敗しました」というエラーはおそらく無関係です。

+0

ブルース、ありがとう。静的なサービスを作成しても同じ効果があると思いますか? –

+0

Bruce、私はService上でシングルトンパターンを実装しました。これはこれまでのところ問題を解決したようですが、私はちょうどそれを見守っていますが、答えをマークしました:) –

関連する問題