2016-09-28 189 views
0

我目前正在將EJB項目從版本2.0升級到版本3.2(全部有狀態)。業務邏輯保持不變,唯一改變的是EJB部分(用註釋替代描述符文件,使用注入點而不是傳統查找等)。 從請求處理的角度來看,一切似乎都正常,問題出在性能上。 使用一個連接的客戶端,每個請求需要大約300毫秒。如果我添加第二個客戶端,平均時間跳至700毫秒。第三個客戶的平均時間超過1秒,依此類推。使用EJB 2.0版本,即使有更多的客戶端,處理時間也會略微增加(50〜100ms),但無需擔心。EJB 3.2性能下降

退化很明顯,我只是無法弄清原因。

我玩過EJB超時,事務類型等,但沒有運氣。我也嘗試了分析服務器(通過JMC),但找不到任何可疑的東西。

這就好像所有的請求都是按順序處理而不是同時處理的。

有人可以提供一些可能的原因提示?有沒有我錯過的配置?

注意:這個問題同時出現在WebSphere 9和GlassFish 4.1.1上,所以這顯然是一個應用程序的問題。

編輯#1

檢查應用程序的日誌後,我可以證實,請求被處理順序,沒有併發。

繼邁克爾的建議,我看着一個線程轉儲,並在給定時刻,有:

  • 27 RUNNABLE
  • 18 TIMED_WAITING
  • 6 TIMED_WAITING(對象監視器)(停車場)
  • 16 TIMED_WAITING(睡覺)
  • 23 WAITING(對象監視器上)
  • 40 WAITING(停車場)

沒有阻塞線程的跡象。

有什麼想法?

+0

嘗試負載測試期間獲得線程轉儲5+用戶。我想有共享資源需要獨佔鎖。 –

+0

@邁克爾,我沒有太多分析線程轉儲的經驗。我究竟應該尋找什麼? –

+0

簡單的方法採取線程轉儲:jstack >> myapp.log。當你需要通過「鎖定」來搜索/ grep時。可能有很多垃圾。如果可以的話,值得通過pastebin發佈。 –

回答

1

您如何測試?

這聽起來像多個客戶端獲得相同的有狀態會話bean實例。

容器將串行調用相同的SFSB實例。它應該這樣做,如果它之前沒有發生過,那麼也許你有一些依賴於平臺的部署描述符來禁用這種行爲。

但是,如果您正在使用測試框架並且所有客戶端都獲得了相同的會話,那麼這也會使您看起來像有問題。

§4.3。EJB規範的13「序列化會話Bean方法」說:

容器將對每個有狀態和無狀態會話的調用序列化爲 bean實例。大多數容器將支持許多同時執行的會話bean的實例;但是,每個實例只能看到 方法調用的序列化序列。因此,有狀態或無狀態會話bean不必被編碼爲可重入。

如果您在所有客戶端之間共享一個SFSB實例,則可以將其從@Stateful更改爲@Singleton。 Singleton EJB通過@ConcurrencyManagement@Lock註釋給出明確的重入控制。如果你完全滿意你的EJB的線程安全的,那麼你可以用你的標記豆起來脫身:

@Singleton 
@ConcurrencyManagement(ConcurrencyManagementType.BEAN) 
public class MyStatefulSessionBeanMasqueradingAsASingleton { 
    ... 
} 
+0

我正在使用一個模擬器,它配置了幾個終端(客戶端)並連接到我的應用程序,密切模擬生產環境中發生的情況。這兩個版本(EJB 2和3)都使用SFSB,唯一的區別是版本2使用的是基本的緩存系統,這不符合順序處理(IMO)的要求。 –

+0

您有一個或多個所有客戶端都可訪問的SFSB? –

+0

是的,所有請求都由同一個SFSB處理。 –