我有一个REST服务,可以调用另一个REST服务。两者都使用MVC 4 WebAPI并调用它们可以正常工作,直到我承受了负载。简化的代码类似于:

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由于系统缺少足够的缓冲区空间或队列已满,无法对套接字执行操作


这将关闭我的PC的网络堆栈,直到我重置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
System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值和已完成同步)+375


如果我返回一个流或只是内容可以正常工作,但是我不能更改响应的状态代码或向响应添加任何其他元数据。

因此,从已从另一个调用REST服务的方法中接收到内容的Get方法返回响应的最佳方法是什么。我不想反序列化/序列化,我真的很想能够向响应中添加一些数据。

更新:在进行负载测试时查看“资源监视器”时,我看到连接不断堆积。看来,我不能肯定地说,但是看来从Get()内部对端点的调用没有释放连接。

最佳答案

我建议尝试将预先创建的HttpClient实例注入控制器中,并在请求中重用它。处置HttpClient时,它将关闭并尝试关闭基础连接。从我回想起HttpClient源代码后,您将在每次创建新的HttpClient实例时打开一个新连接。

关于asp.net-mvc-4 - 使用Web API/MVC从REST服务中调用REST服务4,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10852183/

10-11 01:48