天天看點

從 0 到 1,Java Web 網站架構搭建的技術演進

導語:工作也有幾多年了,無論是身邊遇到的還是耳間聽聞的,多多少少也積攢了自己的一些經驗和思考,當然,我并沒有接觸太多高大上的分布式架構實踐,是以總結的經驗相對比較零碎,歡迎大家随時補充。

俗話說得好,冰凍三尺非一日之寒,滴水穿石非一日之功,羅馬也不是一天就建成的,對于開發人員來說,一個好的架構并不是一蹴而就的。

最開始,就是各種架構一搭,然後扔到 Tomcat 容器中跑,這時候我們的檔案、資料庫、應用都在一個伺服器上。

從 0 到 1,Java Web 網站架構搭建的技術演進

随着系統的上線,使用者量也會逐漸上升,很快一台伺服器已經滿足不了系統的負載,這時我們就要在伺服器還沒有超載時,提前做好準備。

由于我們是單體架構,優化架構在短時間内是不現實的,增加機器是一個不錯的選擇。這時,我們可能要把應用和資料庫服務單獨部署,如果有條件也可以把檔案伺服器單獨部署。

從 0 到 1,Java Web 網站架構搭建的技術演進
從 0 到 1,Java Web 網站架構搭建的技術演進

為了提升服務處理能力,我們在 Tomcat 容器前加一個代理伺服器,一般使用 Nginx,當然你如果更熟悉 Apache 也未嘗不可。

使用者的請求發送給反向代理,然後反向代理把請求轉發到後端的伺服器。

從嚴格意義上說,Nginx 是屬于 Web 伺服器,一般處理靜态 HTML、CSS、JS 請求;而 Tomcat 屬于 Web 容器,專門處理 JSP 請求,當然 Tomcat 也是支援 Html 的,隻是效果沒 Nginx 好而已。

反向代理的優勢,如下所示:

隐藏真實後端服務。

負載均衡叢集。

高可用叢集。

緩存靜态内容實作動靜分離。

安全限流。

靜态檔案壓縮。

解決多個服務跨域問題。

合并靜态請求(HTTP/2.0後已經被弱化)。

防火牆。

SSL 以及 http2。

從 0 到 1,Java Web 網站架構搭建的技術演進

基于以上 Nginx 反向代理,我們還可以實作動靜分離,靜态請求如 HTML、CSS、JS 等請求交給 Nginx 處理,動态請求分發給後端 Tomcat 處理。

Nginx 更新到 1.9.5+ 可以開啟 HTTP/2.0 時代,加速網站通路。當然,如果公司不差錢,CDN 也是一個不錯的選擇。

在這分布式微服務已經普遍流行的年代,我們沒必要踩過多的坑,就很容易進行拆分。

市面上已經有相對比較成熟的技術,比如阿裡開源的 Dubbo(官方明确表示已經開始維護了),Spring 家族的 Spring Cloud,當然具體如何去實施,無論是技術還是業務方面都要有很好的把控。

從 0 到 1,Java Web 網站架構搭建的技術演進

服務發現——Netflix Eureka

客服端負載均衡——Netflix Ribbon

斷路器——Netflix Hystrix

服務網關——Netflix Zuul

分布式配置——Spring Cloud Config

同步通信和異步通信

遠端調用 RPC

REST

消息隊列

服務拆分以後,随之而來的就是持續內建部署,你可能會用到以下工具:Docker、Jenkins、Git、Maven。

基本拓撲結構如下所示:

從 0 到 1,Java Web 網站架構搭建的技術演進

整個持續內建平台的架構演進,如下圖所示:

從 0 到 1,Java Web 網站架構搭建的技術演進

Linux 叢集主要分成三大類:

科學計算叢集。

我們最常見的也是生産中最常接觸到的就是負載均衡叢集。

從 0 到 1,Java Web 網站架構搭建的技術演進

