2010-05-03 59 views
21

我有這樣的朋友....如何最好地實現2002年代的J2EE應用程序的現代化?

我有這樣的朋友,誰在Java EE應用程序的工作原理(J2EE)應用始於2000年代初期。目前他們在這裏和那裏添加一個功能,但有一個很大的代碼庫。多年來,該團隊縮小了70%。

[是的,「我有這個朋友是」。這就是我,試圖幽默注入十幾歲的高中輔導員恥辱混進去]

的Java,復古2002

應用程序使用EJB 2.1,支柱1.x中,DAO的等直JDBC調用(混合物存儲過程和準備好的語句)。沒有ORM。爲了緩存,他們使用OpenSymphony OSCache和本地緩存層的混合。

在過去的幾年中,他們花費精力使用ajax技術和庫來實現UI的現代化。這主要涉及JavaScript庫文件 (jquery,yui等)。

客戶端

在客戶端,缺乏從struts1的Struts2的升級路徑遷移到Struts2的勸阻他們。其他網頁框架開始流行(wicket,spring,jsf)。 Struts2並不是「明確的贏家」。將所有現有的用戶界面從Struts1遷移到Struts2/wicket /等似乎並沒有以非常高的成本提供很多邊際收益。他們不希望有技術篤怨婦(在Struts2子系統X,子系統的Y檢票等),使開發者使用Struts 1

服務器端

上書寫新的功能拼湊在服務器方面,他們考慮轉向ejb 3,但從來沒有很大的動力。開發人員都對ejb-jar.xml,EJBHome和EJBRemote感到滿意,即「ejb 2.1原樣」代表了阻力最小的路徑。

關於ejb環境的一個大投訴是:程序員仍然假裝「ejb服務器運行在與servlet引擎不同的jvm上」。沒有應用程序服務器(jboss/weblogic)曾經實施過這種分離。該團隊從未在單獨的應用服務器上部署ejb服務器。

ear文件包含同一個jar文件的多個副本;一個用於'web層'(foo.war/WEB-INF/lib),另一個用於服務器端(foo.ear /)。應用服務器只加載一個罐子。重複造成歧義。

緩存

至於緩存,他們使用多種緩存實現:OpenSymphony的緩存和自主開發的高速緩存。 Jgroups提供集羣支持

現在是什麼?

問題: 該團隊目前有空餘的時間來投資更新應用程序?聰明的投資者在哪裏花費他們?主要標準爲:

1)生產力提高。具體縮短開發新子系統功能和減少維護的時間。 2)性能/可擴展性。

他們不關心時尚或techno-du-jour street cred。

你們都推薦什麼?

在持久性方面 將所有內容(或僅限新開發)切換到JPA/JPA2?
直接休眠? 等待Java EE 6?

在客戶端/網絡框架端: 移植(一些或全部)到struts2? 檢票口? jsf/jsf2?

至於緩存: 兵馬俑? ehcache? 一致性? 堅持他們有什麼? 如何最好地利用64位jvms提供的巨大堆大小?

在此先感謝。

回答

7

這真的很難自圓其說重新設計的東西,「作品」原樣。你花費大量的工作回到你開始的地方。

這就是說。

從EJB 2.1 Session Beans到EJB 3的轉換非常簡單。對我們來說,當我們進行轉換時,大多數EJB都是單獨部署的,而不是組合的EAR。但是你沒有這個問題。即使使用EJB 3,您可能仍然有一個ejb-jar.xml文件(或多個文件)。

但是,我認爲還是有好處的,而且成本非常低。你可以逐步地做到這一點,一豆一豆vs「一次全部」,這很好,只需將當前ejb-jar.xml文件中的大部分信息移動到應用程序中的註釋中即可。如果沒有其他的東西,它會將可見性(如事務需求等)帶入代碼中,而不是隱藏在ejb-jar.xml文件中。

沒有理由將「應用層」部署到單獨的jvm /服務器上。 Web層是否調用遠程會話Bean? vs Local?通過切換到本地調用,您可能會也可能不會看到加速(如果配置正確,許多「共址」部署可以類似於某些服務器上的本地調用,不知道是否已經這樣做)。

