開發Java Web程序

1. 考慮使用不止一個數據中心javascript

在商務領域,一直存在許多恐怖的道聽途說,而這些恐慌都由於他們只使用了單一的數據中心。若是你想在天然災害或者電力供應故障中倖免,那麼請使用多於1個的數據中心,使用active-active模式來配置你全部的數據中心。雖然在開銷上可能會有所增長,可是比只使用單active的配置要值得多——由於在passive和active副本上,總會發現有些數據片不一致。css

2. 考慮使用稀疏數據中心部署java

無論是經過PaaS,仍是運營團隊進行,當軟件集羣被部署到同一個數據中心的機架上時,確保這些機架使用不一樣的電力供應。你不可能保證機架供電的萬無一失,一旦失敗將會致使整個機架上服務器的丟失,這個時候你絕對不會但願整個數據中心都只連在一個電路上。node

3. 考慮使用私有云來組織資源react

IaaS開源解決方案Openstack等其餘的軟件至今還沒有成熟,須要龐大的團隊來運營,在運行期間會產生各類各樣的問題,除非你有足夠的預算,不然別考慮創建一個私有的雲服務。然而,私有云能夠提供衆多優點。首先在部署方面就能夠進行衆多的定製化,這遠比AWS或者是Rackspace貨架上的選擇要多。其次它容許你作許多的硬件定製化,就比如在硬件層次的Oracle就比準虛擬化環境快得多。web

4. 考慮使用PaaS作解決方案數據庫

爲軟件釋放投入巨量人力進行部署的日子已接近盡頭,各個機構在敏捷及快速市場投放上絞盡腦汁,而PaaS無疑會加速這個部署過程。它容許特性儘量快的發佈,同時也能讓開發者獲得極大的知足。這是個很是好的開始,給予開發者部署集維護本身軟件的工具,這將給工做積極性帶來很大的提升。同時,愈來愈多的開發者甚至不肯意加入沒有自動化軟件部署系統的公司。更少的領導,更簡化的環節,將給你帶來無與倫比的效率。編程

5. 若是使用Oracle或者MySQL,只作基於主鍵的查詢緩存

只有在RAC中存在不多的Artifacts時,Oracle才能在流量高峯時得到最佳性能。儘量避免使用Referential Integrity、Triggers、Materialized Views、Views、Stored Procedures和其餘的Oracle Artifacts。Triggers能夠在從數據訪問層實現。Stored Procedures能夠徹底轉移到應用層。數據庫只用來存儲數據,基於字段進行存儲而不是主鍵,使用相似Lucene的索引器作表的索引,使用一個容許在結果集上作基於其餘字段的查詢,這將會返回這個記錄的主鍵,而這個主關鍵字能夠進一步被用來拿取記錄。服務器

6. 考慮使用Oracle或者MySQL分片

當schema達到臨界點,Oracle的可伸縮性將被限制,這裏建議你對schema作基於功能(好比訂單,產品目錄,促銷活動,客戶等)上的分片,同時也爲高密度表作key shards。爲key shards使用一致性哈希,這樣當一個新的RAC被添加RAC集時,你再也不須要遍歷全部RAC中的鍵,以獲悉哪些鍵須要被移動到鍵的分片中。

7. 若是你使用Oracle作RDBMS,考慮使用Data Guard及Golden Gate

使用這兩種技術將大大簡化甲骨文的運營週期,Data Guard容許一個近實時passive讀副本(沒有客戶端會與之鏈接),而Golden Gate則容許一個近實時的active讀寫副本。

推薦的部署拓撲之一就是爲同個數據中心的每一個分片配置1個Data Guard;使用Golden Gate來備份其餘數據中心的每個分片。

注意:Golden Gate只是近實時

8. 爲Oracle或者MySQL添加數據訪問層

假設你有一個能夠接受500個鏈接的Oracle RAC,而你有25個jBoss實例和這個甲骨文RAC對話,每一個Jboss實例配置範圍10到50的數據庫鏈接池。

當jBoss集羣開啓時,鏈接到Oracle的數目爲250(25乘10),一切運行良好。隨着流量快到jBoss集羣的峯值,想象一下將會發生什麼。在某個點後,Oracle將開始拒絕鏈接。

所以建議經過一個Multiplexer層創建一個Multiplexe應用程序服務器鏈接。能夠是一個簡單的 netty應用,這個應用運行在一個每一個netty節點僅可以與Oracle創建25個鏈接的集羣上,可是對入站鏈接來者不拒。它會將全部的鏈接循環傳遞給Oracle,可是絕對不會超過25個,同時還使用Oracle JDBC驅動與Oracle通訊。

9. 避免跨數據中心事務

當下,這已是很是簡單的事情,可是在任何地方都很是適用,包括Oracle。在兩個數據不一樣數據中心,不要適用1個XA適配器去作跨數據中心事務,這將致使至關長時間的應用線程阻塞,直到兩個階段的提交完成,所以將帶來你的應用程序服務、服務和全部同步上傳流崩潰,最終會由於線程數量增長而致使整個應用程序崩潰,好比在相似Black Friday流量狀況下。

10. 考慮分佈式緩存框架

Memcached、Counbase是最經常使用的選擇。但實際上,卸載非易失性數據到一箇中心緩存集羣上,確實不必在每一個JVM上作相同的拷貝。可是確實須要設置小數量的JVM堆做爲分佈式緩存的一個MRU緩存,這樣的話,緩存集羣自己將會受到很是少的網絡調用。

  • 在JVM上大多數分佈式緩存支持本地緩存的概念,它將儲存最經常使用的對象。
  • JVM上,GC的pause time一樣被最小化了,由於對象圖中須要遍歷的對象比之前更少了。
  • Warmup過程是必不可少的,這能夠幫助將數據導入分佈式緩存,這個過程應該在晚上或者是用戶訪問量低的時候。

 

