我正面临使用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;
}
我怀疑是否有任何代码问题,因为它在本地工作正常。 非常感谢,如果有任何想法!
答案 0 :(得分:1)
显然,您没有提供足够的信息来诊断问题,因此我们所能做的就是如何进一步深入了解以获取一些诊断数据。如果你转移到当前版本(9.7),它会更容易帮助,它甚至可以解决问题。
检查转换是否向W3C服务器(或其他地方)发出任何HTTP请求。例如,获取常见的DTD。 W3C故意限制这些请求。 Saxon的最新版本拦截了这些请求,并在Saxon软件中使用了该文件的本地副本,但您使用的是旧版本。您可以使用各种工具来监控HTTP流量。
在没有任何Apache FOP处理的情况下自行运行转换,以查看数字的比较情况。您需要确定问题是在XSLT处理还是XSL-FO处理期间,最好的方法是运行一个而不用另一个。
检查从命令行自行运行转换时是否会遇到相同的性能问题。
检查使用-TP:profile.html获得的Saxon执行配置文件,并查看两台计算机上的结果比较结果。
检查Java配置文件数据,例如使用run = hprof,看看它在两台机器上的比较情况。任何重大差异都为进一步调查提供了线索。