我正在编写一个带有一堆后端微服务的Web应用程序,以及一个处理SSL卸载,授权,路由等问题的网关应用程序......
网关是自我托管的Owin和WebApi的混合体。 Owin管道在到达WebApi之前处理几乎所有网关逻辑,而WebApi中间件由使用HttpClient将调用转发到后端服务的代理处理程序组成。
在我自己的开发机器上,网关为通信增加了很少的开销:~10ms
但是当我在另一台测试机器上调用它们时,开销显着增加 例如:来自后端的126K数据需要11ms完成(来自Fiddler的结果),但通过网关的相同数据需要大约600ms才能到达。
我的代理处理程序已简化:
internal class ProxyHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// Some modification on the requestUri to forward it to the backend here...
var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
return response;
}
}
有几点需要注意:
我深入研究了WebApi.Owin的代码,发现HttpMessageHandlerAdapter试图改变缓冲行为。定义我自己的始终缓冲的策略选择器也可以解决问题:
private void UseGateway(IAppBuilder appBuilder)
{
HttpMessageHandlerOptions httpMessageHandlerOptions = new HttpMessageHandlerOptions
{
BufferPolicySelector = new MyBufferPolicySelector(),
ExceptionHandler = new NullExceptionHandler(),
ExceptionLogger = new NullExceptionLogger(),
MessageHandler = new ProxyHandler()
};
appBuilder.Use<HttpMessageHandlerAdapter>(httpMessageHandlerOptions);
}
internal class MyBufferPolicySelector : IHostBufferPolicySelector
{
public bool UseBufferedInputStream(object hostContext)
{
return false;
}
public bool UseBufferedOutputStream(HttpResponseMessage response)
{
return true;
}
}
这一切都指向了HttpClient,WebApi和Owin之间的消息体流转换的一些次优行为,但我不知道如何修复它而不缓冲整个响应。
有没有人知道这种行为?
解决问题的正确方法是什么?
也许这是一些实验室环境的怪癖,将在现实世界中修复?
也许我不应该使用HttpClient并转到更基本的实现,如HttpWebRequest?