2 回答

TA貢獻1911條經(jīng)驗 獲得超7個贊
35 毫秒聽起來像是涉及磁盤訪問時間,這表明操作系統(tǒng)緩存存在問題。
類路徑上是否有任何目錄/非 jar 條目可能會減慢速度。此外,如果資源不存在于檢查的第一個位置。
ClassLoader.getResource
如果您可以通過配置(我已經(jīng)多年沒有接觸 tomcat)或只是設(shè)置線程上下文類加載器,則可以覆蓋Thread.setContextClassLoader
。

TA貢獻1852條經(jīng)驗 獲得超7個贊
我可以再花 30 分鐘來調(diào)試這個問題,并研究 Tomcat 如何進行資源緩存。
我特別CachedResource.validateResources感興趣(可以在上面的火焰圖中找到)。true如果CachedResource仍然有效則返回:
protected boolean validateResources(boolean useClassLoaderResources) {
? ? ? ? long now = System.currentTimeMillis();
? ? ? ? if (this.webResources == null) {
? ? ? ? ? ? ...
? ? ? ? }
? ? ? ? // TTL check here!!
? ? ? ? if (now < this.nextCheck) {
? ? ? ? ? ? return true;
? ? ? ? } else if (this.root.isPackedWarFile()) {
? ? ? ? ? ? this.nextCheck = this.ttl + now;
? ? ? ? ? ? return true;
? ? ? ? } else {
? ? ? ? ? ? return false;
? ? ? ? }
? ? }
看起來CachedResource實際上有一個生存時間 (ttl)。實際上Tomcat中有一種方法可以配置cacheTtl?,但你只能增加這個值。資源緩存配置看起來并不那么靈活。
所以我的Tomcat配置了默認值5000毫秒。這在進行性能測試時欺騙了我,因為我的請求之間有 5 秒多一點的時間(查看圖表和其他內(nèi)容)。這就是為什么我的所有請求基本上都在沒有緩存的情況下運行,并且ZipFile.open
每次都會觸發(fā)如此繁重的操作。
因此,由于我對 Tomcat 配置并不是很有經(jīng)驗,所以我還不確定什么是正確的解決方案。增加cacheTTL可以使緩存更長,但從長遠來看并不能解決問題。
概括
我認為這里實際上有兩個罪魁禍首。
FactoryFinder 類不重用 ServiceLoader。他們不重復使用它們可能是有正當理由的——但我實在想不出一個原因。
Tomcat 在固定時間后驅(qū)逐 Web 應用程序資源的緩存(類路徑中的文件 - 就像
ServiceLoader
配置)
再加上沒有為 ServiceLoader 類定義系統(tǒng)屬性,您每秒都會收到一次緩慢的 FactoryFinder 調(diào)用cacheTtl
。
現(xiàn)在我可以忍受將cacheTtl 增加到更長的時間。我也可能會看看 Tom Hawtins 的重寫建議,Classloader.getResources
即使我認為這是擺脫性能瓶頸的一種嚴厲方式。不過,這可能值得一看。
添加回答
舉報