負載均衡實作的三種方法:

DNS 負載均衡,一般域名注冊商的 DNS 伺服器不支援,但我用的阿裡雲解析已經支援。

四層負載均衡(F5、LVS),工作在 TCP 協定下。

七層負載均衡(Nginx、haproxy),工作在 HTTP 協定下。

大家都知道,服務一般分為有狀态和無狀态,而分布式 Session 就是針對有狀态的服務。

分布式 Session 的幾種實作方式:

基于資料庫的 Session 共享。

基于 resin/tomcat web 容器本身的 Session 複制機制。

基于 oscache/Redis/memcached 進行 Session 共享。

基于 cookie 進行 Session 共享。

分布式 Session 的幾種管理方式:

Session Replication 方式管理 (即 Session 複制)。 簡介:将一台機器上的 Session 資料廣播複制到叢集中其餘機器上。 使用場景:機器較少,網絡流量較小。 優點:實作簡單、配置較少、當網絡中有機器 Down 掉時不影響使用者通路。 缺點:廣播式複制到其餘機器有一定延時,帶來一定網絡開銷。

Session Sticky 方式管理。 簡介:即粘性 Session、當使用者通路叢集中某台機器後,強制指定後續所有請求均落到此機器上。 使用場景:機器數适中、對穩定性要求不是非常苛刻。 優點:實作簡單、配置友善、沒有額外網絡開銷。 缺點:網絡中有機器 Down 掉時,使用者 Session 會丢失、容易造成單點故障。

緩存集中式管理。 簡介:将 Session 存入分布式緩存叢集中的某台機器上,當使用者通路不同節點時先從緩存中拿 Session 資訊。 使用場景:叢集中機器數多、網絡環境複雜。 優點:可靠性好。 缺點:實作複雜,穩定性依賴于緩存的穩定性、Session 資訊放入緩存時要有合理的政策寫入。

目前生産中使用到的:

基于 Tomcat 配置實作的 Mem Cache 緩存管理 Session 實作(麻煩)。

基于 Os Cache 和 shiro 多點傳播的方式實作(網絡影響)。

基于 Spring-Session+Redis 的方式實作(最适合)。

負載均衡政策的優劣及其實作的難易程度有兩個關鍵因素:負載均衡算法,對網絡系統狀況的檢測方式和能力。

rr 輪詢排程算法

顧名思義,輪詢分發請求。優點是實作簡單,缺點是不考慮每台伺服器的處理能力。

wrr 權重排程算法

我們給每個伺服器設定權值 weight,負載均衡排程器根據權值排程伺服器,伺服器被調用的次數跟權值成正比。優點是考慮了伺服器處理能力的不同。

sh 原位址散列

提取使用者 IP,根據散列函數得出一個 key,再根據靜态映射表,查出對應的 value,即目标伺服器 IP。一單目标機器超負荷,則傳回空。

dh 目标位址散列

同上,隻是現在提取的是目标位址的 IP 來做哈希。優點是以上兩種算法都能實作同一個使用者通路同一個伺服器。

lc 最少連接配接

優先把請求轉發給連接配接數少的伺服器。優點是使得叢集中各個伺服器的負載更加均勻。

wlc 權重最少連接配接

在 lc 的基礎上,為每台伺服器加上權值。算法為:(活動連接配接數*256+非活動連接配接數)÷權重 ,計算出來的值小的伺服器優先被選擇。優點是可以根據伺服器的能力配置設定請求。

sed 最短期望延遲

sed 跟 wlc 類似,差別是不考慮非活動連接配接數。算法為:(活動連接配接數+1)*256÷權重,同樣計算出來的值小的伺服器優先被選擇。

nq 永不排隊

改進的 sed 算法,我們想一下什麼情況下才能“永不排隊”,那就是伺服器的連接配接數為 0 的時候,那麼假如有伺服器連接配接數為 0,均衡器直接把請求轉發給它,無需經過 sed 的計算。

