Csv 分布式系统中表现出不一致行为的Univocity bean处理器
我正在使用univocity bean处理器进行文件解析。我能够在我的本地盒子上成功地使用它。但是,在具有多个主机的环境中部署相同的代码时,解析器显示出不一致的行为。比如说,对于无效文件,它并没有处理失败,对于有效文件,它有时也会处理失败 想知道bean处理器实现是否适合多线程分布式环境 示例代码:Csv 分布式系统中表现出不一致行为的Univocity bean处理器,csv,parsing,distributed-system,univocity,Csv,Parsing,Distributed System,Univocity,我正在使用univocity bean处理器进行文件解析。我能够在我的本地盒子上成功地使用它。但是,在具有多个主机的环境中部署相同的代码时,解析器显示出不一致的行为。比如说,对于无效文件,它并没有处理失败,对于有效文件,它有时也会处理失败 想知道bean处理器实现是否适合多线程分布式环境 示例代码: private void validateFile(@Nonnull final File inputFile) throws NonRetriableException { try {
private void validateFile(@Nonnull final File inputFile) throws NonRetriableException {
try {
final BeanProcessor<TargetingInputBean> rowProcessor = new BeanProcessor<TargetingInputBean>(
TargetingInputBean.class) {
@Override
public void beanProcessed(@Nonnull final TargetingInputBean targetingInputBean,
@Nonnull final ParsingContext context) {
final String customerId = targetingInputBean.getCustomerId();
final String segmentId = targetingInputBean.getSegmentId();
log.debug("Validating customerId {} segmentId {} for {} file", customerId, segmentId, inputFile
.getAbsolutePath());
if (StringUtils.isBlank(customerId) || StringUtils.isBlank(segmentId)) {
throw new DataProcessingException("customerId or segmentId is blank");
}
try {
someValidation(customerId);
} catch (IllegalArgumentException ex) {
throw new DataProcessingException(
String.format("customerId %s is not in required format. Exception"
+ " message %s", customerId, ex.getMessage()),
ex);
}
}
};
rowProcessor.setStrictHeaderValidationEnabled(true);
final CsvParser parser = new CsvParser(getCSVParserSettings(rowProcessor));
parser.parse(inputFile);
} catch (TextParsingException ex) {
throw new NonRetriableException(
String.format("Exception=%s occurred while getting & parsing targeting file "
+ "contents, error=%s", ex.getClass(), ex.getMessage()),
ex);
}
}
private CsvParserSettings getCSVParserSettings(@Nonnull final BeanProcessor<TargetingInputBean> rowProcessor) {
final CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(rowProcessor);
parserSettings.setHeaderExtractionEnabled(true);
parserSettings.getFormat().setDelimiter(AIRCubeTargetingFileConstants.FILE_SEPARATOR);
return parserSettings;
}
您使用的是最新版本吗 如果我没有弄错的话,我刚刚意识到您可能受到版本2.5.0中引入的错误的影响,该错误在版本2.5.6中已修复。这困扰了我一段时间,因为这是一个难以追踪的内部并发问题。基本上,当您传递一个没有显式编码的文件时,它将尝试在输入中找到一个UTF BOM标记(有效地使用第一个字符),以自动确定编码。这只发生在输入流和文件中 无论如何,这个问题已经解决了,所以只需更新到最新版本就可以为您解决这个问题(如果您没有使用2.5版,请告诉我) 如果您希望保留当前版本,则如果调用,错误将消失
parser.parse(inputFile, Charset.defaultCharset());
这将防止解析器试图发现文件中是否有BOM标记,从而避免了那个讨厌的bug
希望这对这里图书馆的作者有所帮助。它应该在并发环境中正常工作。您的
someValidation
方法是否同步?你有什么特例?你能用堆栈跟踪更新你的问题吗?此外,您可能会遇到问题,因为您没有提供文件编码。您可能应该调用类似于parser.parse(inputFile,“UTF-8”)代码>使用正确的编码而不是“UTF-8”嗨,someValidation只是一个简单的库调用。问题是我们没有得到任何例外。执行完成,没有任何异常。这个问题时断时续地发生。有时,对于无效文件,验证会成功。这不是在本地主机上发生的,而是在分布式环境中发生的。UTF-8编码是否也会导致不一致的行为?编码可能相关。分布式环境与此无关。如果出现线程问题,您应该能够通过保存服务器首先处理的文件来重现该问题。然后创建一个单一的单元测试,激发多个线程,每个线程在其中处理这些文件。如果没有一组要测试的文件,就不可能解决这个问题。另外,如果没有看到异常,那是因为它们是从主线程外部抛出的。尝试只记录异常,而不是抛出新的DataProcessingException来查看发生了什么
parser.parse(inputFile, Charset.defaultCharset());