Java Web項目如何做到升級不斷掉服務,同時涉及到的相關問題
原文地址:https://m.oschina.net/question/737237_2203576
現在容器用的是tomcat,做維護比較多,因為程序老是要升級,更新了class文件,必須要重啟環境,這樣的話用戶體驗就非常差,而且耽誤時間,實際開發中我用了jrebel插件倒是沒什么問題,但是生產環境好像都不推薦這個東西,想問下大型的項目是如何做到的呢?
一般是這樣,首先,網站架設成,負載均衡器+應用服務器+Session服務器的模式。Session服務器常見的用redis、memcache都有。更新的時候,先把一部分(比如1/3)應用服務器下線,更新應用,再重新上線。之后再逐步更新剩下的部分。一次更新1/3的話就分三次上線完成。
可以使用nginx做一台backup服務器,先更新backup服務器,測試完成以后,更新其他非backup服務器。
那現在2/3的服務器上是新代碼,1/3的服務器上是老代碼。 訪問這兩組的用戶看到的功能是不是不一樣?這個怎么解決呢?
tomcat、glassfish、jboss等都是支持熱部署的,修改一個類是不用自己手動重啟web服務器的,只有修改外部jar包中的類則必須重啟,不然jar包會沖突,不會替換,當然這種熱部署是重新加載web容器,性能不佳。生產環境是不建議開啟熱部署的。
你可以在網上搜索一下java服務器代碼class類熱更新,有一大堆資料,當然你也可以用groovy、jruby、scale這些本身運行於jvm而且可熱更新的腳本語言,甚至jdk自帶一套解析運行js腳本的引擎,還有一種方案就是用業務規則引擎,比如Drools,不過這個也要學習另外一種腳本。
大且穩健和高並發的項目往往不是單一的語言能做好的,需要多方面的結合,java組件框架這么多,就需要優秀的架構師去利用整合了。我們並不一定能生成開發出多么優秀的東西,但應該合理利用其它優秀的東西。
影響有多大,你一台Tomcat,估計用戶也不會多到哪里去吧,凌晨進行。幾秒種而已
1、session可以掛Redis或者Memcached.應用服前面掛nginx或者haproxy做負載均衡。或者只做反向代理也行,nginx和haproxy基本是秒起的,不過不建議這么做。
2、tomcat是可以開啟熱加載的,不過一般不建議開啟,熱加載易導致PermGen space溢出。
3、jdk7以后開始可以做classloader的卸載,jdk8以后從permgen替換到了metaspace,理論上可以避免permgen的溢出問題,有興趣可以試試自己寫一個應用服務器實踐一下。
1:舊數據兼容新功能問題。
升級后,比如報表功能新增了字段,那么歷史數據可能沒有新增加的字段的功能。
2:升級的時候session的問題。
升級的時候,如果負載均衡使用的是黏性策略(session不共享),那么升級服務的時候,肯定有些用戶的功能會斷掉的,所以一般選擇晚上,或者人少的時候升級系統。
升級的時候如果負載均衡策略是session共享,同樣有問題,有的用戶前一秒連上服務器A,下一秒連上服務器B,那么如果B服務器上的功能是新的,但是還不流程並不兼容之前的老服務,那么用戶的操作可能進行不下去。
最好的策略是黏性策略和Nginx搭配起來用,首先一部分服務器空出來,直到沒人用這些空出來的服務器之后,開始進行升級。升級之后。已經連接上舊服務的用戶,還是使用之前的服務器進行連接,新接入的用戶,舊轉接到新的服務器上去。等舊服務所在的服務器已經沒有人用的時候,再將舊服務器進行更新。