切換到本地的最大風險是,通過遠程調用,您的參數「安全」不會被更改,因爲它們是通過網絡進行序列化的。使用本地語義,如果您有意或無意地更改參數的值(即,更改bean中某個屬性的值),該更改將反映在調用者中。這可能也可能不是問題。如果他們已經使用本地調用語義,即使對於「遠程」bean,他們也已經遇到了這個問題。

至於JPA vs SQL,我會保持原樣。如果你真的想要JPA運行時(vs開發時間)的好處,尤其是高速緩存等,那麼你就必須將整個數據層(或者至少是大的所有的相關部分都是一次性的)。真的有風險並且容易出錯。

對於「重複瓶子」問題,這是打包和構建的工件,而不是部署。爲了解決歧義問題,您需要在開發環境中使用共享的jar庫,並認識到如果將j​​ar升級爲一個jar文件,您將會升級它。人們譴責這是一個不合理的需求,如果jar發生了變化,就會迫使整個應用程序升級。對於巨大的,不同的應用程序,當然。但對於單個JVM中的應用程序,不,事實並非如此。儘管我們希望每一點點都可以成爲一個孤立的世界,我們稱之爲Java類加載器環境,但事實並非如此。我們越能保持簡化,在複雜性和維護方面就越好。對於常見的罐子,您可能會考慮將這些罐子捆綁到應用程序服務器並從應用程序中取出。我不喜歡那種方法,但是如果你能使它爲你工作,它就有了用處。它肯定會減少部署大小。客戶端方面,從Struts 1轉換到Struts 2並不難,因爲它們在高層次上都非常相似(值得注意的是,它們都是動作框架)。這裏的關鍵在於兩個框架可以彼此並肩生活,同樣允許增量更改。您可以慢慢遷移舊代碼,也可以單獨在新框架中實現新代碼。這與嘗試混合和匹配動作框架和組件框架不同。這實際上是一種「狗和貓,一起生活」的情況。如果我要走這條路線,我只是簡單地將組件放在自己的WAR中,然後繼續前進。組件框架的狀態管理使得後端與它們互操作真的很麻煩。如果您選擇通過新的WAR實施,請確保您花一點時間做某種「單一登錄」,以便人們可以根據需要「登錄」每個模塊。只要這些應用程序不共享任何會話狀態,這就是集成真正需要去的地方。一旦你選擇通過新的WAR添加一個新的子系統,你可以使用任何你想要的技術爲客戶端。

緩存是一個不同的問題。不同的緩存解決了不同的問題。緩存和記憶系統內的一些小內容(如JSP渲染)或使用分佈式緩存在故障轉移或負載平衡期間跨實例傳輸會話是一回事。擁有一個基於緩存的領域層是另一回事,其中持久性和緩存集成得非常緊密。這要複雜得多。只要把它全部放在你的頭上是痛苦的。

前者在遇到需求時幾乎可以散佈在應用程序中,而且這些類型的緩存幾乎可以獨立存在,而不是協調的全局緩存框架的一部分。

後者是不同的。在那裏你需要重做你的整個數據模型,甚至是你根本沒有緩存的部分,因爲你要確保你有一致的訪問數據和緩存視圖。

這實際上是JPA所做的,它具有兩個級別的緩存,以及爲什麼我之前提到過,它不是隨便插入應用程序的,除了大多數獨立的系統塊以外。當不同的模塊觸及相同的後端資源時,緩存的一致性和一致性成爲一個真正的問題,這就是爲什麼你需要在兩個系統上集成這些模塊的原因。

注意,它可以做到。訣竅是簡單地集成數據訪問級別,然後您可以在該級別開始緩存。但是如果你有人直接進行SQL調用,那就必須去做。

最後,我認爲使用的術語是進化而不是革命。遷移到EJB 3或3.1我不認爲必須很痛苦,因爲它幾乎適用於EJB 2.1,這是一個福音。你可以有一個「混合」的環境。如果你使用實體bean,那麼最痛苦的整合就是如此,但你沒有,所以這很好。對於所有EJB反對者來說,這種跨越的向後兼容性,幾乎10年的EJB,使您能夠實際保留大量代碼,但仍然繼續前進。

+0

