2016-10-24 10 views
1

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; 

    } 

ローカルでは正常に動作するため、コードの問題が発生するのではないかと疑いがあります。 これについてのご意見があれば幸いです!

答えて

1

明らかに、問題を診断するのに十分な情報を提供していないため、診断データを得るためにさらにドリルダウンする方法に関するアドバイスを提供するだけです。現在のバージョン(9.7)に移行すると、助けがさらに簡単になり、問題を解決する可能性もあります。

変換でW3Cサーバー(または他の場所)へのHTTP要求が行われているかどうかを確認します。たとえば、共通のDTDを取得する。 W3Cは意図的にこれらの要求を抑制する。最近のSaxonのリリースはこれらの要求を傍受し、Saxonソフトウェア内のファイルのローカルコピーを使用しますが、非常に古いバージョンを使用しています。 HTTPトラフィックを監視するために使用できるさまざまなツールがあります。

Apache FOP処理を行わずに単独で変換を実行し、図の比較方法を確認します。問題がXSLT処理中であるのかXSL-FO処理中であるのかを判断する必要があります。これを実行する最善の方法は、もう一方を実行せずに実行することです。

コマンドラインから単独で変換を実行すると、同じパフォーマンスの問題が発生するかどうかを確認してください。

-TP:profile.htmlを使用して取得したSaxon実行プロファイルを確認し、2台のマシンでどのように結果が比較されるかを確認してください。

Javaプロファイルデータを確認します。 run = hprofを使用して、2つのマシンでどのように比較するかを確認してください。大きな違いがあれば、それ以上の調査の手掛かりとなります。

+0

返信いただきありがとうございます。私はバージョン9.7と9.6を試しましたが、問題はまだ同じです。試してみると、foファイルを生成し、apacheを完全に使わないようにしました。この手順は1秒かかるだけです。これは、遅さがapache fo側によって引き起こされたことを意味しますか?なぜなら、foが生成されたときにSaxonの仕事が完了したのか、それともFOからPDFへの処理に関わったのか分からないからです。また、SaxonはFOからpdfを生成する関数を持っていますか?ありがとう –

+0

これらの測定値が正しい場合、あなたの問題はSaxonではなくApache FOPにあります(つまり、ごめんなさい、私はあなたをさらに助けることはできません)。 Saxonは、XSL-FOからPDFへの変換には関与していません。 –

+0

おかげさまで、私たちはそれぞれの異なるステップで費やされた時間を測定し、XSL-foからPDFへの処理はほとんどの時間を要したので、この問題はapache fop側で発生するようです。 –

関連する問題