java - GSAItem.getPropertyValue 占用超过 70% 的 CPU 时间(Dynatrace 数据)
问题描述
我正在尝试并行进行提要处理,从平面文件中提取数据并填充一些存储库项。
代码有点像下面。在生产中,它非常慢,通过 Dynatrace 进行调查时,我可以看到 getPropertyValue 方法调用中的锁定时间比平时要大(总时间的 70% 用于锁定)
在使用 dynatrace 深入研究 getPropertyvalue 方法时,我可以看到这个方法 GSAItemDescriptor.putItemInCache 是罪魁祸首。我怀疑此方法中有同步块导致线程等待。
有什么办法破解这个?
...
try {
inventoryIdsList.parallelStream().forEach((item)->{
final String lockString = item.split("_")[0] + "_inventory_index_update";
final String lock = lockString.intern();
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
synchronized (lock) {
if(doIncrementalIndexInNewTransaction(item)) {
vlogDebug("Success indexing done inventoryId={0}",item);
} else {
vlogError("Failed_to_index inventoryId={0}",item);
}
}
},pool);
futures.add(future);
});
CompletableFuture<Void> allfutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
allfutures.get();
} catch (Exception e) {
vlogError(e,"Error while executing async.");
}
...
void doIncrementalIndexInNewTransaction(inventoryId){
TransactionDemarcation td = new TransactionDemarcation();
boolean success = false;
try {
vlogDebug("Processig inventory item idexing inventoryId={0}",inventoryId);
td.begin(getTransactionManager(),TransactionDemarcation.REQUIRES_NEW);
RepositoryItem inventoryRI = getInventoryRepository().getItem(inventoryId,"inventory");
if(inventoryRI != null){
String inventoryUpdateStore= (String) inventoryRI.getPropertyValue("locationId");
String skuId =(String)inventoryRI.getPropertyValue("skuId");
MutableRepositoryItem skuRepositoryItem= (MutableRepositoryItem) mutableRepository.getItemForUpdate(skuId, "sku");
...
Some other operations
...
skuRepositoryItem.setPropertyValue("lastUpdated",System.currentMillis());
}
vlogDebug("Success inventoryId={0}",inventoryId);
return true;
} catch (Exception e) {
vlogError(e,"Exception occured while processing inventoryId={0}",inventoryId);
success = false;
} finally {
try {
td.end(!success);
} catch (Exception e) {
vlogError(e,"Unable to end transaction id={0} \n inventoryId={1}", td,inventoryId);
}
}
return success;
}
提前致谢。
解决方案
推荐阅读
- flutter - 如何让 Flutter 容器从屏幕的左边缘开始?
- flutter - 从 imap 下载附件:BODY[1.3.1.2] 和 BODY.PEEK[1.3.1.2] 返回 null
- pandas - 在 pandas 中获取等于给定行的值的列名
- node.js - 使用纪元时间戳作为客户端输入的 Postgres 数据查询?
- alpha - 以透明背景录制
- python - 使用 Runge-Kutta 算法 python 求解罗斯勒振荡器
- c# - 从查找表中批量读取的有效方法
- javascript - 如何通过定义特定的代码属性映射此对象数组以获取完整对象?
- mysql - 两个单独的更新涉及一个 SQL 查询中的不同列
- spring-boot - spring security自定义表达式中访问http请求