【发布时间】:2020-02-09 22:54:06
【问题描述】:
我有一个将在晚上某个时间触发的 cron 作业,它会从数据库中获取大约 100k 的大量 productId, 并从一个服务中获取所有这些产品的 productInfo,该服务对 1 个 productId 的 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
这是我的石英属性文件。 我想知道是否有更好的方法来获取所有 100k 产品的 ProductInfo。
一种方法
我为所有 ProductId 安排了 100k 个作业。而在集群环境中运行的quartz会根据可用的实例进行调度。
org.quartz.threadPool.threadCount=80 - 该属性表明在一个服务实例中最多有 80 个线程可以占用作业。 是吗? 如果我有 2 个实例正在运行,那么至少 100-160 个作业可以同时运行。我的方法正确吗?这可以大大减少时间。
还有比这更好的方法吗?
【问题讨论】:
-
你可以使用quartz来调度job,也可以使用Executors来实际运行job。所以本质上,你不会持有由quartz框架调用的线程。
-
所以你的意思是我应该像我一样创建一个工作,并且在里面应该使用执行器线程。是吗?
-
是的。所以创建作业,然后将责任委托给另一个类,该类将拥有执行器并可以并行运行您的作业。根据您的要求调整执行器的线程数。这将使任何其他石英计划任务的空间,因为线程将被快速释放。
标签: java spring spring-boot quartz-scheduler