我们使用System.Net.Http.HttpClient
进行k8s内部微服务之间的调用。
几天前,我们注意到http调用的行为非常奇怪: 微服务之间的一些呼叫(接近2-3%)失败并出现错误
System.OperationCanceledException: The operation was canceled.
at System.Net.Http.HttpClient.HandleFinishSendAsyncError(Exception e, CancellationTokenSource cts)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
at OurCode.HttpServiceClient.GetStringResponseAsync(String methodUri, HttpMethod httpMethod)
...another our code...
我们的http通话超时后(3秒)。但是在被叫服务内部没有有关呼叫的日志。
我们启用packetbeat来跟踪http请求,并且还注意到,没有执行任何从呼叫者服务到被呼叫者服务的http请求。 该服务的CPU,内存和网络一直都正常。
用于http调用的代码的简化版本如下:
public async Task<string> GetStringResponseAsync(String methodUri, HttpMethod httpMethod)
{
int timeoutInMilliseconds = 3000;
var tokenSource = new CancellationTokenSource();
var rm = new HttpRequestMessage(httpMethod, methodUri);
Task<HttpResponseMessage> httpTask = HttpClient.SendAsync(rm, tokenSource.Token);
tokenSource.CancelAfter(timeoutInMilliseconds);
HttpResponseMessage response = await httpTask;
await EnsureSuccessStatusCode(response);
return await response.Content.ReadAsStringAsync();
}
任何关于没有网络请求http都会导致这种奇怪行为的问题的想法,我该怎么做进一步调查?
答案 0 :(得分:2)
这只是意味着Web服务没有响应。
HttpClient
会在超时时间过后抛出TaskCanceledException
(从OperationCanceledException
继承)。它不是直观的,对我(和其他人)没有任何意义,但是不幸的是,它就是这样做的。
对此here进行了一些讨论(一些人提到了一些变通方法,以区分超时与真正的取消,如果您愿意的话)。
答案 1 :(得分:0)
我不知道这对将来是否会有所帮助,但我遇到了同样的问题。原来,我托管的服务器默认情况下不会自动使用代理地址。我最终不得不在我的代码中添加以下内容:
using (var handler = new WinHttpHandler()){
handler.WindowsProxyUsePolicy = WindowsProxyUsePolicy.UseCustomProxy;
handler.Proxy = new WebProxy(server, port);
//the rest of your code.....
}
此操作手动添加了代理服务器信息,我的控制台应用程序开始按预期运行。