2012-06-01 7 views
3

다른 REST 서비스를 호출하는 REST 서비스가 있습니다. 둘 다 MVC 4 WebAPI를 사용하고 있으며로드 할 때까지 제대로 호출한다고합니다.WebAPI/MVC 4를 사용하여 REST 서비스에서 REST 서비스 호출

public HttpResponseMessage Get() 
{ 
    var url = WebHelpers.CreateUrl(Request, "EmployeesGet"); 
    var client = new HttpClient(); 
    var response = client.GetAsync(url).Result; 
    var retResp = new HttpResponseMessage(); 
    retResp.Content = response.Content; 
    return retResp; 
} 

WebHelper.CreateUrl 엔드 포인트 URL을 구성합니다 : 단순화 된 코드는 같은입니다. 내가 시뮬레이션, 100 사용자에 부하를 넣어 , 나는 약 16,000 요청에 도착하고 난 소켓 예외를 얻을 : 시스템에 충분한 버퍼 공간이 부족하거나 때문에 때문에 소켓에 ​​대한 작업을 수행 할 수 없습니다

의 SocketException를 대기열이 가득 찼습니다.

이렇게하면 IIS를 재설정 할 때까지 내 컴퓨터의 네트워크 스택이 다운됩니다. 아마 나는 더 깨끗한 것에 사전 대처해야한다고 생각했기 때문에 나는 아무 효과없이 HttpClient을 처분했다. 그렇다면 일단 콘텐츠를 얻었 으면 끝점에서받은 응답을 폐기해야한다고 생각했습니다. 더 이상 필요하지 않게되었습니다. 이상한 것은 폐기 된 객체를 참조 할 수 없다는 예외가 발생한다는 것입니다. MVC 프레임 워크에서 오는 것입니다. 예외는 다음과 같습니다.

[ObjectDisposedException : 폐기 된 개체에 액세스 할 수 없습니다. 개체 이름 : ' System.Net.Http.StreamContent '] System.Web.Http.WebHost.HttpControllerHandler.EndProcessRequest (IAsyncResult를 결과) 49019 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute (.) 469 (IExecutionStep 단계, 부울 & completedSynchronously) +375

내가 스트림 또는 돌아 가면 바로 콘텐츠 일들이 잘 작동하지만, 그때는 응답의 상태를 변경할 수 없습니다 코드에 추가하거나 다른 메타 데이터를 응답에 추가하십시오.

그래서 REST 서비스에 대한 다른 호출에서 내용을 수신 한 Get 메서드의 응답을 반환하는 가장 좋은 방법은 무엇입니까? deserialize/serialize하고 싶지 않고 나가는 응답에 어떤 데이터를 추가 할 수 있기를 정말로 원합니다.

업데이트 :로드 테스트를하는 동안 리소스 모니터를 보는 동안 연결이 겹쳐서 표시됩니다. 그것은, 그리고 확실히 말할 수없는 것 같지만 내부에서 끝점에 대한 호출 것 같습니다 Get() 연결을 해제하지 않습니다.

답변

2

컨트롤러에 미리 생성 된 HttpClient 인스턴스를 삽입하고 요청간에 다시 사용하려고하는 것이 좋습니다.HttpClient가 처리되면 HttpClient가 해제되고 기본 연결을 닫으려고합니다. HttpClient 소스를 살펴보면 새 HttpClient 인스턴스를 만들 때마다 새 연결이 열립니다.

+0

나는 그것을 생각했다. 나는 그것을 시도 할지도 모른다. 문제는 각 호출마다 URL이 다를 수 있으므로 각 클라이언트에 사이트의 특정 인스턴스가 있다는 것입니다. 나는 이것을 시험해보고 차이가 있는지 봅니다. – JayGlynn

+0

@JayGlynn URL이 다른 경우 문제가 없어야합니다. HttpClient는 동시 호출을 위해 여러 스레드가 다시 사용할 수 있도록 구축되었습니다. –

+0

Ninject를 사용하여 스레드 당 하나의 인스턴스로 이동해야했지만 도움이되었습니다. 나는 임시 포트의 한계를 바꾸었고 큰 변화를 가져왔다. 내가 다른 요청을 한 이래로 나는 평소보다 두 배 빠른 포트를 사용하고있었습니다. – JayGlynn

1

스레드를 차단합니다 당신은 .Result를 호출하는 것을

  1. 의 커플. 이는 성능 문제의 일부일 수 있습니다. 비동기 작업을 수행 중이므로 Task<HttpResponseMessage>을 반환하고 동작 방식을 비동기로 설정하고 내부 서비스 호출의 결과를 외부 호출 본문으로 변환하는 연속을 예약하십시오.
  2. 내부 호출의 HttpContent을 외부 호출의 결과로 단순히 복사하는 것에 대해 확신하지 않습니다. 내부 스트림을 읽고 새로운 외부 스트림으로 복사 해보는 것이 좋습니다.
+0

나는 차단하고 있음을 알고 있지만 일반적으로 종단점에 대한 호출은 매우 빠르며 문제가되지 않습니다. 게다가이 코드에서 일하는 devs 팀을 갖게 될 것이고 간단하게 유지하려고합니다. 작업 또는 스트림을 반환하지만 메타 데이터를 추가하는 응답에 액세스 할 권한이 없습니다. 우리는 사용자 정의 헤더를 가지고 있으며 상태 코드를 관리 할 수 ​​있기를 원합니다. 나는 내용을 복사하는 것에 대해서도 궁금해한다. 그래서 내용이 잘 돌아와서 작동하는 것처럼 보이지만, 무엇인가가 소켓 리소스를 해제하지 않는다. – JayGlynn