2015-10-26 59 views
1

我有一個在Jetty下運行良好的spring引導java servlet,但在Tomcat下運行時性能問題,這是我們的目標部署環境。Spring引導servlet在Tomcat中顯示性能問題,但不顯示Jetty

  1. JAXB unmarshal是瓶頸,因爲ServiceLoader花費大量時間查找要使用哪個TransformerFactory實現。 (YourKit profiling showing the look up for the TransformerFactory implementation
  2. 撒克遜是變換實現和罐子被包含到Tomcat/webapps /下的myapp/WEB-INF/lib和具有正確的META-INF/services文件
  3. 使用碼頭當這個問題是不存在servlet容器
  4. 我已確認下兩Jetty和Tomcat的運行我得到一個TransformerFactory正確執行從正確的罐子
  5. 明確添加映射到Tomcat JAVA_OPTS選項解決了這個問題:

    -Djavax .xml.transform.TransformerFactory = net.sf.saxon.Transfo rmerFactoryImpl

編輯:在碼頭 我們的XML讀取/轉換時間約在Tomcat下5秒與20秒,它是直接由於類加載器搜索我們的TransformerFactory。

我能夠通過在servlet配置中顯式指定TransformerFactory來解決問題,但我的問題仍然存在: 爲什麼Tomcat需要此顯式setProperty並且Jetty容器不?

public class Application extends SpringBootServletInitializer { 
    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
    System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl"); 

    return application.sources(Application.class); 
} 

很抱歉,如果這是一個基本的問題,我是一個老C++狗學習Java和Web應用程序/ servlet的技巧。

+0

對於4的一個問題:「運行可執行文件.jar或.war文件時」是指那些文件使用嵌入式碼頭而不是嵌入式tomcat? –

+0

當我做了測試時,他們使用的是嵌入式Tomcat。碼頭在我的所有測試中一直都是外部的。 – dleb

+0

我也讀過關於Jetty和Tomcat的類加載器的文檔。從這些,我不會指望有任何區別,因爲兩個容器必須遵守標準中的servlet容器設置的類加載器規則。 – dleb

回答

0

如果未設置標識工廠的JAXP系統屬性,那麼JAXP會在類路徑中搜索JAR文件,其中包含有關JAR文件清單的services文件中變壓器工廠的信息。在類路徑中有很多JAR的情況下,該搜索可能非常昂貴,並且最好避免它。您看到的性能差異的最可能的解釋是您的Tomcat配置比Jetty配置有更多的JAR文件要搜索。

到目前爲止實例撒克遜是直接做,避免了JAXP機制完全以最快的方式:

TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl() 

這也更可靠;如果您的應用程序使用Saxon進行了測試,並且您不相信它使用位於類路徑中的舊XSLT 1.0處理器運行,那麼您還可以將Saxon硬編碼用於應用程序源代碼。如果您希望應用程序能夠使用不同的JAXP XSLT實現運行,並且在運行時進行選擇,那麼JAXP機制的唯一優勢就是它。

+0

謝謝邁克爾。我認爲這支持我對System.setProperty進行硬編碼的解決方案,以定義我們正在使用的實現。您提供的代碼片段是否真的爲整個應用程序設置了TransformerFactory?我在問,因爲我們不直接控制TransformerFactory的創建時間/位置。基本上我想知道如果我應該用我的配置方法 – dleb

+0

中的代碼片段替換我的系統調用否,提供的代碼將替換「TransformerFactory factory = TransformerFactory.newInstance()'的任何內容,並假定您有權訪問在那裏完成的應用程序。如果您不能以這種方式更改代碼,那麼使用系統屬性是您的最佳選擇,但缺點是它適用於整個應用程序,並且可能會更改僅由部分應用程序使用的XSLT引擎默認的JDK引擎,當使用不同的JDK引擎時會中斷。 –