Csv 分布式系统中表现出不一致行为的Univocity 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 {

我正在使用univocity bean处理器进行文件解析。我能够在我的本地盒子上成功地使用它。但是,在具有多个主机的环境中部署相同的代码时,解析器显示出不一致的行为。比如说,对于无效文件,它并没有处理失败,对于有效文件,它有时也会处理失败

想知道bean处理器实现是否适合多线程分布式环境

示例代码:

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());