如何在AEM as a Cloud Service中的领导者实例上运行作业

了解如何在AEM as a Cloud Service中的AEM Author服务中的领导实例上运行作业,并了解如何将其配置为仅运行一次。

Sling作业是在后台运行的异步任务,旨在处理系统或用户触发的事件。 默认情况下,这些作业在集群中的所有实例(pod)之间均匀分布。

有关详细信息,请参阅Apache Sling事件和作业处理

创建和处理作业

为演示目的,让我们创建一个简单的​作业,以指示作业处理器记录消息

创建作业

使用以下代码来​创建 Apache Sling作业:

package com.adobe.aem.guides.wknd.core.sling.jobs.impl;

import java.util.HashMap;
import java.util.Map;

import org.apache.sling.event.jobs.JobManager;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(immediate = true)
public class SimpleJobCreaterImpl {

    private static final Logger log = LoggerFactory.getLogger(SimpleJobCreaterImpl.class);

    // Define the topic on which the job will be created
    protected static final String TOPIC = "wknd/simple/job/topic";

    // Inject a JobManager
    @Reference
    private JobManager jobManager;

    @Activate
    protected final void activate() throws Exception {
        log.info("SimpleJobCreater activated successfully");
        createJob();
        log.info("SimpleJobCreater created a job");
    }

    private void createJob() {
        // Create a job and add it on the above defined topic
        Map<String, Object> jobProperties = new HashMap<>();
        jobProperties.put("action", "log");
        jobProperties.put("message", "Job metadata is: Created in activate method");
        jobManager.addJob(TOPIC, jobProperties);
    }
}

上述代码中的要注意事项包括:

  • 作业有效负载有两个属性: actionmessage
  • 使用JobManageraddJob(...)方法,将作业添加到主题wknd/simple/job/topic

处理作业

使用以下代码来​ 处理 ​上述Apache Sling作业:

package com.adobe.aem.guides.wknd.core.sling.jobs.impl;

import org.apache.sling.event.jobs.Job;
import org.apache.sling.event.jobs.consumer.JobConsumer;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(service = JobConsumer.class, property = {
        JobConsumer.PROPERTY_TOPICS + "=" + SimpleJobCreaterImpl.TOPIC
}, immediate = true)
public class SimpleJobConsumerImpl implements JobConsumer {

    private static final Logger log = LoggerFactory.getLogger(SimpleJobConsumerImpl.class);

    @Override
    public JobResult process(Job job) {
        // Get the action and message properties
        String action = job.getProperty("action", String.class);
        String message = job.getProperty("message", String.class);

        // Log the message
        if ("log".equals(action)) {
            log.info("Processing WKND Job, and {}", message);
        }

        // Return a successful result
        return JobResult.OK;
    }

}

上述代码中的要注意事项包括:

  • SimpleJobConsumerImpl类实现JobConsumer接口。
  • 这是已注册以使用主题wknd/simple/job/topic中的作业的服务。
  • process(...)方法通过记录作业有效负载的message属性来处理该作业。

默认作业处理

当您将上述代码部署到AEM as a Cloud Service环境并在AEM Author服务(作为具有多个AEM Author JVM的集群运行)上运行它时,作业将在每个AEM Author实例(pod)上运行一次,这意味着创建的作业数量与pod的数量相匹配。 Pod的数量将始终大于1(对于非RDE环境),但会因AEM as a Cloud Service的内部资源管理而波动。

作业在每个AEM Author实例(pod)上运行,因为wknd/simple/job/topic与AEM的主队列相关联,该主队列将作业分发到所有可用实例。

如果作业负责更改状态(如创建或更新资源或外部服务),则这通常会出现问题。

如果希望作业在AEM Author服务上只运行一次,请添加如下所述的作业队列配置

您可以通过在Cloud Manager中查看AEM Author服务的日志来验证它。

所有实例已处理 作业

您应会看到:

<DD.MM.YYYY HH:mm:ss.SSS> [cm-pxxxx-exxxx-aem-author-68775db964-nxxcx] *INFO* [sling-oak-observation-15] org.apache.sling.event.impl.jobs.queues.JobQueueImpl.<main queue> Starting job queue <main queue>
<DD.MM.YYYY HH:mm:ss.SSS> INFO [com.adobe.aem.guides.wknd.core.sling.jobs.impl.SimpleJobConsumerImpl] Processing WKND Job, and Job metadata is: Created in activate method

<DD.MM.YYYY HH:mm:ss.SSS> [cm-pxxxx-exxxx-aem-author-68775db964-r4zk7] *INFO* [sling-oak-observation-11] org.apache.sling.event.impl.jobs.queues.JobQueueImpl.<main queue> Starting job queue <main queue>
<DD.MM.YYYY HH:mm:ss.SSS> INFO [com.adobe.aem.guides.wknd.core.sling.jobs.impl.SimpleJobConsumerImpl] Processing WKND Job, and Job metadata is: Created in activate method

有两个日志条目,每个AEM Author实例(68775db964-nxxcx68775db964-r4zk7)各一个,指示每个实例(pod)已处理作业。

如何在领导实例上运行作业

要在AEM Author服务上仅运行作业​一次,请创建类型为​ Ordered ​的新Sling作业队列,并将您的作业主题(wknd/simple/job/topic)与此队列关联。 使用此配置时,将仅允许前导AEM创作实例(pod)处理作业。

在您的AEM项目的ui.config模块中,创建一个OSGi配置文件(org.apache.sling.event.jobs.QueueConfiguration~wknd.cfg.json)并将其存储在ui.config/src/main/content/jcr_root/apps/wknd/osgiconfig/config.author文件夹中。

{
    "queue.name":"WKND Queue - ORDERED",
    "queue.topics":[
      "wknd/simple/job/topic"
    ],
    "queue.type":"ORDERED",
    "queue.retries":1,
    "queue.maxparallel":1.0
  }

上述配置中需要注意的要点包括:

  • 队列主题设置为wknd/simple/job/topic
  • 队列类型设置为ORDERED
  • 最大并行作业数设置为1

在部署上述配置后,作业将仅由领导实例处理,确保它在整个AEM Author服务中仅运行一次。

<DD.MM.YYYY HH:mm:ss.SSS> [cm-pxxxx-exxxx-aem-author-7475cf85df-qdbq5] *INFO* [FelixLogListener] Events.Service.org.apache.sling.event Service [QueueMBean for queue WKND Queue - ORDERED,7755, [org.apache.sling.event.jobs.jmx.StatisticsMBean]] ServiceEvent REGISTERED
<DD.MM.YYYY HH:mm:ss.SSS> INFO [com.adobe.aem.guides.wknd.core.sling.jobs.impl.SimpleJobConsumerImpl] Processing WKND Job, and Job metadata is: Created in activate method
<DD.MM.YYYY HH:mm:ss.SSS> [com.adobe.aem.guides.wknd.core.sling.jobs.impl.SimpleJobConsumerImpl] Processing WKND Job, and Job metadata is: Created in activate method
recommendation-more-help
4859a77c-7971-4ac9-8f5c-4260823c6f69