從0到1,Java Web網(wǎng)站架構(gòu)搭建的技術(shù)演進
工作也有幾多年了,無論是身邊遇到的還是耳間聽聞的,多多少少也積攢了自己的一些經(jīng)驗和思考,當(dāng)然,我并沒有接觸太多高大上的分布式架構(gòu)實踐,所以總結(jié)的經(jīng)驗相對比較零碎,歡迎大家隨時補充。
俗話說得好,冰凍三尺非一日之寒,滴水穿石非一日之功,羅馬也不是一天就建成的,對于開發(fā)人員來說,一個好的架構(gòu)并不是一蹴而就的。
初始搭建
最開始,就是各種框架一搭,然后扔到 Tomcat 容器中跑,這時候我們的文件、數(shù)據(jù)庫、應(yīng)用都在一個服務(wù)器上。
服務(wù)分離
隨著系統(tǒng)的上線,用戶量也會逐步上升,很快一臺服務(wù)器已經(jīng)滿足不了系統(tǒng)的負載,這時我們就要在服務(wù)器還沒有超載時,提前做好準備。
由于我們是單體架構(gòu),優(yōu)化架構(gòu)在短時間內(nèi)是不現(xiàn)實的,增加機器是一個不錯的選擇。這時,我們可能要把應(yīng)用和數(shù)據(jù)庫服務(wù)單獨部署,如果有條件也可以把文件服務(wù)器單獨部署。
反向代理
為了提升服務(wù)處理能力,我們在 Tomcat 容器前加一個代理服務(wù)器,一般使用 Nginx,當(dāng)然你如果更熟悉 Apache 也未嘗不可。
用戶的請求發(fā)送給反向代理,然后反向代理把請求轉(zhuǎn)發(fā)到后端的服務(wù)器。
從嚴格意義上說,Nginx 是屬于 Web 服務(wù)器,一般處理靜態(tài) HTML、CSS、JS 請求;而 Tomcat 屬于 Web 容器,專門處理 JSP 請求,當(dāng)然 Tomcat 也是支持 Html 的,只是效果沒 Nginx 好而已。
反向代理的優(yōu)勢,如下所示:
- 隱藏真實后端服務(wù)。
- 負載均衡集群。
- 高可用集群。
- 緩存靜態(tài)內(nèi)容實現(xiàn)動靜分離。
- 安全限流。
- 靜態(tài)文件壓縮。
- 解決多個服務(wù)跨域問題。
- 合并靜態(tài)請求(HTTP/2.0后已經(jīng)被弱化)。
- 防火墻。
- SSL 以及 http2。
動靜分離
基于以上 Nginx 反向代理,我們還可以實現(xiàn)動靜分離,靜態(tài)請求如 HTML、CSS、JS 等請求交給 Nginx 處理,動態(tài)請求分發(fā)給后端 Tomcat 處理。
Nginx 升級到 1.9.5+ 可以開啟 HTTP/2.0 時代,加速網(wǎng)站訪問。當(dāng)然,如果公司不差錢,CDN 也是一個不錯的選擇。
服務(wù)拆分
在這分布式微服務(wù)已經(jīng)普遍流行的年代,我們沒必要踩過多的坑,就很容易進行拆分。
市面上已經(jīng)有相對比較成熟的技術(shù),比如阿里開源的 Dubbo(官方明確表示已經(jīng)開始維護了),Spring 家族的 Spring Cloud,當(dāng)然具體如何去實施,無論是技術(shù)還是業(yè)務(wù)方面都要有很好的把控。
01Dubbo
02SpringCloud
- 服務(wù)發(fā)現(xiàn)——Netflix Eureka
- 客服端負載均衡——Netflix Ribbon
- 斷路器——Netflix Hystrix
- 服務(wù)網(wǎng)關(guān)——Netflix Zuul
- 分布式配置——Spring Cloud Config
03微服務(wù)與輕量級通信
- 同步通信和異步通信
- 遠程調(diào)用 RPC
- REST
- 消息隊列
持續(xù)集成部署
服務(wù)拆分以后,隨之而來的就是持續(xù)集成部署,你可能會用到以下工具:Docker、Jenkins、Git、Maven。
基本拓撲結(jié)構(gòu)如下所示:
整個持續(xù)集成平臺的架構(gòu)演進,如下圖所示:
服務(wù)集群
Linux 集群主要分成三大類:
- 高可用集群。
- 負載均衡集群。
- 科學(xué)計算集群。
我們最常見的也是生產(chǎn)中最常接觸到的就是負載均衡集群。
01負載均衡實現(xiàn)
負載均衡實現(xiàn)的三種方法:
DNS 負載均衡,一般域名注冊商的 DNS 服務(wù)器不支持,但我用的阿里云解析已經(jīng)支持。
四層負載均衡(F5、LVS),工作在 TCP 協(xié)議下。
七層負載均衡(Nginx、haproxy),工作在 HTTP 協(xié)議下。
02分布式 Session
大家都知道,服務(wù)一般分為有狀態(tài)和無狀態(tài),而分布式 Session 就是針對有狀態(tài)的服務(wù)。
分布式 Session 的幾種實現(xiàn)方式:
- 基于數(shù)據(jù)庫的 Session 共享。
- 基于 resin/tomcat web 容器本身的 Session 復(fù)制機制。
- 基于 oscache/Redis/memcached 進行 Session 共享。
- 基于 cookie 進行 Session 共享。
分布式 Session 的幾種管理方式:
- Session Replication 方式管理 (即 Session 復(fù)制)。
簡介:將一臺機器上的 Session 數(shù)據(jù)廣播復(fù)制到集群中其余機器上。
使用場景:機器較少,網(wǎng)絡(luò)流量較小。
優(yōu)點:實現(xiàn)簡單、配置較少、當(dāng)網(wǎng)絡(luò)中有機器 Down 掉時不影響用戶訪問。
缺點:廣播式復(fù)制到其余機器有一定延時,帶來一定網(wǎng)絡(luò)開銷。
- Session Sticky 方式管理。
簡介:即粘性 Session、當(dāng)用戶訪問集群中某臺機器后,強制指定后續(xù)所有請求均落到此機器上。
使用場景:機器數(shù)適中、對穩(wěn)定性要求不是非常苛刻。
優(yōu)點:實現(xiàn)簡單、配置方便、沒有額外網(wǎng)絡(luò)開銷。
缺點:網(wǎng)絡(luò)中有機器 Down 掉時,用戶 Session 會丟失、容易造成單點故障。
- 緩存集中式管理。
簡介:將 Session 存入分布式緩存集群中的某臺機器上,當(dāng)用戶訪問不同節(jié)點時先從緩存中拿 Session 信息。
使用場景:集群中機器數(shù)多、網(wǎng)絡(luò)環(huán)境復(fù)雜。
優(yōu)點:可靠性好。
缺點:實現(xiàn)復(fù)雜,穩(wěn)定性依賴于緩存的穩(wěn)定性、Session 信息放入緩存時要有合理的策略寫入。
目前生產(chǎn)中使用到的:
- 基于 Tomcat 配置實現(xiàn)的 Mem Cache 緩存管理 Session 實現(xiàn)(麻煩)。
- 基于 Os Cache 和 shiro 組播的方式實現(xiàn)(網(wǎng)絡(luò)影響)。
- 基于 Spring-Session+Redis 的方式實現(xiàn)(最適合)。
03負載均衡策略
負載均衡策略的優(yōu)劣及其實現(xiàn)的難易程度有兩個關(guān)鍵因素:負載均衡算法,對網(wǎng)絡(luò)系統(tǒng)狀況的檢測方式和能力。
rr 輪詢調(diào)度算法
顧名思義,輪詢分發(fā)請求。優(yōu)點是實現(xiàn)簡單,缺點是不考慮每臺服務(wù)器的處理能力。
wrr 加權(quán)調(diào)度算法
我們給每個服務(wù)器設(shè)置權(quán)值 weight,負載均衡調(diào)度器根據(jù)權(quán)值調(diào)度服務(wù)器,服務(wù)器被調(diào)用的次數(shù)跟權(quán)值成正比。優(yōu)點是考慮了服務(wù)器處理能力的不同。
sh 原地址散列
提取用戶 IP,根據(jù)散列函數(shù)得出一個 key,再根據(jù)靜態(tài)映射表,查出對應(yīng)的 value,即目標服務(wù)器 IP。一單目標機器超負荷,則返回空。
dh 目標地址散列
同上,只是現(xiàn)在提取的是目標地址的 IP 來做哈希。優(yōu)點是以上兩種算法都能實現(xiàn)同一個用戶訪問同一個服務(wù)器。
lc 最少連接
優(yōu)先把請求轉(zhuǎn)發(fā)給連接數(shù)少的服務(wù)器。優(yōu)點是使得集群中各個服務(wù)器的負載更加均勻。
wlc 加權(quán)最少連接
在 lc 的基礎(chǔ)上,為每臺服務(wù)器加上權(quán)值。算法為:(活動連接數(shù)*256+非活動連接數(shù))÷權(quán)重 ,計算出來的值小的服務(wù)器優(yōu)先被選擇。優(yōu)點是可以根據(jù)服務(wù)器的能力分配請求。
sed 最短期望延遲
sed 跟 wlc 類似,區(qū)別是不考慮非活動連接數(shù)。算法為:(活動連接數(shù)+1)*256÷權(quán)重,同樣計算出來的值小的服務(wù)器優(yōu)先被選擇。
nq 永不排隊
改進的 sed 算法,我們想一下什么情況下才能“永不排隊”,那就是服務(wù)器的連接數(shù)為 0 的時候,那么假如有服務(wù)器連接數(shù)為 0,均衡器直接把請求轉(zhuǎn)發(fā)給它,無需經(jīng)過 sed 的計算。
LBLC 基于局部性的最少連接
均衡器根據(jù)請求的目的 IP 地址,找出該 IP 地址最近被使用的服務(wù)器,把請求轉(zhuǎn)發(fā)之,若該服務(wù)器超載,則采用最少連接數(shù)算法。
LBLCR 帶復(fù)制的基于局部性的最少連接
均衡器根據(jù)請求的目的 IP 地址,找出該 IP 地址最近使用的“服務(wù)器組”,注意,這里不是具體某個服務(wù)器,然后采用最少連接數(shù)算法,從該組中挑出具體的某臺服務(wù)器出來,把請求轉(zhuǎn)發(fā)之。
若該服務(wù)器超載,那么根據(jù)最少連接數(shù)算法,從在集群的非本服務(wù)器組的服務(wù)器中,找出一臺服務(wù)器出來,加入本服務(wù)器組,然后把請求轉(zhuǎn)發(fā)之。
讀寫分離
MySQL 主從配置,讀寫分離并引入中間件,開源的 MyCat,阿里的 DRDS 都是不錯的選擇。
如果是對高可用要求比較高,但是又沒有相應(yīng)的技術(shù)保障,建議使用阿里云的 RDS 或者 Redis 相關(guān)數(shù)據(jù)庫,省事省力又省錢。
全文檢索
如果有搜索業(yè)務(wù)需求,引入 solr 或者 elasticsearch 也是一個不錯的選擇,不要什么都塞進關(guān)系型數(shù)據(jù)庫。
緩存優(yōu)化
引入緩存無非是為了減輕后端數(shù)據(jù)庫服務(wù)的壓力,防止其"罷工"。
常見的緩存服務(wù)有:Ehcache、OsCache、MemCache、Redis,它們都是主流經(jīng)得起考驗的緩存技術(shù)實現(xiàn),特別是 Redis 已大規(guī)模運用于分布式集群服務(wù)中,并證明了自己優(yōu)越的性能。
消息隊列
異步通知:比如短信驗證,郵件驗證這些非實時反饋性的邏輯操作。
流量削鋒:應(yīng)該是消息隊列中的常用場景,一般在秒殺或團搶活動中使用廣泛。
日志處理:系統(tǒng)中的日志是必不可少的,但是如何去處理高并發(fā)下的日志卻是一個技術(shù)活,一不小心可能會壓垮整個服務(wù)。
工作中我們常用到的開源日志 ELK,為嘛中間會加一個 Kafka 或者 Redis 就是這么一個道理(一群人涌入和排隊進的區(qū)別)。
消息通訊:點對點通信(個人對個人)或發(fā)布訂閱模式(聊天室)。
日志服務(wù)
消息隊列中提到的 ELK 開源日志組件對于中小型創(chuàng)業(yè)公司是一個不錯的選擇。
安全優(yōu)化
以上種種,沒有安全做保證,一切都會歸于零:
- 阿里云的 VPN 虛擬專有網(wǎng)絡(luò)以及安全組配置。
- 自建機房的話,要自行配置防火墻安全策略。
- 相關(guān)服務(wù)訪問,比如 MySQL、Redis、Solr 等如果沒有特殊需求盡量使用內(nèi)網(wǎng)訪問并設(shè)置鑒權(quán)。
- 盡量使用代理服務(wù)器,不要對外開放過多的端口。
- HTTPS 配合 HTTP/2.0 也是個不錯的選擇。
架構(gòu)師必備詞匯
01高可用
- 負載均衡(負載均衡算法)
- 反向代理
- 服務(wù)隔離
- 服務(wù)限流
- 服務(wù)降級(自動優(yōu)雅降級)
- 失效轉(zhuǎn)移
- 超時重試(代理超時、容器超時、前端超時、中間件超時、數(shù)據(jù)庫超時、NoSql超時)
- 回滾機制(上線回滾、數(shù)據(jù)庫版本回滾、事務(wù)回滾)
02高并發(fā)
- 應(yīng)用緩存
- HTTP 緩存
- 多級緩存
- 分布式緩存
- 連接池
- 異步并發(fā)
03分布式事務(wù)
- 二階段提交(強一致)
- 三階段提交(強一致)
- 消息中間件(最終一致性),推薦阿里的 RocketMQ。
04隊列
- 任務(wù)隊列
- 消息隊列
- 請求隊列
05擴容
- 單體垂直擴容
- 單體水平擴容
- 應(yīng)用拆分
- 數(shù)據(jù)庫拆分
- 數(shù)據(jù)庫分庫分表
- 數(shù)據(jù)異構(gòu)
- 分布式任務(wù)
06網(wǎng)絡(luò)安全
- SQL 注入
- XSS 攻擊
- CSRF 攻擊
- 拒絕服務(wù)(DoS,Denial of Service)攻擊
架構(gòu)師必備工具
01操作系統(tǒng)
Linux(必備)、某軟的
02負載均衡
DNS、F5、LVS、Nginx、OpenResty、HAproxy、負載均衡SLB(阿里云)
03分布式框架
Dubbo、Motan、Spring-Could
04數(shù)據(jù)庫中間件
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數(shù)據(jù)庫
MySQL、Redis、MongoDB、PostgreSQL、Memcache、HBase
11網(wǎng)絡(luò)
專用網(wǎng)絡(luò) VPC、彈性公網(wǎng) IP、CDN