LBLC 基于局部性的最少連接配接

均衡器根據請求的目的 IP 位址,找出該 IP 位址最近被使用的伺服器,把請求轉發之,若該伺服器超載,則采用最少連接配接數算法。

LBLCR 帶複制的基于局部性的最少連接配接

均衡器根據請求的目的 IP 位址,找出該 IP 位址最近使用的“伺服器組”,注意,這裡不是具體某個伺服器,然後采用最少連接配接數算法,從該組中挑出具體的某台伺服器出來,把請求轉發之。

若該伺服器超載,那麼根據最少連接配接數算法,從在叢集的非本伺服器組的伺服器中,找出一台伺服器出來,加入本伺服器組,然後把請求轉發之。

MySQL 主從配置,讀寫分離并引入中間件,開源的 MyCat,阿裡的 DRDS 都是不錯的選擇。

如果是對高可用要求比較高,但是又沒有相應的技術保障,建議使用阿裡雲的 RDS 或者 Redis 相關資料庫,省事省力又省錢。

如果有搜尋業務需求,引入 solr 或者 elasticsearch 也是一個不錯的選擇,不要什麼都塞進關系型資料庫。

引入緩存無非是為了減輕後端資料庫服務的壓力,防止其"罷工"。

常見的緩存服務有:Ehcache、OsCache、MemCache、Redis,它們都是主流經得起考驗的緩存技術實作,特别是 Redis 已大規模運用于分布式叢集服務中,并證明了自己優越的性能。

異步通知:比如短信驗證,郵件驗證這些非實時回報性的邏輯操作。

從 0 到 1,Java Web 網站架構搭建的技術演進

流量削鋒:應該是消息隊列中的常用場景,一般在秒殺或團搶活動中使用廣泛。

日志處理:系統中的日志是必不可少的,但是如何去處理高并發下的日志卻是一個技術活,一不小心可能會壓垮整個服務。

工作中我們常用到的開源日志 ELK,為嘛中間會加一個 Kafka 或者 Redis 就是這麼一個道理(一群人湧入和排隊進的差別)。

消息通訊:點對點通信(個人對個人)或釋出訂閱模式(聊天室)。

消息隊列中提到的 ELK 開源日志元件對于中小型創業公司是一個不錯的選擇。

從 0 到 1,Java Web 網站架構搭建的技術演進

以上種種,沒有安全做保證,一切都會歸于零:

阿裡雲的 V** 虛拟專有網絡以及安全組配置。

自建機房的話,要自行配置防火牆安全政策。

相關服務通路,比如 MySQL、Redis、Solr 等如果沒有特殊需求盡量使用内網通路并設定鑒權。

盡量使用代理伺服器,不要對外開放過多的端口。

HTTPS 配合 HTTP/2.0 也是個不錯的選擇。

負載均衡(負載均衡算法)

反向代理

服務隔離

服務限流

服務降級(自動優雅降級)

失效轉移

逾時重試(代理逾時、容器逾時、前端逾時、中間件逾時、資料庫逾時、NoSql逾時)

復原機制(上線復原、資料庫版本復原、事務復原)

02 高并發

應用緩存

HTTP 緩存

多級緩存

分布式緩存

連接配接池

異步并發

二階段送出(強一緻)

三階段送出(強一緻)

消息中間件(最終一緻性),推薦阿裡的 RocketMQ。

從 0 到 1,Java Web 網站架構搭建的技術演進

任務隊列

請求隊列

擴容

單體垂直擴容

單體水準擴容

應用拆分

資料庫拆分

資料庫分庫分表

資料異構

分布式任務

SQL 注入

XSS 攻擊

CSRF 攻擊

拒絕服務(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

作者:張志朋 簡介:資深 Java 愛好者,深耕于線上教育領域。 來源:51CTO技術棧微信公衆号 \ https://blog.52itstyle.com