我们有一个三层基础架构(前端是所有Web API 2,中间件接受来自前端的API调用并运行业务逻辑和数据库访问,然后是数据库)
我正在试图找出为什么我的应用程序在我采用中间层时锁定。我们使用Memcached进行所有读取,前端提供缓存数据就好了,但是其中一个调用检查用户是否已登录。在具有一个应用程序池的本地计算机上运行,该调用锁定了线程(我认为)并阻止其余的调用做任何事情,直到自动登录呼叫的超时到期。
代码路径如下所示: 致电api / autologin - >前端API调用Client.SendAsync(我们将数据传递给中间件的自定义方法),这会尝试使用HttpClient.SendAsAsync调用中间件,超时为3分钟(可能应该缩短此时间) 我的期望是,这应该在我们等待的时候释放这个帖子。这似乎不是结果。 真正奇怪的是,当中间件关闭时,Client.SendAsync会运行很多次,就像10.我认为这可能是Chrome中的HTTP 2.0,但我切换到了Fiddler,它做了同样的事情。非常奇怪。
所以,两个问题。 1.多次通话有什么用? 2.为什么线程似乎被锁定了?
这是代码。
/// <summary>
/// Auto login user if they have the persistent cookies.
/// </summary>
/// <returns>The groups the logged in user has access to in the form of a
LoggedInUserData object.</returns>
[Route("api/cms/autologin/")]
[HttpGet]
public async Task<HttpResponseMessage> AutoLogin()
{
HttpResponseMessage response = await Client.SendAsync(this.Request);
return this.LoginCacheHelper(response);
}
那叫
public static async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request)
{
return await Client.SendAsync<string>(request, null, null, false);
}
哪个电话
public static async Task<HttpResponseMessage> SendAsync<T>(HttpRequestMessage request, T content = null, string route = null, bool isFile = false, TimeSpan? timeout = null) where T : class
{
// Validate all internal certs.
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
// Determine the route and make sure route has a starting forward slash.
if (!string.IsNullOrWhiteSpace(route) && route.StartsWith("http"))
{
// Check to make sure this is a selinc.com domain for security purposes.
if (Sel.Utils.Validation.UriValidation.IsSelincDomain(route))
{
request.RequestUri = new Uri(route);
}
else
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
}
else
{
string middlewareRoute = GetRoute(route, request);
// Change Uri to middle ware.
request.RequestUri = new Uri(Config.MwareSiteUrl + middlewareRoute);
}
// Remove host header
request.Headers.Host = string.Empty;
// Set content of request.
// File content will be kept on the request as is.
if (content != null && !isFile)
{
request.Content = new ObjectContent<T>(content, new JsonMediaTypeFormatter());
}
else if (!isFile)
{
request.Content = null;
}
// Client handler set use cookies to false which will pass along the current cookies
HttpClientHandler clientHandler = new HttpClientHandler() { UseCookies = false };
// The HttpClient object
HttpClient client = new HttpClient(clientHandler);
client.Timeout = timeout ?? new TimeSpan(0, 3, 0);
// Send the request
return await client.SendAsync(request);
}
在Chrome中添加网络日志的图像以说明行为。 请注意,如果我删除对自动登录的API调用,一切正常。这是该堆栈中唯一一个触及后端的调用。
另请注意:如果我修改SendAsync方法只是返回一个新的HttpResponseMessage(因此不起作用),那么自动登录基本上什么都不做,快速返回并且网站加载应该是,中间件服务器关闭。这只是为了证明它是导致问题的自动登录API调用。自动登录API调用是此时调用SendAsync的唯一方法,因此它是一个有效的测试。
// Send the request
////return await client.SendAsync(request);
return new HttpResponseMessage();