感謝您的有益迴應。你和「進入春天」的職位相互補充,並解決我們關注的問題。 至於'遠程'與'本地'我有點不清楚。在實踐中,所有的電話都是本地的 - 因爲Jboss在本地處理與同一個vm中的ejb電話。我沒有預見過將ejb作爲Web層放在單獨的虛擬機上。 我們將看看我們的'重複jar'問題和部署。 AFAIK和IIRC之前的版本在.war罐子和罐子罐子上是模糊的(Jboss有它的'flatclassloader'模型,它把耳朵/戰爭中的每個罐子視爲平等,但那是另一個主題) – user331465 2010-05-05 15:36:49

+0

也是,Glassfish也有「每個EAR一個類加載器「模型,」每WAR一個「模型是一個選項。當我嘗試在同一個EAR中捆綁兩個WAR時,這是一個真正的問題。 EJB規範沒有以某種方式定義行爲,因此兩種模型都是「兼容」的,但我認爲這是一個漏洞,因爲在兩種不同環境下構建的應用程序並不是真正可互換的,即使兩者都被編碼爲「規格」。 – 2010-05-05 17:13:55

+0

+1,因爲此答案此時只收到1個其他的upvote。 – 2010-09-23 17:00:42

0

如果我是你,我會從測量開始。也許需要進行一些典型的操作,最好是那些在高負載或者某些情況下令人討厭的用戶,將他們的路徑切入某些階段並測量每個步驟消耗的時間。一旦找到需要花費很長時間的步驟,您可以縮小範圍,直至找到可能的罪魁禍首。如果是數據庫訪問,緩存可能會有所幫助等等。您可能會發現一些簡單的舊優化,但也沒關係,對吧?

如果您使用的是舊版本的應用程序。服務器,那麼我建議升級它。它通常具有更好的性能/可伸縮性,而對於JBoss,由於更好的支持(可以更容易地找到信息/人力資源),它變得更加合理。

至於EJB2.1到EJB3的遷移,我測試了EJB3依賴注入與EJB2.1 JNDI查找,而且速度更快。也許擺脫EJBHome的東西讓事情變得更快,儘管我並不確定。一旦完全遷移到EJB3,您將擁有JPA,並且很容易讓ehcache工作,並且我可以告訴您ehcache非常高效。 (當然我不知道如何比較你現在正在使用的一個..)

0

我理解你的朋友的痛苦:)

但是更新,更亮的框架並不一定使你的最終用戶的生活更美好畢竟那是你的報酬。一些問題已經存在了一段時間,緩存數據以加快速度,爲方法調用提供自動佈線請求參數,管理事務,將相關組件捆綁在一起......多年來人們開發了'足夠好的'實現。

我的感覺是,如果框架開關帶來很多改進,它只值得花錢。例如,如果切換到其他的東西可以AJAX化你的應用程序,那麼它可能是值得的。但是你必須讓最終用戶感受到改進。

我的建議是開始將您的業務模型與其他任何事物(DAO,UI,事務管理...)解耦,然後引入新的框架(ORM?)會更容易。即使它最終不起作用,你可能會通過解耦來提高代碼庫的質量。

0

說實話,你很可能只是重做Grails的整個事情,不喜歡它20倍比過了多長時間做,在2002年快;)

對於我絕對要使用一個真正的Java堆棧項目因爲,我堅持使用Spring 3.0和 Hibernate 3.5。您甚至可以使用Roo快速啓動項目,如果您不再需要它,請關閉它。使用IntelliJ這樣的想法來快速編碼。

不幸的是,我得說這不是生產力了。雖然對於原始Java非常棒......原始Java只是非常吸引人,除非你絕對需要Java提供的一切。

另外,Ajax對Spring來說真的很糟糕。如果你想在你的MVC中使用數據庫映射,你必須對定製的Jackson反序列化器進行編碼...所以你必須解析原始的JSON。這太可怕了,春天的人們已經意識到了這個問題。祝你好運,很快看到高級修復。

我曾經嘲笑Ruby on Rails的人......但我得把它交給他們,他們說得對。對於中小型項目來說,它確實有效。如果你想要Java堆棧的可擴展性,Grails是一個很好的解決方案。如果你確實真的不想朝那個方向發展,那麼只需使用帶有Hibernate 3.5的現代化Spring 3.0就行了。