11. 考慮把web應用程序分解爲服務

上帝保佑,若是你負責的web應用程序超過50萬行代碼,並且仍然只做單一的項目部署,那麼是時候根據服務功能把它分解成專業的服務了,並分配到不一樣的子組織或團隊去操做。將Web應用程序分解爲服務有如下諸多優點:

  • Debug將變得簡單
  • 擴展及讓子系統運行的更好將變得簡單
  • 很容易瞭解運行環境裏發生了什麼
  • 更快的添加新功能

12. 不要使用session stickiness

這絕是與魔鬼共舞,session stickiness會讓極值負荷下沒法擴展。你的客戶端應該可以調用ANY應用程序服務器,並獲得其查詢值。其中一個方法是讓服務無狀態,也稱爲RestFUL服務。每一個請求,客戶端會收發標識狀態的id,表明客戶session的數據存儲在數據庫或跨多個請求的分佈式緩存。

若是由於某個緣由,取代RestFUL服務,你網站大部分是創建在HttpServlets和HttpSession屬性上,使用如下方法能夠實現獨立session stickiness的網站:

一個servlet過濾器面對每項服務,取走每一個請求的id,而後調用分佈式緩存來填充會話屬性,這將有助於處理請求。所以數據中心任何服務器均可以響應來自客戶端的請求,由於session狀態被保持在memcached。

不使用session stickiness還容許使用「rolling restart」方式重啓你的應用程序服務器集羣,從而實現100%的正常運行時間。

13. 終止反向代理商的SSL

在SSL信號交換及潛在TCP通訊有效保持上,反向代理很是擅長。在反向代理有上設定一個顯式的TCP維持計時器,nGinx及許多其餘http服務器都容許這麼作,這容許TCP鏈接屢次重複使用。與TCP信號交換的成本是3個network call,這樣許多請求就能夠避免這個開銷。

所以從反向代理到應用程序服務器,一般是RAW http;所以,一樣也要維持TCP的上行鏈接。

14. 爲GSLB類型的負載平衡器使用粘性負載平衡

跨數據中心的負載平衡,建議使用session stickiness。這是由於在跨數據中心複製上,數據庫Oracle或Cassandra只能依賴最終一致性技術。所以,非粘性跨數據中心負載均衡器將使你的客戶端再也沒法訪問網站。所以常用GSLB,多數狀況下,你的CDN將得到基於位置的GSLB數據中心解決方案。

15. 減小主頁上的CNAME查找

儘可能減小主頁上的CNAME查找。單單主頁的CNAME查找,一些網站就有10個或更多。即便客戶端DNS查找的答案可能來自他們的ISP遞歸緩存,咱們仍然能夠作的更好。www.dwhao.com CNAME查找爲零。

dig   www.dwhao.com   
;; QUESTION SECTION:  
; www.dwhao.com IN A  
;; ANSWER SECTION:  
www.dwhao.com .28 IN A 205.251.242.54

16. 擁抱一切「reactor」

在高流量軟件系統中,reactor模式一次又一次的得以證實。一系列框架被建立用以實現reactor模式,reactor大體使用場景以下:

  • 做爲一個反向代理:nGinx
  • 應用程序服務器: node.js
  • 並行處理的: Scala的actor model

除非你的業務邏輯是高度CPU綁定,不然就得考慮使用reactor模式或基於事件循環的軟件。若是沒法實現,能夠考慮像RxJava框架那樣的響應式編程模型。

17. 實現調用取消

從Siddharth Anand的一個會議上獲得靈感,服務調用時的調用圖。首先,經過數字的遞減實現超時。接下來,服務調用圖的每次調用,都會建立一個UUID,並在分佈式緩存中爲UUID設置一個標誌:

UUID:true

  • 若是服務調用圖中的任何服務超時,UUID的標誌設置爲false。
  • 如今爲全部服務實現一個servlet過濾器,一直檢查這個標誌,只在這個標誌是真時才繼續處理。
  • 若是標誌是是假,程序返回一個空的response。
  • 這在大業務量時,能夠禁止沒必要要的調用。

18. 執行GC搜索協議

再次,靈感來自於同一我的——經過Netty讓全部的服務也顯示一個TCP端口。在調用一個服務以前,調用TCP端口而後暫停2 - 5 ms等待訪問。若是調用超時,這意味着這個Java進程正字作一個「stop the world」的垃圾收集。重生之大文豪www.dwhao.com客戶當即切換到另外一個服務實例,而後嘗試一樣的步驟。若是調用成功,而後調用實例上的實際服務。

注意:實現GC搜索協議須要的客戶端ip地址配置(即客戶端負載均衡)。

19. 儘量讓業務邏輯和I / O存取異步進行

在流量爆炸時,異步業務邏輯能讓您的應用程序避免創建過多的線程。將事件隊列推送給負載均衡集羣,讓它去作進程訂閱的業務邏輯,而不是在http request/response週期線程作這些事。

20. 偏心最終一致性數據庫

尤爲是當你在運行跨數據中心的應用程序。除非你的用例是事務處理的(好比訂單)等等,不然偏心使用最終一致性數據庫好比Cassandra,並儘量少的使用ACID類型數據庫。

21. 使用CDN服務靜態內容

使用CDN服務靜態內容——javascript、圖像、css 等。CDN能有效地將靜態內容複製到近客戶地方,所以許多針對這些靜態內容的http請求最終穿越不會超過幾百英里。 

22. 打包壓縮javascript到一個文件中

減小javascript內聯。

相關文章
相關標籤/搜索