一步一步理解 Java 企業級應用的可擴充套件性
摘要:本文主要介紹如何理解 Java 應用的擴充套件方式以及不同型別的擴充套件技術和具體技巧,介紹一些有關 Java 企業級應用的一般擴充套件策略。
老實說,“可擴充套件性”是個全面且詳盡的話題,而且往往得不到充分理解。人們通常認為可擴充套件性等同於高可用性,筆者見過程式設計新手和架構師“老手”都建議將叢集作為可擴充套件性和高可用性的解決方案。建議確實沒錯,但問題是,人們通常是通過網際網路搜尋,而非實際理解應用本身的情況來實現叢集。
筆者並未自稱“專家”,只想通過這篇文章介紹一些有關 Java 企業級應用的一般擴充套件策略。
問題
可擴充套件性並非 Java 企業級平臺規範內的標準元件。相關技術通常因供應商(應用伺服器)而異,並且往往需要使用不止一款產品(應用伺服器本身除外)。正因如此,設計可擴充套件的 Java 企業級應用才會有些棘手,要完成任務,往往不僅沒有可以參照的例項,而且要求我們必須徹徹底底地理解應用。
擴充套件型別
筆者確信你們不是第一次看到這些內容。擴充套件一般分為兩大類:縱向擴充套件,和橫向擴充套件。
擴充套件的第一個自然階段是縱向擴充套件。
縱向擴充套件:包括給伺服器增加更多資源,例如記憶體 (RAM)、磁碟空間、處理器等。這在某些方案中具備實用價值,但經過特定時間點後就會發現,這種擴充套件費用高昂,不如藉助橫向擴充套件。
橫向擴充套件:在這個過程中會增加更多機器或額外的伺服器例項/節點,這也叫做叢集(Clustering),因為所有伺服器是作為一個集體或叢集一起執行的。
高可用性不等於可擴充套件性
系統高度可用(擁有多個伺服器節點以方便故障轉移),並不表示系統可擴充套件。高可用性只是意味著,如果當前處理節點崩潰,請求會傳遞或轉移到叢集中的另一個節點,以便從開始處繼續。可擴充套件性則是通過增加可用資源(記憶體、處理器等)而提升系統特定效能(例如使用者數量、吞吐量、響應時間)的能力,即使將失敗請求傳遞到另一個節點,也無法保證應用會在這種場景中正確執行(原因我們會在下面揭曉)。
下面我們來了解一些關於可擴充套件性的觀點和相關討論。
讓橫向擴充套件的叢集達到負載均衡
假設您已經縱向擴充套件至最大容量,現在又用多個節點形成叢集,將系統進行了橫向擴充套件。接下來您要做的可能是在叢集基礎架構前放置一臺負載均衡器,讓負載分散在叢集各部分之間(如果要詳細瞭解負載均衡,大家可以參考其他方面的資料,在這裡我們重點還是說擴充套件問題)。
應用有狀態還是無狀態?
現在你已經橫向擴充套件了,這就夠了嗎?如果你的應用無狀態,即應用邏輯在處理請求時不依靠現有伺服器狀態,則橫向擴充套件已經足夠。
但如果應用具有 HTTP 會話物件、有狀態 EJB、會話域 bean (CDI、JSF) 等元件時,又會怎樣?這取決於具體客戶(具體來說,即呼叫執行緒),儲存特定狀態並依靠當前顯示的狀態來執行請求(例如,HTTP 會話物件可能會儲存使用者的身份驗證狀態、購物車資訊等)。
在橫向擴充套件或叢集式應用中,節點的任何叢集都可能為後續請求提供服務。如果首個請求的 JVM 例項處的狀態資料沒有被接收,其他節點會如何處理請求?
會話保持
會話保持配置可在負載均衡器層面上完成,確保來自特定客戶/終端使用者的請求始終被轉發到同一個例項/應用伺服器節點,即維持伺服器親和力。這樣,我們就緩解了所需狀態無法顯示的問題。但這裡有個陷阱 – 如果節點崩潰怎麼辦?狀態會被破壞,使用者會被轉至伺服器請求處理所依賴的、但不具備現有狀態的例項。
叢集複製
為解決上述問題,您可對應用伺服器叢集機制進行配置,以支援有狀態元件的複製,藉此可確保 HTTP 會話資料(和其他有狀態物件)顯示在所有伺服器例項上。如此一來,終端使用者請求便可轉至任何伺服器節點,即使某個伺服器例項崩潰或不可用,叢集中的其他任何節點都能夠處理請求。現在您的叢集就不是一般叢集了,而是複製叢集。
叢集複製特定於 Java 企業級容器/應用伺服器,最好查閱相關文件,瞭解如何複製叢集。一般而言,大多數應用服務都支援 Java 企業級元件(如有狀態和無狀態的 EJB、HTTP 會話、JMS 佇列等)叢集。
然而這造成了另一個問題 – 應用伺服器中的每一個節點都處理會話資料,導致 JVM 堆記憶體越來越多,因此垃圾回收也越來越頻繁,另外,複製叢集時還會消耗一定的處理能力。
有狀態元件的外部儲存
在另一層儲存會話資料和有狀態的物件,這可以藉助 RDBMS 實現,大多數應用伺服器本身就支援這一功能。
你可能已經注意到了,我們已經將儲存從記憶體層轉移到持久層 - 一天工作結束時,你可能會遇到由資料庫導致的擴充套件問題。不是說這一定會發生,但資料庫確實可能因為應用而過載,而後逐漸延時(例如在故障轉移時)。設想一下,從資料庫中再現整個使用者會話狀態以便用在另一個叢集例項中,不僅耗費大量時間,還會影響峰值負載下的終端使用者體驗。
最後的邊界:分散式記憶體中快取
這是最後的邊界,至少在我看來如此,因為它把我們帶回了記憶體方法。沒有比這更好的辦法了!Oracle Coherence、Hazelcast 這類產品或其他任何分散式快取/記憶體網格產品可用於清理有狀態的狀態儲存和複製/分佈 - 這就是快取層。好的一面是這些產品大多預設支援 HTTP 會話儲存。
這種結構設定意味著,應用伺服器的重啟不會影響現有使用者會話 - 給系統打補丁而不造成當機和終端使用者斷電(雖然並不像聽上去那麼容易,但顯然是個辦法!),這始終是好事。總的來說,其理念是:應用層和 web 會話快取層可獨立執行和擴充套件,彼此不受干擾。
分散式不等於重複式
這兩個詞之間存在巨大差異,就快取層而言,理解其中的差異是極為關鍵的。兩者各有長短:
分散式:快取共享資料的各個部分,即資料集被分在各快取叢集節點之間(利用與產品特定的演算法)。
重複式:所有快取節點都擁有所有資料,即每個快取伺服器都包含整個資料集的一份複本。
延伸閱讀(主要關於 Weblogic)
- 聚類配置
- 用於會話永續性的 RDBMS 配置
- 分散式 Web 會話複製 – Oracle Coherence, Hazelcast
- 高可擴充套件性 – 非常好的資源!
結束語
高度可擴充套件性可能不是所有 Java 企業級應用的必要條件。但如果你打算構建網際網路/面向大眾的應用,將高可擴充套件性納入設計因素顯然非常實用。
對於希望充分利用自動靈活性(經濟可行!)和高可用性等雲平臺(主要是PaaS)特點的應用而言,可擴充套件的設計是必要的。
不難發現,有狀態的應用通常更難以擴充套件。完全「無狀態」或許無法實現,但我們應當朝這方面努力。
你用哪些技巧和方法來擴充套件 Java 企業級應用,快來和大家分享吧。
(編譯自:https://dzone.com/articles/the-basics-of-scaling-java-ee-applications)
OneAPM 為您提供端到端的 Java 應用效能解決方案,我們支援所有常見的 Java 框架及應用伺服器,助您快速發現系統瓶頸,定位異常根本原因。分鐘級部署,即刻體驗,Java 監控從來沒有如此簡單。想閱讀更多技術文章,請訪問 OneAPM 官方技術部落格。
本文轉自 OneAPM 官方部落格
相關文章
- 可擴充套件性套件
- 基於 Kyma 的企業級雲原生應用的擴充套件案例分享套件
- API閘道器,企業級閘道器可擴充套件API套件
- ETL的可擴充套件性和可維護性套件
- 構建可擴充套件的應用(一) (轉)套件
- 可擴充套件性筆記一套件筆記
- 一步步入門編寫PHP擴充套件PHP套件
- c# 高階應用 理解擴充套件方法C#套件
- 如何構建可控,可靠,可擴充套件的 PWA 應用套件
- 一步步來用C語言來寫python擴充套件C語言Python套件
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- 實用的可選項(Optional)擴充套件套件
- 教你 4 步搭建彈性可擴充套件的 WebAPI套件WebAPI
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- SDN在5G和WAN中的應用,它是否具備可擴充套件性套件
- VSCode擴充套件應用VSCode套件
- easyui應用(四)--- easyui擴充套件UI套件
- 並查集擴充套件應用並查集套件
- 服務的擴充套件性套件
- Java併發程式設計:效能、擴充套件性和響應Java程式設計套件
- 可擴充套件的搜尋元件套件元件
- 五、談擴充套件方法的理解套件
- Django與微服務架構:構建可擴充套件的Web應用Django微服務架構套件Web
- 企業級Flutter專案-走出第一步Flutter
- 凱捷:擴充套件製造業AI應用報告套件AI
- ?用Chrome擴充套件管理器, 管理你的擴充套件Chrome套件
- XBRL(可擴充套件商業報告語言套件
- [譯]擴充套件 Node.js 應用套件Node.js
- 27. 企業級開發基礎8:物件導向擴充套件物件套件
- 編寫可擴充套件程式套件
- bash的特有擴充套件屬性套件
- 聊聊如何讓你的業務程式碼具有可擴充套件性套件
- 軟體可擴充套件性:來自星巴克的經驗套件
- Apache Cassandra——可擴充套件微服務應用程式的持久資料儲存Apache套件微服務
- plain framework的實際應用和擴充套件AIFramework套件
- 一步一步理解命令模式模式
- Kotlin擴充套件函式與屬性原理解析Kotlin套件函式
- Swift 擴充套件 Storyboard 屬性Swift套件