2016-10-24 8 views
1

xml을 PDF로 변환하는 saxon 및 apache fo를 사용하면 성능 문제가 있습니다. 우리가 테스트하는 데 사용하는 pdf는 85 페이지이고 320k 정도입니다. 메소드 호출에서 거의 2 분을 보내고 로컬에서는 5 초 미만 만 소요됩니다. 우리는 해당 메소드 호출 중에 CPU 사용량과 GC를 모니터링하여 서버에서 cpu 사용이 5 %로 일정하게 유지되고 서버 측에서 cpu에 대한 제한이 없다는 것을 알았습니다. GC는 1-2 초마다 발생하지만 모두 마이너 GC이며 각각 10 ~ 50ms 만 소요됩니다. 우리는 또한 테스트 중 io wait를 모니터링하고 매우 낮게 유지했습니다.
libs 우리가 사용하는 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 실행 프로필을 확인하고 두 시스템에서 결과를 비교하는 방법을 확인하십시오.

Java 프로필 데이터를 확인하십시오. run = hprof를 사용하여 두 시스템에서 어떻게 비교되는지보십시오. 주요 차이점은 추가 조사를위한 단서를 제공합니다.

+0

답장을 보내 주셔서 감사합니다. 나는 9.7과 9.6 버전을 시도했지만 문제는 여전히 동일하다. 단지 fo 파일을 생성하고 아파치 fo를 완전히 사용하지 않으며이 단계는 1 초 걸립니다. 이것은 느린 것은 아파치쪽으로 인해 발생했다는 것을 의미합니까? 왜냐하면 fo가 생성 될 때 Saxon의 작업이 완료되는지 또는 PDF 처리에 FO에 참여하게되는지 확실하지 않기 때문입니다. 또한 Saxon은 FO에서 pdf를 생성하는 기능을 가지고 있습니까? 감사합니다 –

+0

그 측정 값이 맞다면 Saxon이 아닌 Apache FOP에 문제가 있습니다 (미안하지만 더 이상 당신을 도울 수 없습니다). Saxon은 XSL-FO에서 PDF 로의 변환에 관여하지 않습니다. –

+0

감사합니다. 각 단계마다 소요 된 시간을 측정했으며 PDF 처리를위한 XSL-fo가 대부분의 시간을 소비 했으므로이 문제는 apache fop 쪽에서 발생합니다. –