Windows 工作流:为什么他们会陷入持久性困境?

发布于 2024-07-29 08:45:32 字数 607 浏览 2 评论 0原文

我有一个使用 SQL 持久性的 Windows 工作流实例,托管在 Web 运行时中,因为工作流是由 ASP.NET 表单提交启动的。 大多数时候它运行得很好,但我注意到有些情况下我必须踢东西:

我注意到 nextTimer 已经逾期了,甚至逾期了几个小时。 有时,持久性数据库中的ownerID和ownedUntil字段为空,有时则不是。 “解锁”和“阻止”字段始终均为“1”。

...然后工作流运行时不会重新拾取它,直到我清空“所有者”字段(如果它们已填充)并通过回收踢出应用程序池,并且在大多数情况下,事情进展顺利。 没有错误(我在所有内容周围都有 try/catch 块,并将捕获的任何内容写到跟踪文件中),所以不是这样。

导致持久化的延迟活动均设置为一分钟,运行时的所有权持续时间也为60秒。 它被卡住的代码应该总是花费不到一分钟的时间。

当我写这篇文章时,我很好奇应用程序池/应用程序域的回收是否会导致它......当工作流尝试在运行时调用任何方法时,它正忙于旋转应用程序域/池,并且可能会泄漏60 秒所有权持续时间。 这听起来有点合理,这会导致它不能正常补水吗?

除了这个岔路之外,什么可能导致我所看到的这种行为? 我不想每天通过解除卡住的工作流程来照顾运行时。

I have a Windows Workflow instance that's using SQL persistence, being hosted in the web runtime, since the workflows are started by ASP.NET form submissions. It runs great most of the time, but I've noticed instances where I have to kick things:

I notice the nextTimer has gone way overdue, even by hours. Sometimes the ownerID and ownedUntil fields are null in the persistence database, sometimes not. The "unlocked" and "blocked" fields are always both "1".

...and then the workflow runtime doesn't pick it back up until I null out the "owner" fields if they're populated and kick the application pool with a recycle, and things go along just fine after that for the most part. There are no errors (I have try/catch blocks around everything and write out anything caught into a trace file), so that's not it.

The delay activities causing the persistence are all set to one minute, and the ownership duration for the runtime is 60 seconds as well. The code that it gets stuck on should always take less than a minute.

As I write this, I'm curious if recycles of the app pool/app domain are causing it...when the workflow tries to call whatever method in the runtime, it's busy spinning up the app domain/pool and might leak over the 60 seconds ownership duration. That sound remotely plausible, and would that cause it to not rehydrate properly?

Barring that sidetrack, what could cause this behavior I'm seeing? I don't want to babysit the runtime every day by unsticking stuck workflows.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

百思不得你姐 2024-08-05 08:45:33

应用程序域回收很可能是您问题的很大一部分。 一旦最后一个请求完成,IIS 将回收 AppDomain。 但是,它不会将另一个线程上运行的代码视为该请求的一部分。 这是在 IIS 中托管时使用 ManualWorkflowSchedulerService 的主要原因之一。 但是,当您使用活动计时器选项时,它仍然使用后台线程来执行工作流活动。

还要确保工作流程闲置后立即卸载。 最简单的方法是使用 SqlWorkflowPersistenceService 上的 UnloadOnIdle 设置。

PersistenceService 仅在启动时检查所有权已过期的工作流。 因此,重新启动 IIS 工作进程很可能也会重新启动旧的工作流程,而无需任何额外的工作。 但由于这是新问题的情况......只需清除旧的所有权也应该可以解决问题。 在这种情况下,PersistenceService 应该在下次重新加载工作流程。 唯一的技巧是知道哪个 runitme ID 是旧的,哪个不是(保存该值的属性不是公开的)。

另一件需要确保的事情是 IIS 工作进程已重新加载。 如果不这样做,则没有 WF 运行时,因此它无法检查过期的计时器。 听起来你已经涵盖了这一点,但以防万一。

Its quite likely that the app domain recycling is a large part of your problem. IIS will recycle an AppDomain as soon as the last request is finished. It does not however see code running on another thread as part of that request. That is one of main reasons for using the ManualWorkflowSchedulerService when hosting in IIS. But when you use the active timers option it still uses a background thread to execute workflow activities.

Also make sure you unload workflows as soon as they go idle. The easiest way of doing so is using the UnloadOnIdle setting on the SqlWorkflowPersistenceService.

The PersistenceService checks for workflows with an expired ownership but only at startup time. So most likely restarting the IIS worker process will also restart old workflows without any extra work. But as this is the case of new problems..... Just clearing out the old ownership should also do the trick. In that case the PersistenceService should just reload the workflows at the next time. The only trick is to know which runitme ID is old and which isn't (the property holding the value is not public).

Another thing to make sure of is that the IIS worker process is reloaded. If this isn't done there is no WF runtime so it cannot check for expired timers. It sounds like you have this covered but just in case.

微凉徒眸意 2024-08-05 08:45:33

您是否检查过数据库和网络服务器上的时钟(如果它们不是同一台服务器)? 我之前在工作流程中遇到过类似的问题,根本原因是数据库和网络服务器时钟不同步。

Have you checked the clock on your db and web servers (if they are not the same server)? I've had similar problems before with workflow and the root cause was that the db and web server clocks were not in sync.

〆凄凉。 2024-08-05 08:45:33

工作流实例被锁定到运行时(因此多个工作流运行时可以共享数据库,而无需同时处理实例)。 当 AppDomain 回收时,运行时应该停止,导致实例解锁

这可能是多余的,我没有检查这一点,但它有助于解锁工作流实例:

AppDomain.CurrentDomain.DomainUnload += ((sender, args) =>
                                             {
                                                 if (_runtime.IsStarted)
                                                     _runtime.StopRuntime();
                                             });
AppDomain.CurrentDomain.ProcessExit += ((sender, args) =>
                                            {
                                                if (_runtime.IsStarted)
                                                    _runtime.StopRuntime();
                                            });

Workflow instances are locked to a runtime (so multiple workflow runtimes can share a database without instances being handled by both). When the AppDomain recycles, the Runtime should be stopped, causing the instances to become unlocked

This might be a redundant, I didn't check for that, but it helped in unlocking the workflow instances:

AppDomain.CurrentDomain.DomainUnload += ((sender, args) =>
                                             {
                                                 if (_runtime.IsStarted)
                                                     _runtime.StopRuntime();
                                             });
AppDomain.CurrentDomain.ProcessExit += ((sender, args) =>
                                            {
                                                if (_runtime.IsStarted)
                                                    _runtime.StopRuntime();
                                            });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文