Saxon xslt转换为PDF在服务器上运行缓慢,但在本地

时间:2016-10-24 18:10:14

标签: linux tomcat saxon apache-fop

我正面临使用saxon和apache来将xml转换为PDF的性能问题。我们用来测试的pdf有85页,大约是320k。它在转换方法调用上花费近2分钟,在本地只需不到5秒。 我们在该方法调用期间监视cpu使用情况和GC,发现在服务器上,cpu使用率保持稳定在5%,我们对服务器端的cpu没有任何限制。 GC每1到2秒发生一次,但它们都是次要的GC,每个只需要10到50毫秒。我们还会在测试过程中监控等待,并且保持非常低 我们使用的库是:saxon 9.1和apache fop 2.1(我们使用不同的saxon和apache版本进行了测试,但问题仍然存在) xml和xsl文件太大,所以我无法发布它们。下面是转换的示例代码:

 public static TransformerFactory transformerFactory;
 public static Transformer xlsProcessor;

 public static byte[] generatePDF(InputStream xmlData, String xslFile)
        throws TransformerException, IOException {


    byte[] fileArray = null;
    InputStream xsltfile = null;
    ByteArrayOutputStream outStream = null;
    try {
        xsltfile =
            XmlToPdfGenerator.class.getClassLoader()
                    .getResourceAsStream(xslFile);

        StreamSource source = new StreamSource(xmlData);

        StreamSource transformSource = new StreamSource(xsltfile);
        if (null== fopFactory){
            File xconf= new File(XmlToPdfGenerator.class.getClassLoader().getResource("a xconf file").getFile());
            fopFactory = FopFactory.newInstance(xconf);
        }
        FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
        outStream = new ByteArrayOutputStream();
        Transformer xslfoTransformer =
            getTransformer(transformSource);
        if (xslfoTransformer != null) {
        Fop fop;
        try {
            fop =
                fopFactory.newFop(MimeConstants.MIME_PDF,
                        foUserAgent, outStream);
            Result res = new SAXResult(fop.getDefaultHandler());
            try {

            xslfoTransformer.transform(source, res);

            fileArray = outStream.toByteArray();
            } catch (TransformerException e) {
                // some error handling logic omitted
            } catch (Exception e) {
                // some error handling logic omitted
            }
        } catch (FOPException e) {
                // some error handling logic omitted
        }
        }
    } catch (TransformerFactoryConfigurationError e) {
                // some error handling logic omitted
    } catch (Exception e) {
                // some error handling logic omitted
    } finally {
        if (null != xsltfile) {
        xsltfile.close();
        }
        if (null != outStream) {
        outStream.close();
        }
    }
    return fileArray;
    }

 private static Transformer getTransformer(StreamSource streamSource) {
   if (null==transformerFactory){
    transformerFactory =
            new net.sf.saxon.TransformerFactoryImpl();
    }
    try {
        if (xlsProcessor == null) {
            xlsProcessor  =
                transformerFactory.newTransformer(streamSource);
        }
        return xlsProcessor  ;
    } catch (TransformerConfigurationException e) {
        // some error handling logic 
    }
    return null;

    }

我怀疑是否有任何代码问题,因为它在本地工作正常。 非常感谢,如果有任何想法!

1 个答案:

答案 0 :(得分:1)

显然,您没有提供足够的信息来诊断问题,因此我们所能做的就是如何进一步深入了解以获取一些诊断数据。如果你转移到当前版本(9.7),它会更容易帮助,它甚至可以解决问题。

检查转换是否向W3C服务器(或其他地方)发出任何HTTP请求。例如,获取常见的DTD。 W3C故意限制这些请求。 Saxon的最新版本拦截了这些请求,并在Saxon软件中使用了该文件的本地副本,但您使用的是旧版本。您可以使用各种工具来监控HTTP流量。

在没有任何Apache FOP处理的情况下自行运行转换,以查看数字的比较情况。您需要确定问题是在XSLT处理还是XSL-FO处理期间,最好的方法是运行一个而不用另一个。

检查从命令行自行运行转换时是否会遇到相同的性能问题。

检查使用-TP:profile.html获得的Saxon执行配置文件,并查看两台计算机上的结果比较结果。

检查Java配置文件数据,例如使用run = hprof,看看它在两台机器上的比较情况。任何重大差异都为进一步调查提供了线索。