+0

我研究過Grails(通過其中的一本書),發現它非常令人印象深刻:它看起來是新應用程序的理想選擇,但與現有應用程序的集成看起來更加困難。 你能否澄清一下「阿賈克斯與春天不好」?即Spring-in-general或Spring的特定組件/方面。我不熟悉Spring的細節,也不熟悉json的問題。 謝謝 – user331465 2010-05-05 15:42:59

3

幾年前,我在一個非常相似的位置上,擁有一個由EJB 1.x和本地MVC框架組成的複雜的單一應用程序。一次性遷移整件事絕不是一種選擇,我需要一次一個一個的做法,沒有破壞任何東西,也不需要批准一個大型預算項目。

讓我這樣做的工具是Spring(當時是v1.2)。當您從Spring中刪除所有流行語時,您留下的是一個用於集成不同應用程序組件的簡單框架,使您可以更輕鬆地將這些組件交換出來,隨時隨地更新。

例如,Spring爲您提供integration with Struts 1,使您更容易將Struts 1組件引入到「Spring方式」中。你的Struts應用程序應該像以前一樣運行,但是現在他們已經具備了從下到上的現代化的槓桿作用。接下來,Spring的數據訪問抽象將允許您插入現有的JDBC DAO,並開始引入DA抽象以使它們更易於現代化。如果你選擇堅持使用JDBC,那很好,Spring提供了extensive JDBC support以使它感覺不到石器時代。如果你想鼓搗JPA或Hibernate,那麼這些將與JDBC一樣容易地與Spring管理的應用程序集成。

對於EJB來說,Spring可以將wrap the EJB access layer變成史前的東西,使它們更容易被吞下。一旦您將客戶端層與EJB數據訪問的具體細節隔離開來,如果您願意,可以使用更簡單的Spring管理組件(使用任何遠程處理,事務,安全性或無)來替換EJB(一次一個) ),或者如果您願意,您可以保留EJB(也許使用EJB3)。總之,讓Spring接管應用程序「主幹」的角色,同時開始使用已有的相同遺留組件。然後,您按照您指定的速度和風險實現現代化的更多自由。

這不是一件容易的事情,但有一定的耐心和毅力,你可以到達想要去的地方而不會造成太多的干擾。

+0

感謝您的回覆。 「逐漸過渡到春天」提供了一些有用的見解。作爲非Spring用戶,我忘記了Spring提供的不僅僅是一個'web框架'。 我是新來的stackoverflow,不知道爲什麼我不能爲一個問題指定多個答案,但它是你和其他答案之間的投票。感謝您的稱重。 – user331465 2010-05-05 15:22:57

1

好的,這裏不是要求用不同語言重寫或學習彈簧和編寫2000行XML的答案。建議你的朋友嘗試在glassfish v3中部署應用程序,EJB 2.1將可以工作(並且可以和任何新的EE 6代碼搭配使用)。未來,他們現在可以在EJB 3.1中開發新代碼,並且可以在閒暇時重構舊的EJB 2.1代碼。

他們可以繼續使用Struts或將新代碼緩慢遷移到JSF/Wicket/???

JPA同樣如此,儘管他們的領域模型可能需要在一個大爆炸或許多較小的爆炸中發生,但他們可以按照自己的步調移動到JPA 2。

緩存? EclipseLink(JPA 2 RI)在板上有一些相當不錯的緩存。 Read more

大多數這個布丁都有證據。我在工作中剛剛在glassfish v3中部署了一個遺留的EJB 3 + Struts 1.3應用程序,它不僅非常簡單(它花費的精力是將它從jdeveloper項目中移出並投入到netbeans項目中),但它的基礎很好開始重構到EE 6,我們打算這樣做,因爲要求錯誤或功能。

基本上,這歸結爲「如果它沒有損壞不修復它。」爲什麼改變工作(儘管很舊)的代碼?讓它活下去,在EE 6中編寫新的功能,並且如果某個功能涉及舊代碼,請考慮將它重構爲EE 6。

最重要的是,參與這一努力,將部署到GlassFish的第三版......

相關問題