【问题标题】:Priority of Sitecore scheduled jobsSitecore 计划作业的优先级
【发布时间】:2016-10-03 17:03:34
【问题描述】:

我有两个按计划作业运行的 Sitecore 代理。代理 A 是具有优先级的长期运行任务。代理 B 是具有优先级的短期任务。 B 运行的间隔比 A 的间隔短。

问题是 B 永远不会运行,而 A 已经在运行。

我已经实现了this,以便能够在内容编辑器中手动运行代理。当我这样做时,虽然 A 已经在运行,但我可以运行 B(即使我在自定义对话框中将它们设置为相同的线程优先级)。

如何在我的配置文件中指定 B 的优先级高于 A?或者让我的计划作业设置为多线程,以便在 Sitecore 中同时运行作业?有标准的方法吗?

我尝试了like this 在代理实现中设置线程优先级的方法,但是当A 已经运行时,此代码从未在B 中调用。因此,优先级应该以某种方式在作业实施本身“之前”完成。

【问题讨论】:

  • 首先作业 B 在没有从 Run Agent 手动触发的情况下运行吗?
  • 是的。这些作业在不同时运行时完美
  • 两个代理是否执行相同的工作?例如,两者都执行发布
  • 没有。 A 将一些数据导入我们的电子商务数据库 (uCommerce)。 B 从我们的电子商务解决方案中导出订单

标签: multithreading sitecore scheduled-tasks


【解决方案1】:

在意识到将我的高优先级计划任务 B 作为 Sitecore 中的后台代理运行不是一个好的解决方案后,我最终选择了以下解决方案。为了回答这个问题,我现在打电话给 B:ExampleJob

我创建了一个名为ExampleJobStarter 的新代理类。这项工作的目的只是启动另一个运行实际工作的线程ExampleJob

public class ExampleJobStarter
{
    public override void Run()
    {
        if (ExampleJob.RunTheExampleJob) return;
        ExampleJob.RunTheExampleJob = true;
        Task.Run(() => new ExampleJob().Run());
    }
}

public class ExampleJob
{
    public static bool RunTheExampleJob;

    public override void Run()
    {
        while (RunTheExampleJob)
        {
            DoWork();
            Thread.Sleep(10000);
        }
    }

    private void DoWork()
    {
        ... // here I perform the actual work
    }
}

ExampleJobStarter 现在已在我的 Sitecore 配置文件中注册为每 10 分钟运行一次。我还从 Sitecore 配置中删除了 ExampleJob,因此它不会自动运行(因此,它本身不再是 Sitecore 作业)。 ExampleJobStarter 将简单地确保 ExampleJob 在另一个线程中运行。 ExampleJob 本身将每 10 秒完成一次工作,不受低优先级作业代理的干扰,该代理仍作为普通后台代理运行。

如果您走这条路,请注意死锁问题(在这种情况下,我正在使用的数据不是问题)。

【讨论】:

    【解决方案2】:

    正如另一个答案中已经提到的,Sitecore 计划任务是按顺序运行的,因此每个代理仅在前一个代理完成后运行。

    但是,数据库中定义的任务可以运行async,这意味着您可以安排多个任务并行运行。

    您需要创建一个命令并定义一个时间表:

    定义命令

    命令在 Sitecore 客户端中定义。

    1. 在内容编辑器中导航到 /sitecore/system/Tasks/Commands
    2. 使用命令模板创建新项目
    3. 指定类型和方法字段。

    定义时间表

    数据库代理将根据调度中的设置执行命令。

    1. 在内容编辑器中导航到 /sitecore/system/Tasks/Schedules
    2. 使用计划模板创建新项目
    3. 对于命令字段,选择您刚刚创建的命令项
    4. 如果任务适用于特定项目,您可以在“项目”字段中识别这些项目。该字段支持多种格式。
    5. 对于“计划”字段,您可以确定任务的运行时间。此字段的值采用竖线分隔格式。
    6. 在计划中,检查标记为Async 的字段。

    您可以阅读有关Database Scheduler in the Sitecore Community Docs 的更多信息。

    请注意,如果您安排太多任务并行运行,这可能会导致性能问题。

    如果您无法像在 config.如果您不能简单地从代码中访问配置设置(并且它们需要传入),那么对于配置中定义的计划任务,您可以从计划任务代码中调用 Sitecore 作业。 Sitecore 作业作为一个线程运行,每个作业都会启动一个新线程,因此可以并行运行,只需确保作业名称是唯一的(同名的作业将排队)。

    【讨论】:

      【解决方案3】:

      您可能已经从 Hishaam 的回答中了解到(不打算重复这个好信息),使用 Sitecore 代理可能不是您尝试做的最佳解决方案。对于类似的设置(需要在电子商务网站上执行导入、导出或其他排队任务的任务),我使用了外部调度引擎(在我的情况下,Hangfire 可以很好地完成工作,但您也可以使用其他的)这在我的 Sitecore 解决方案中称为服务。这些服务作为一个层执行以到达 Sitecore。

      您可以决定要使用这些服务走多远(甚至可以启动新线程),但它们将能够彼此相邻运行。这样您就不会遇到另一个进程仍在运行的问题。我选择了一种架构,其中服务对真正的业务逻辑来说是非常薄的一层。

      您可能需要确保一个服务背后的代码在已经运行时不能被调用(在处理队列的情况下我需要这样做),但这些事情在 .net 代码中都是可能的。

      我发现此设置更强大,尤其是对于重要的任务。任务需要运行的时间也更容易配置。

      【讨论】:

      • 是的,我考虑过(在 Sitecore 之外运行任务)。我也考虑过Sitecron,但我没有这方面的经验
      【解决方案4】:

      原因是因为 Sitecore Scheduled Job 是按顺序运行的。因此,如果您正在执行一个作业,它在完成之前不会触发其他作业。

      如果我没记错的话,sitecore 会将需要在当前运行的作业之后执行的其他作业排入队列。

      由于您使用 Run Agent Tool 触发作业,它会运行,因为您正在强制它执行。除了发布之外,它不会检查是否有另一个作业正在运行,它会排队,因为它正在将项目从源数据库传输到目标数据库。

      编辑:

      对于 Sitecore v7.x,您可以从 Web.config 或对于 Sitecore v8.x 的 Sitecore.config 检查<job>。您将看到用于作业的管道。如果我没记错的话,我认为您需要检查调度程序的代码。命名空间是Sitecore.Tasks.Scheduler, Sitecore.Kernel

      谢谢

      【讨论】:

      • 你能改变这种行为吗?
      • 我不这么认为。这将需要更改 sitecore 计划作业管道。最好不要弄乱它,因为还有其他预定的代理。你的工作 A 和 B 是否相互依赖?
      • 无依赖性。计划作业管道的名称是什么?那我可以自己去看看。我查看了 showconfig.aspx,但找不到可以挂接的地方
      猜你喜欢
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多