yuzd / Hangfire.HttpJob

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

设置了HttpJobItem的Timeout超过一个小时,但是httpjob执行时间超过一个小时时还是返回错误 #107

Closed TotocQ closed 3 years ago

TotocQ commented 3 years ago

你好,谢谢的开源! 问题:设置了HttpJobItem的Timeout超过一个小时,但是httpjob执行时间超过一个小时时还是返回错误 具体错误:System.Threading.Tasks.TaskCanceledException: The request was canceled due to the configured HttpClient.Timeout of 3600 seconds elapsing. 检查源码后发现: https://github.com/yuzd/Hangfire.HttpJob/blob/9d12dd08882e7360b0ca68ccc9a3be00cfe9b7a5/Server/Hangfire.HttpJob/Server/HangfireHttpClientFactory.cs#L14 在初始化时直接写死了超时时间是一个小时,而且在调用的过程中也没有使用HttpJobItem中的Timeout来重新赋值

yuzd commented 3 years ago

下面设置的1小时你可以理解为兜底的timeout。因为httpclient是复用的,所以没有去根据HttpJobItem的Timeout去改这个值。 https://github.com/yuzd/Hangfire.HttpJob/blob/9d12dd08882e7360b0ca68ccc9a3be00cfe9b7a5/Server/Hangfire.HttpJob/Server/HangfireHttpClientFactory.cs#L14

但是在实际的http调用的时候会用到这个值的,也就是Timeout会实际生效的,为啥呢,你可以看下

https://github.com/yuzd/Hangfire.HttpJob/blob/9d12dd08882e7360b0ca68ccc9a3be00cfe9b7a5/Server/Hangfire.HttpJob/Server/HttpJob.cs#L357

你的情况是预料外的情况,因为没有考虑到短连接还会有超过1小时的情况, 你为何不考虑在你的接口里面重新开一个task去执行呢?

我能想到的解决方案: 我将兜底的timeout改成可以配置的,默认是1小时,但是你可以通过改appsettings.json 去更改

你有其他意见或者想法吗?

TotocQ commented 3 years ago

因为只是想把任务和定时器分开而已,而且使用webapi接口的方式也相对比较好调试

至于如果复现这个问题,你可以先把HttpClient的Timeout设置短一点,然后写一个长时间运行的服务,HttpJobItem的timeout设置长一点,就可以复现这个问题了

以我个人对CancellationToken的理解,CancellationToken是通过客户端来取消服务端执行的一个标识,放在httpclient中,跟timeout是两个东西,timeout表示客户端等待多久,即使超时了服务端也还在执行,CancellationToken表示客户允许这个任务执行多久,超过时间会发送取消标识到服务端,服务端可以根据这个取消标识,取消整个方法

解决方案:

yuzd commented 3 years ago

一般我长时间的会用HttpJob的中间件,可以参考wiki专门的介绍 https://github.com/yuzd/Hangfire.HttpJob/wiki/03.HttpJob.Agent%E7%BB%84%E4%BB%B6%E4%BB%8B%E7%BB%8D%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8

已发布 3.5.6 nuget更新过会你看下

  1. 其实可以尽量写成依赖接口注入的方式,外部可以通过自己实现接口的方式替换内部方法,或者重写替代 image

  2. 当然也可以按照你的方法使用配置文件进行配置 image

TotocQ commented 3 years ago

非常感谢