yuzd / Hangfire.HttpJob

httpjob for Hangfire,restful api for Hangfire,job调度与业务分离
https://github.com/yuzd/Hangfire.HttpJob/wiki
MIT License
635 stars 187 forks source link

作业的Timeout 参数,设置较大值时失效 #12

Closed FattySun closed 4 years ago

FattySun commented 5 years ago

比如周期性作业,在json编辑器中设置 "Timeout": 180000 作业启动后,在1分40秒会出现异常,导致作业失败 +1m 40.598s System.Threading.Tasks.TaskCanceledException: The operation was canceled. ---> System.IO.IOException: Unable to read data from the transport connection: 由于线程退出或应用程序请求,已中止 I/O 操作。. ---> System.Net.Sockets.SocketException: 由于线程退出或应用程序请求,已中止 I/O 操作。

作业调用的web api有做超时配置 public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() .ConfigureKestrel((context, options) => { options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(40); options.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(40); });

yuzd commented 5 years ago

首先确保理解一致: 在json编辑器中设置 "Timeout": 180000 这个代表的是 调度的时候 HttpClient 请求你的webapi 的 超时时间。

你这个error只截取了一点 看上去是HttpCLient请求超时报的错误, 还有更详多的log吗?

FattySun commented 5 years ago

嗯,我理解 在json编辑器中设置 "Timeout": 180000 这个代表的是 调度的时候 HttpClient,而且我也没有找到其他可以设置HttpClient的Timeout时间的地方。

下面这是Job界面中,所有异常描述 System.Threading.Tasks.TaskCanceledException: The operation was canceled. ---> System.IO.IOException: Unable to read data from the transport connection: 由于线程退出或应用程序请求,已中止 I/O 操作。. ---> System.Net.Sockets.SocketException: 由于线程退出或应用程序请求,已中止 I/O 操作。 --- End of inner exception stack trace --- at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token) at System.Net.Security.SslStreamInternal.g__InternalFillBufferAsync|38_0[TReadAdapter](TReadAdapter adap, ValueTask1 task, Int32 min, Int32 initial) at System.Net.Security.SslStreamInternal.ReadAsyncInternal[TReadAdapter](TReadAdapter adapter, Memory1 buffer) at System.Net.Http.HttpConnection.FillAsync() at System.Net.Http.HttpConnection.ReadNextResponseHeaderLineAsync(Boolean foldedHeadersAllowed) at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Hangfire.HttpJob.Server.HttpJob.Excute(HttpJobItem item, String jobName, String queuename, Boolean isretry, PerformContext context)

yuzd commented 5 years ago

如果你设置了Timeout (单位是毫秒) 的话 那么会在这里起作用:

https://github.com/yuzd/Hangfire.HttpJob/blob/master/Hangfire.HttpJob/Server/HttpJob.cs#L137

            var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(item.Timeout));
            var httpResponse = client.SendAsync(request, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult();

意思就是 如果发起http请求超过了这个Timeout 就会自动取消请求。 看你贴的错误日志应该就是webapi那边的接口超时了。 如果在hangfire调度的时候有这种超时的话 你拿着同样请求的数据 用postman试试 验证是否真的超时!


我查到了原来是HttpClient的默认的超时时间的原因导致的 默认的超时是100s 这个我来修复一下

FattySun commented 5 years ago

因为每次异常发生时间都是一样的,我也觉得可能是因为默认超时时间的问题,多谢。 :)

yuzd commented 5 years ago

因为每次异常发生时间都是一样的,我也觉得可能是因为默认超时时间的问题,多谢。 :)

已发布新版 更新下

guolianyu commented 4 years ago

这个问题,新版的还是存在 System.Threading.Tasks.TaskCanceledException: The operation was canceled. ---> System.IO.IOException: Unable to read data from the transport connection: Operation canceled. ---> System.Net.Sockets.SocketException (125): Operation canceled --- End of inner exception stack trace --- at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.GetResult(Int16 token) at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken) at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts) at Hangfire.HttpJob.Server.HttpJob.Run(HttpJobItem item, PerformContext context, List1 logList, HttpJobItem parentJob) in /src/src/Hangfire.HttpJob/Server/HttpJob.cs:line 269 at Hangfire.HttpJob.Server.HttpJob.Excute(HttpJobItem item, String jobName, String queuename, Boolean isretry, PerformContext context) in /src/src/Hangfire.HttpJob/Server/HttpJob.cs:line 134

yuzd commented 4 years ago

你检查你的设置是否对吗

guolianyu commented 4 years ago

image

guolianyu commented 4 years ago

image

guolianyu commented 4 years ago

我直接在postman或者浏览器上调用我的接口是不会出现这个问题。我的hangfire有一个任务是1分钟执行一次,是否会对我的这个调度产生影响

yuzd commented 4 years ago

针对你这个问题,为了判断究竟是你设置的timeout 还是 你服务端接口超时导致的 我加了详细的log。你更新下最新版本 3.1.5 。然后你在给我日志 一起研究下

guolianyu commented 4 years ago

好的

yuzd commented 4 years ago

@LouieGuo 试了没

yuzd commented 4 years ago

截图log给我看下呢

yuzd commented 4 years ago

按照你之前的截图重新截图下

guolianyu commented 4 years ago

image image

yuzd commented 4 years ago

好像你这个不是新版本呢,确定你升级为 3.1.5了吗

guolianyu commented 4 years ago

我下午本地先用你的源码先测一下找找原因,到时候log也截图出来