JavaWeb專案技術架構總結
題記
工作也有幾多年了,無論是身邊遇到的還是耳間聞到的,多多少少也積攢了自己的一些經驗和思考,當然,博主並沒有太多接觸高大上的分散式架構實踐,相對比較零碎,隨時補充(附帶架構裝逼詞彙)。
俗話說的好,冰凍三尺非一日之寒,滴水穿石非一日之功,羅馬也不是一天就建成的,當然對於我們開發人員來說,一個好的架構也不是一蹴而就的。
初始搭建
開始的開始,就是各種框架一搭,然後扔到Tomcat容器中跑就是了,這時候我們的檔案,資料庫,應用都在一個伺服器上。
服務分離
隨著系統的的上線,使用者量也會逐步上升,很明顯一臺伺服器已經滿足不了系統的負載,這時候,我們就要在伺服器還沒有超載的時候,提前做好準備。
由於我們是單體架構,優化架構在短時間內是不現實的,增加機器是一個不錯的選擇。這時候,我們可能要把應用和資料庫服務單獨部署,如果有條件也可以把檔案伺服器單獨部署。
反向代理
為了提升服務處理能力,我們在Tomcat容器前加一個代理伺服器,我一般使用Nginx,當然你如果更熟悉apache也未嘗不可。
使用者的請求傳送給反向代理,然後反向代理把請求轉發到後端的伺服器。
嚴格意義上來說,Nginx是屬於web伺服器,一般處理靜態html、css、js請求,而Tomcat屬於web容器,專門處理JSP請求,當然Tomcat也是支援html的,只是效果沒Nginx好而已。
反向代理的優勢,如下:
1.隱藏真實後端服務
2.負載均衡叢集
3.高可用叢集
4.快取靜態內容實現動靜分離
5.安全限流
6.靜態檔案壓縮
7.解決多個服務跨域問題
8.合併靜態請求(HTTP/2.0後已經被弱化)
9.防火牆
10.SSL以及http2
動靜分離
基於以上Nginx反向代理,我們還可以實現動靜分離,靜態請求如html、css、js等請求交給Nginx處理,動態請求分發給後端Tomcat處理。
Nginx 升級到1.9.5+可以開啟HTTP/2.0時代,加速網站訪問。
當然,如果公司不差錢,CDN也是一個不錯的選擇。
服務拆分
在這分散式微服務已經普遍流行的年代,其實我們沒必要踩過多的坑,就很容易進行拆分。市面上已經有相對比較成熟的技術,比如阿里開源的Dubbo(官方明確表示已經開始維護了),spring家族的spring cloud,當然具體如何去實施,無論是技術還是業務方面都要有很好的把控。
Dubbo
SpringCloud
1.服務發現——Netflix Eureka
2.客服端負載均衡——Netflix Ribbon
3.斷路器——Netflix Hystrix
4.服務閘道器——Netflix Zuul
5.分散式配置——Spring Cloud Config
微服務與輕量級通訊
1.同步通訊和非同步通訊
2.遠端呼叫RPC
3.REST
4.訊息佇列
持續整合部署
服務拆分以後,隨著而來的就是持續整合部署,你可能會用到以下工具。
Docker、Jenkins、Git、Maven
圖片源於網路,基本拓撲結構如下所示:
整個持續整合平臺架構演進到如下圖所示:
服務叢集
Linux叢集主要分成三大類( 高可用叢集, 負載均衡叢集,科學計算叢集)。其實,我們最常見的也是生產中最常接觸到的就是負載均衡叢集。
負載均衡實現
1.DNS負載均衡,一般域名註冊商的dns伺服器不支援,但博主用的阿里雲解析已經支援
2.四層負載均衡(F5、LVS),工作在TCP協議下
3.七層負載均衡(Nginx、haproxy),工作在Http協議下
分散式session
大家都知道,服務一般分為有狀態和無狀態,而分散式sessoion就是針對有狀態的服務。
分散式Session的幾種實現方式
1.基於資料庫的Session共享
2.基於resin/tomcat web容器本身的session複製機制
3.基於oscache/Redis/memcached 進行 session 共享。
4.基於cookie 進行session共享
分散式Session的幾種管理方式
1.Session Replication 方式管理 (即session複製)
簡介:將一臺機器上的Session資料廣播複製到叢集中其餘機器上
使用場景:機器較少,網路流量較小
優點:實現簡單、配置較少、當網路中有機器Down掉時不影響使用者訪問
缺點:廣播式複製到其餘機器有一定廷時,帶來一定網路開銷
2.Session Sticky 方式管理
簡介:即粘性Session、當用戶訪問叢集中某臺機器後,強制指定後續所有請求均落到此機器上
使用場景:機器數適中、對穩定性要求不是非常苛刻
優點:實現簡單、配置方便、沒有額外網路開銷
缺點:網路中有機器Down掉時、使用者Session會丟失、容易造成單點故障
3.快取集中式管理
簡介:將Session存入分散式快取叢集中的某臺機器上,當用戶訪問不同節點時先從快取中拿Session資訊
使用場景:叢集中機器數多、網路環境複雜
優點:可靠性好
缺點:實現複雜、穩定性依賴於快取的穩定性、Session資訊放入快取時要有合理的策略寫入
目前生產中使用到的
1.基於tomcat配置實現的MemCache快取管理session實現(麻煩)
2.基於OsCache和shiro組播的方式實現(網路影響)
3.基於spring-session+redis實現的(最適合)
負載均衡策略
負載均衡策略的優劣及其實現的難易程度有兩個關鍵因素:一、負載均衡演算法,二、對網路系統狀況的檢測方式和能力。
1、rr 輪詢排程演算法。顧名思義,輪詢分發請求。
優點:實現簡單
缺點:不考慮每臺伺服器的處理能力
2、wrr 加權排程演算法。我們給每個伺服器設定權值weight,負載均衡排程器根據權值排程伺服器,伺服器被呼叫的次數跟權值成正比。
優點:考慮了伺服器處理能力的不同
3、sh 原地址雜湊:提取使用者IP,根據雜湊函式得出一個key,再根據靜態對映表,查處對應的value,即目標伺服器IP。過目標機器超負荷,則返回空。
4、dh 目標地址雜湊:同上,只是現在提取的是目標地址的IP來做雜湊。
優點:以上兩種演算法的都能實現同一個使用者訪問同一個伺服器。
5、lc 最少連線。優先把請求轉發給連線數少的伺服器。
優點:使得叢集中各個伺服器的負載更加均勻。
6、wlc 加權最少連線。在lc的基礎上,為每臺伺服器加上權值。演算法為:(活動連線數*256+非活動連線數)÷權重 ,計算出來的值小的伺服器優先被選擇。
優點:可以根據伺服器的能力分配請求。
7、sed 最短期望延遲。其實sed跟wlc類似,區別是不考慮非活動連線數。演算法為:(活動連線數+1)*256÷權重,同樣計算出來的值小的伺服器優先被選擇。
8、nq 永不排隊。改進的sed演算法。我們想一下什麼情況下才能“永不排隊”,那就是伺服器的連線數為0的時候,那麼假如有伺服器連線數為0,均衡器直接把請求轉發給它,無需經過sed的計算。
9、LBLC 基於區域性性的最少連線。均衡器根據請求的目的IP地址,找出該IP地址最近被使用的伺服器,把請求轉發之,若該伺服器超載,最採用最少連線數演算法。
10、LBLCR 帶複製的基於區域性性的最少連線。均衡器根據請求的目的IP地址,找出該IP地址最近使用的“伺服器組”,注意,並不是具體某個伺服器,然後採用最少連線數從該組中挑出具體的某臺伺服器出來,把請求轉發之。若該伺服器超載,那麼根據最少連線數演算法,在叢集的非本伺服器組的伺服器中,找出一臺伺服器出來,加入本伺服器組,然後把請求轉發之。
讀寫分離
MySql主從配置,讀寫分離並引入中介軟體,開源的MyCat,阿里的DRDS都是不錯的選擇。
如果是對高可用要求比較高,但是又沒有相應的技術保障,建議使用阿里雲的RDS或者Redis相關資料庫,省事省力又省錢。
全文檢索
如果有搜尋業務需求,引入solr或者elasticsearch也是一個不錯的選擇,不要什麼都塞進關係型資料庫。
快取優化
引入快取無非是為了減輕後端資料庫服務的壓力,防止其"罷工"。
常見的快取服務有,Ehcache、OsCache、MemCache、Redis,當然這些都是主流經得起考驗的快取技術實現,特別是Redis已大規模運用於分散式叢集服務中,並證明了自己優越的效能。
訊息佇列
非同步通知:比如簡訊驗證,郵件驗證這些非實時反饋性的邏輯操作。
流量削鋒:應該是訊息佇列中的常用場景,一般在秒殺或團搶活動中使用廣泛。
日誌處理:系統中日誌是必不可少的,但是如何去處理高併發下的日誌確是一個技術活,一不小心可能會壓垮整個服務。工作中我們常用到的開源日誌ELK,為嘛中間會加一個Kafka或者redis就是這麼一個道理(一群人湧入和排隊進的區別)。
訊息通訊:點對點通訊(個人對個人)或釋出訂閱模式(聊天室)。
日誌服務
訊息佇列中提到的ELK開源日誌組間對於中小型創業供公司是一個不錯的選擇。
安全優化
以上種種,沒有安全做保證可能都會歸於零。
1.阿里雲的VPN虛擬專有網路以及安全組配置
2.自建機房的話,要自行配置防火牆安全策略
3.相關服務訪問,比如Mysql、Redis、Solr等如果沒有特殊需求儘量使用內網訪問並設定鑑權
4.儘量使用代理伺服器,不要對外開放過多的埠
5.https配合HTTP/2.0也是個不錯的選擇
架構裝逼必備詞彙
高可用
1.負載均衡(負載均衡演算法)
2.反向代理
3.服務隔離
4.服務限流
5.服務降級(自動優雅降級)
6.失效轉移
7.超時重試(代理超時、容器超時、前端超時、中介軟體超時、資料庫超時、NoSql超時)
8.回滾機制(上線回滾、資料庫版本回滾、事務回滾)
高併發
1.應用快取
2.HTTP快取
3.多級快取
4.分散式快取
5.連線池
6.非同步併發
分散式事務
1.二階段提交(強一致)
2.三階段提交(強一致)
3.訊息中介軟體(最終一致性),推薦阿里的RocketMQ
佇列
1.任務佇列
2.訊息佇列
3.請求佇列
擴容
1.單體垂直擴容
2.單體水平擴容
3.應用拆分
4.資料庫拆分
5.資料庫分庫分表
6.資料異構
7.分散式任務
網路安全
1.SQL注入
2.XSS攻擊
3.CSRF攻擊
4.拒絕服務(DoS,Denial of Service)攻擊
架構裝逼必備工具
作業系統
Linux(必備)、某軟的
負載均衡
DNS、F5、LVS、Nginx、OpenResty、HAproxy、負載均衡SLB(阿里雲)
分散式框架
Dubbo、Motan、Spring-Could
資料庫中介軟體
DRDS (阿里雲)、Mycat、360 Atlas、Cobar (不維護了)
訊息佇列
RabbitMQ、ZeroMQ、Redis、ActiveMQ、Kafka
註冊中心
Zookeeper、Redis
快取
Redis、Oscache、Memcache、Ehcache
整合部署
Docker、Jenkins、Git、Maven
儲存
OSS、NFS、FastDFS、MogileFS
資料庫
MySql、Redis、MongoDB、PostgreSQL、Memcache、HBase
網路
專用網路VPC、彈性公網IP、CDN