gpt4 book ai didi

java - 是否有更好的方法来减少长时间运行的 quartz 作业的执行时间?

转载 作者:行者123 更新时间:2023-12-01 23:14:58 24 4
gpt4 key购买 nike

我有一个 cron 作业,会在晚上的某个时候触发,它从数据库获取大量大约 100k 的 ProductId,并从服务中获取所有产品的产品信息,对 1 个产品 ID 进行 API 调用大约需要 700 毫秒。

CronJob

public class GetProducts extends QuartzJobBean {

@Autowired
private ProductClient productClient;

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

List<Long> ProductsIds = fetchAllProductIdsFromDb();

Response<ProductClientResponse> response = null;

for (Long productId : ProductsIds) {
ProductClientRequestBody requestBody = new ProductClientRequestBody();
requestBody.putIdInsideTheRequestBody(productId);
response = productClient.getResult(requestBody).execute();

if (response != null && response.isSuccessful()) {
log.info("We have got successful response for {}", i);
}
}
}
}

这里的productClient是服务的Retrofit客户端。因此,这项工作从技术上来说需要 5 个小时才能完成。

#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName=QuartzScheduler
org.quartz.scheduler.instanceId=AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=80
org.quartz.threadPool.threadPriority=5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties=true
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=QRTZ_
org.quartz.jobStore.isClustered=true
org.quartz.jobStore.clusterCheckinInterval=20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.myDS.driver=com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.maxConnections=10
org.quartz.dataSource.myDS.validationQuery=select 0 from dual
org.quartz.scheduler.batchTriggerAcquisitionMaxCount =10
org.quartz.dataSource.myDS.URL=jdbc:mysql://127.0.0.1:3306/quartz
org.quartz.dataSource.myDS.user=root
org.quartz.dataSource.myDS.password=root

这是我的 quartz 属性文件。我想知道是否有更好的方法来获取所有 100k 产品的 ProductInfo。

一种方法

我为所有 ProductId 安排了 100k 作业。而在集群环境中运行的quartz将根据可用的实例进行调度。

org.quartz.threadPool.threadCount=80 - 此属性指出在服务的一个实例中最多 80 个线程可以占用作业。 是吗?如果我有 2 个实例运行,那么至少可以同时运行 100-160 个作业。我的方法正确吗?这可以大大减少时间。

还有比这更好的方法吗?

最佳答案

注意:- 这是为了演示可以进一步即兴编写代码的方法(我尚未测试代码,可能存在语法错误)

<p></p>

<p>public class ProductsJob extends QuartzJobBean {</p>

<pre><code>@Autowired
private ProductClient productClient;

@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
List<Long> ProductsIds = fetchAllProductIdsFromDb();
ProductsExecutor productsExecutor=new ProductsExecutor();
productsExecutor.runTasks(ProductsIds);
}
</code></pre>

<p>}</p>

<p>public class ProductsExecutor {</p>

<pre><code>private int threadPoolSize=10;
private ExecutorService executorService;

public ProductsExecutor()
{
executorService =Executors.newFixedThreadPool(threadPoolSize);
}

public void runTasks(List<Integer> productIds)
{
//Loop and execute the task and wait for them it necessary
ProductsWorker worker=new ProductsWorker();
worker.setProductId(productId);
executorService.invokeAll(worker);
}
</code></pre>

<p>}</p>

<p>public class ProductsWorker implements Runnable {</p>

private int productId;
@Override
public void run() {
ProductClientRequestBody requestBody = new ProductClientRequestBody();
requestBody.putIdInsideTheRequestBody(productId);
response = productClient.getResult(requestBody).execute();

if (response != null && response.isSuccessful()) {
log.info("We have got successful response for {}");
}

}

public void setProductId(int productId)
{
this.productId=productId;
}

}

不要忘记销毁您的执行器服务,因为每次quartz运行都会创建一个新的执行器服务。您还可以为所有提交的任务添加awaitTermination。

关于java - 是否有更好的方法来减少长时间运行的 quartz 作业的执行时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58357733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com