xmlをPDFに変換するためにsaxonとapache foを使用するとパフォーマンス上の問題に直面しています。私たちがテストするために使用するpdfは85ページあり、およそ320kです。 メソッド呼び出しではほぼ2分を費やし、ローカルではわずか5秒しかかかりません。 私たちはそのメソッド呼び出し中にCPU使用量とGCを監視し、サーバー上ではCPU使用率が5%で安定しており、サーバー側からCPUに制限がないことがわかりました。 GCは1秒から2秒ごとに発生しますが、すべてマイナーGCであり、それぞれ10〜50msしかかかりません。我々はまた、テスト中の待機を監視し、非常に低いままであった。
私たちが使っているlibsはsaxon 9.1とapache fop 2.1です(saxonとapacheのバージョンは異なりますが、問題は残ります) xmlとxslファイルが大きすぎて投稿できません。以下は変換のサンプルコードです:Saxon xsltはサーバー上では遅いがローカルでは高速
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;
}
ローカルでは正常に動作するため、コードの問題が発生するのではないかと疑いがあります。 これについてのご意見があれば幸いです!
返信いただきありがとうございます。私はバージョン9.7と9.6を試しましたが、問題はまだ同じです。試してみると、foファイルを生成し、apacheを完全に使わないようにしました。この手順は1秒かかるだけです。これは、遅さがapache fo側によって引き起こされたことを意味しますか?なぜなら、foが生成されたときにSaxonの仕事が完了したのか、それともFOからPDFへの処理に関わったのか分からないからです。また、SaxonはFOからpdfを生成する関数を持っていますか?ありがとう –
これらの測定値が正しい場合、あなたの問題はSaxonではなくApache FOPにあります(つまり、ごめんなさい、私はあなたをさらに助けることはできません)。 Saxonは、XSL-FOからPDFへの変換には関与していません。 –
おかげさまで、私たちはそれぞれの異なるステップで費やされた時間を測定し、XSL-foからPDFへの処理はほとんどの時間を要したので、この問題はapache fop側で発生するようです。 –