Closed miniprince closed 4 years ago
我在linux系统上部署到docker'容器的时候没有遇到过这个问题。你的linux服务器是国内的吗? 你在Startup.cs
下面的这个代码 去掉试一试
//强制显示中文
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
或者改成 ···
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("");
···
看还会报错吗?
是的,版本是Centos7.7,我使用Hangfire官方版本也遇到过这个问题,.net跨平台似乎有较大概率会面临这个问题。请参考:https://www.bluetian.net/2018/11/18/cross-platformTimeZones/
Hangfire.HttpJob 就是hangfire的一个插件而已,Hangfire能遇到的问题,肯定也会在这里遇到。我看下这个你说的解决方案:建议使用TimeZoneConverter开源项目进行转换
感谢你提供
大牛您好,我在试用中又发现一个时区问题,在windows环境下正常但在linux环境下却报错,找了一个相应的解决方案,仅供参考 。 [root@Centos7 BisJob]# dotnet BisJobSqlserver.dll Hosting environment: Production Content root path: /web/BisJob Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down. fail: Hangfire.Server.RecurringJobScheduler[0] Recurring job '接口测试' can't be scheduled due to an error and will be disabled. System.TimeZoneNotFoundException: The time zone ID 'China Standard Time' was not found on the local computer. ---> System.IO.FileNotFoundException: Could not find file '/usr/share/zoneinfo/China Standard Time'. File name: '/usr/share/zoneinfo/China Standard Time' at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func
2 errorRewriter) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode) at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at Internal.IO.File.ReadAllBytes(String path) at System.TimeZoneInfo.TryGetTimeZoneFromLocalMachine(String id, TimeZoneInfo& value, Exception& e) --- End of inner exception stack trace --- at System.TimeZoneInfo.FindSystemTimeZoneById(String id) at Hangfire.DefaultTimeZoneResolver.GetTimeZoneById(String timeZoneId) at Hangfire.RecurringJobEntity..ctor(String recurringJobId, IDictionary
2 recurringJob, ITimeZoneResolver timeZoneResolver, DateTime now) 解决方案:建议使用TimeZoneConverter开源项目进行转换//在不同操作系统上使用统一的方式区解决时区的问题 TimeZoneInfo timeZoneInfo = TZConvert.GetTimeZoneInfo("China Standard Time"); try { //支持添加一个 只能手动出发的 if (string.IsNullOrEmpty(jobItem.Cron)) { RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), Cron.Never, timeZoneInfo, jobItem.QueueName.ToLower()); return true; }
RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), jobItem.Cron, timeZoneInfo, jobItem.QueueName.ToLower()); return true; } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex); return false; } ```你要把原来的服务删除掉,重新添加进去。China Standard Time这个时区Linux下识别不了
@18616865900 你也是希望用TimeZoneConverter开源项目进行转换?吗
我有一个问题:
我也没有指定用 China Standard Time 为啥会报这个错呢
System.TimeZoneNotFoundException: The time zone ID 'China Standard Time' was not found on the local computer.
---> System.IO.FileNotFoundException: Could not find file '/usr/share/zoneinfo/China Standard Time'.
File name: '/usr/share/zoneinfo/China Standard Time'
我怀疑是我在demo的Startup.cs
下面的这个代码 造成的
//强制显示中文 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
@miniprince 可以去掉试试报不报错吗?
我的想法是: 可以自己指定时区,如果指定了 就用 TimeZoneConverter 转换,否则就用默认的 TimeZoneInfo.Local ...
我也是没有指定时区但是报错了,因为Centos7系统安装时默认时区选择的是中国上海时区,TimeZoneInfo.Local取的是默认时区因此报错。现在的问题应该是跟操作系统的时区有关。
@miniprince @18616865900 我刚提交了一个版本,可以配置时区参数
这样方便外部来进行设置,可参考下面的wiki介绍
大牛,非常感谢。之前我这边是测试环境是好的,正式环境也是好的,刚上线2周,可是不知道什么原因,测试环境突然不执行了,正式环境还是正常的。很奇怪,找了好几天原因,明天有个需求要用到这个服务,刚才把代码安你说的改了下,测试环境好了。我在怀疑是不是之前的版本在docker 上是不是不是很稳定。
还有个问题就是有,我这边有的job数据量大 我要分批并行执行,我现在用的方法是把分批的数据添加到Hangfire.HttpJob.Client添加到任务中,这样有个缺点就是Cron值不好设置,不想用Hangfire.HttpJob.Agent,因为用Hangfire.HttpJob.Agent就要在服务中写业务代码了 ,你这边有没好的方法呢。
新版本我已测试,在Centos7下运行正常,时区问题完美解决,非常感谢。
@18616865900 你也是希望用TimeZoneConverter开源项目进行转换?吗 是的,我的是突然服务不跑了,之前是好的。按照你说的方法问题解决了,之前的版本在部署在docker上容易出问题,非常感谢。
@18616865900
还有个问题就是有,我这边有的job数据量大 我要分批并行执行,我现在用的方法是把分批的数据添加到Hangfire.HttpJob.Client添加到任务中,这样有个缺点就是Cron值不好设置,不想用Hangfire.HttpJob.Agent,因为用Hangfire.HttpJob.Agent就要在服务中写业务代码了 ,你这边有没好的方法呢。
你是用HttpJob.Client 创建周期性Job 吗? 我觉得应该是创建BackGroundJob吧。 但是这样没法做到并行,如果你用Hangfire.HttpJob.Agent组件的话,其实就很简单了。可以在你的job里面用多线程
大牛您好,我在试用中又发现一个时区问题,在windows环境下正常但在linux环境下却报错,找了一个相应的解决方案,仅供参考 。 [root@Centos7 BisJob]# dotnet BisJobSqlserver.dll Hosting environment: Production Content root path: /web/BisJob Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down. fail: Hangfire.Server.RecurringJobScheduler[0] Recurring job '接口测试' can't be scheduled due to an error and will be disabled. System.TimeZoneNotFoundException: The time zone ID 'China Standard Time' was not found on the local computer. ---> System.IO.FileNotFoundException: Could not find file '/usr/share/zoneinfo/China Standard Time'. File name: '/usr/share/zoneinfo/China Standard Time' at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func
2 errorRewriter) at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode) at System.IO.FileStream.OpenHandle(FileMode mode, FileShare share, FileOptions options) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options) at Internal.IO.File.ReadAllBytes(String path) at System.TimeZoneInfo.TryGetTimeZoneFromLocalMachine(String id, TimeZoneInfo& value, Exception& e) --- End of inner exception stack trace --- at System.TimeZoneInfo.FindSystemTimeZoneById(String id) at Hangfire.DefaultTimeZoneResolver.GetTimeZoneById(String timeZoneId) at Hangfire.RecurringJobEntity..ctor(String recurringJobId, IDictionary
2 recurringJob, ITimeZoneResolver timeZoneResolver, DateTime now) 解决方案:建议使用TimeZoneConverter开源项目进行转换//在不同操作系统上使用统一的方式区解决时区的问题 TimeZoneInfo timeZoneInfo = TZConvert.GetTimeZoneInfo("China Standard Time"); try { //支持添加一个 只能手动出发的 if (string.IsNullOrEmpty(jobItem.Cron)) { RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), Cron.Never, timeZoneInfo, jobItem.QueueName.ToLower()); return true; }