您的位置:首頁>正文

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

作者:張志朋

簡介:資深 Java 愛好者, 深耕于線上教育領域

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

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

初始搭建

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

服務分離

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

由於我們是單體架構, 優化架構在短時間內是不現實的, 增加機器是一個不錯的選擇。

這時, 我們可能要把應用和資料庫服務單獨部署, 如果有條件也可以把檔案伺服器單獨部署。

反向代理

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

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

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

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

隱藏真實後端服務。

負載均衡集群。

高可用集群。

緩存靜態內容實現動靜分離。

安全限流。

靜態檔案壓縮。

解決多個服務跨域問題。

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

防火牆。

SSL 以及 http2。

動靜分離

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

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

服務拆分

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

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

01 Dubbo

02 SpringCloud

服務發現——Netflix Eureka

客服端負載均衡——Netflix Ribbon

斷路器——Netflix Hystrix

服務閘道——Netflix Zuul

分散式配置——Spring Cloud Config

03 微服務與羽量級通信

同步通信和非同步通信

遠端調用 RPC

REST

訊息佇列

持續集成部署

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

基本拓撲結構如下所示:

整個持續集成平臺的架構演進,如下圖所示:

服務集群

Linux 集群主要分成三大類:

高可用集群。

負載均衡集群。

科學計算集群。

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

01 負載均衡實現

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

DNS 負載均衡,一般功能變數名稱註冊商的 DNS 伺服器不支援,但我用的阿裡雲解析已經支持。

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

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

02 分散式 Session

大家都知道,服務一般分為有狀態和無狀態,而分散式 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 的方式實現(最適合)。

03 負載均衡策略

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

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 已大規模運用于分散式集群服務中,並證明了自己優越的性能。

訊息佇列

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

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

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

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

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

日誌服務

訊息佇列中提到的 ELK 開源日誌元件對於中小型創業公司是一個不錯的選擇。

安全優化

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

阿裡雲的 VPN 虛擬專有網路以及安全性群組配置。

自建機房的話,要自行配置防火牆安全性原則。

相關服務訪問,比如 MySQL、Redis、Solr 等如果沒有特殊需求儘量使用內網訪問並設置鑒權。

儘量使用代理伺服器,不要對外開放過多的埠。

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

架構師必備詞彙

01 高可用

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

反向代理

服務隔離

服務限流

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

失效轉移

超時重試(代理超時、容器超時、前端超時、中介軟體超時、資料庫超時、NoSql超時)

回滾機制(上線回滾、資料庫版本回滾、交易復原)

02 高併發

應用緩存

HTTP 緩存

多級緩存

分散式緩存

連接池

非同步併發

03 分散式事務

二階段提交(強一致)

三階段提交(強一致)

消息中介軟體(最終一致性),推薦阿裡的 RocketMQ。

04 佇列

任務佇列

訊息佇列

請求佇列

05

擴容

單體垂直擴容

單體水準擴容

應用拆分

資料庫拆分

資料庫分庫分表

資料異構

分散式任務

06 網路安全

SQL 注入

XSS 攻擊

CSRF 攻擊

拒絕服務(DoS,Denial of Service)攻擊

架構師必備工具

01 作業系統

Linux(必備)、某軟的

02 負載均衡

DNS、F5、LVS、Nginx、OpenResty、HAproxy、負載均衡SLB

03 分散式框架

Dubbo、Motan、Spring-Could

04 資料庫中介軟體

DRDS 、Mycat、360 Atlas、Cobar (不維護了)

05 消息隊列

RabbitMQ、ZeroMQ、Redis、ActiveMQ、Kafka

06 註冊中心

Zookeeper、Redis

07 緩存

Redis、Oscache、Memcache、Ehcache

08 集成部署

Docker、Jenkins、Git、Maven

09 存儲

OSS、NFS、FastDFS、MogileFS

10 資料庫

MySQL、Redis、MongoDB、PostgreSQL、Memcache、HBase

11 網路

私人網路絡 VPC、彈性公網 IP、CDN

整個持續集成平臺的架構演進,如下圖所示:

服務集群

Linux 集群主要分成三大類:

高可用集群。

負載均衡集群。

科學計算集群。

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

01 負載均衡實現

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

DNS 負載均衡,一般功能變數名稱註冊商的 DNS 伺服器不支援,但我用的阿裡雲解析已經支持。

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

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

02 分散式 Session

大家都知道,服務一般分為有狀態和無狀態,而分散式 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 的方式實現(最適合)。

03 負載均衡策略

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

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 已大規模運用于分散式集群服務中,並證明了自己優越的性能。

訊息佇列

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

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

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

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

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

日誌服務

訊息佇列中提到的 ELK 開源日誌元件對於中小型創業公司是一個不錯的選擇。

安全優化

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

阿裡雲的 VPN 虛擬專有網路以及安全性群組配置。

自建機房的話,要自行配置防火牆安全性原則。

相關服務訪問,比如 MySQL、Redis、Solr 等如果沒有特殊需求儘量使用內網訪問並設置鑒權。

儘量使用代理伺服器,不要對外開放過多的埠。

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

架構師必備詞彙

01 高可用

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

反向代理

服務隔離

服務限流

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

失效轉移

超時重試(代理超時、容器超時、前端超時、中介軟體超時、資料庫超時、NoSql超時)

回滾機制(上線回滾、資料庫版本回滾、交易復原)

02 高併發

應用緩存

HTTP 緩存

多級緩存

分散式緩存

連接池

非同步併發

03 分散式事務

二階段提交(強一致)

三階段提交(強一致)

消息中介軟體(最終一致性),推薦阿裡的 RocketMQ。

04 佇列

任務佇列

訊息佇列

請求佇列

05

擴容

單體垂直擴容

單體水準擴容

應用拆分

資料庫拆分

資料庫分庫分表

資料異構

分散式任務

06 網路安全

SQL 注入

XSS 攻擊

CSRF 攻擊

拒絕服務(DoS,Denial of Service)攻擊

架構師必備工具

01 作業系統

Linux(必備)、某軟的

02 負載均衡

DNS、F5、LVS、Nginx、OpenResty、HAproxy、負載均衡SLB

03 分散式框架

Dubbo、Motan、Spring-Could

04 資料庫中介軟體

DRDS 、Mycat、360 Atlas、Cobar (不維護了)

05 消息隊列

RabbitMQ、ZeroMQ、Redis、ActiveMQ、Kafka

06 註冊中心

Zookeeper、Redis

07 緩存

Redis、Oscache、Memcache、Ehcache

08 集成部署

Docker、Jenkins、Git、Maven

09 存儲

OSS、NFS、FastDFS、MogileFS

10 資料庫

MySQL、Redis、MongoDB、PostgreSQL、Memcache、HBase

11 網路

私人網路絡 VPC、彈性公網 IP、CDN

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示