大型Java项目架构演进
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
大型Java項(xiàng)目架構(gòu)演進(jìn)過(guò)程
1. All-In-One (所有服務(wù)在一臺(tái)服務(wù)器上):
? ?也就是所有的服務(wù)都在同一個(gè)服務(wù)器上,包括應(yīng)用服務(wù)器、文件服務(wù)器和數(shù)據(jù)庫(kù)
2. 各服務(wù)分別部署在不同的服務(wù)器上
? ? 隨著用戶越來(lái)越多,訪問(wèn)量越來(lái)越大,硬盤(pán)、CPU、內(nèi)存等硬件開(kāi)始吃緊,一臺(tái)服務(wù)器已經(jīng)無(wú)法滿足需求,這個(gè)時(shí)候就需要將不同的服務(wù)部署在多個(gè)服務(wù)器上,給應(yīng)用服務(wù)(Application server)配置更好的內(nèi)存和cpu,給數(shù)據(jù)庫(kù)服務(wù)器配置更好,更大,更快的硬盤(pán)。
3. 添加緩存服務(wù)器:
? ? 隨著訪問(wèn)的并發(fā)越來(lái)越高,為了縮短接口的訪問(wèn)時(shí)間,提高訪問(wèn)性能。
????同時(shí)發(fā)現(xiàn),我們的很多業(yè)務(wù)數(shù)據(jù)不需要每次都從數(shù)據(jù)庫(kù)中獲取,于是我們使用緩存來(lái)進(jìn)行數(shù)據(jù)緩存,提高訪問(wèn)速度。
? ? (80%的業(yè)務(wù)集中在20%的數(shù)據(jù)上,即2--8原則)
? ? 在這里緩存又可以分為? 本地緩存 和 遠(yuǎn)程緩存。 同時(shí),遠(yuǎn)程緩存又有兩種情形:單機(jī)緩存 和 分布式集群緩存
? ? 使用該架構(gòu)需要思考和解決的問(wèn)題:
????? ? 1. 哪種業(yè)務(wù)特點(diǎn)的數(shù)據(jù)需要進(jìn)行緩存
????? ? 2. 哪些數(shù)據(jù)適合進(jìn)行本地緩存,哪些數(shù)據(jù)適合進(jìn)行遠(yuǎn)程緩存
????? ? 3. 分布式緩存在擴(kuò)容時(shí)會(huì)遇到什么問(wèn)題,如果解決
????? ? 4. 分布式緩存的算法都有哪幾種,各有什么優(yōu)缺點(diǎn)
?
4. 增加負(fù)載均衡器,服務(wù)器均衡:
? ? 隨著訪問(wèn)的QPS(每秒查詢率)不斷的提高,服務(wù)器的處理能力(例如Tomcat)可能就會(huì)出現(xiàn)瓶頸,雖然也可以購(gòu)買更加強(qiáng)大的硬件,但總會(huì)有上限,而且這個(gè)成本到了后期會(huì)出現(xiàn)指數(shù)級(jí)的增長(zhǎng),這個(gè)時(shí)候就需要做一個(gè)服務(wù)器的集群,通過(guò)負(fù)責(zé)均衡服務(wù)器來(lái)實(shí)現(xiàn)服務(wù)集群訪問(wèn)。
? ? 這個(gè)時(shí)候需要考慮的問(wèn)題:
????? ? 1. 負(fù)責(zé)均衡的調(diào)度策略都有哪些,各有什么優(yōu)缺點(diǎn),各適合什么場(chǎng)景。
?????????調(diào)度策略: 輪訓(xùn)、權(quán)重、地址散列(包含:源ip散列 和 目的ip散列)、最少連接、加權(quán)最少連接
????? ? 2. session的管理問(wèn)題
????????? ? 同一用戶可能第一次登陸的是A服務(wù)器,那么session信息是保存在A服務(wù)器上的,第二次可能訪問(wèn)的是B服務(wù)器,這個(gè)時(shí)候B服務(wù)器上并沒(méi)有該用戶的session信息,這時(shí)就涉及到了session管理的問(wèn)題問(wèn)題。
????? ? 方式1.?可以使用 Session?Sticky(粘滯會(huì)話)
????????????
????????????實(shí)現(xiàn)原理:對(duì)于同一連接中的數(shù)據(jù)包,負(fù)載均衡會(huì)將其進(jìn)行一個(gè)轉(zhuǎn)化,然后轉(zhuǎn)發(fā)至后端固定的服務(wù)器上進(jìn)行處理。也就像上圖所示,Browser1每次都會(huì)訪問(wèn)Application1這個(gè)服務(wù)器。這個(gè)方案解決了session的共享問(wèn)題。但是同時(shí)又有缺點(diǎn):1. 如果Application1進(jìn)行了重啟,那么保存在其上的信息將會(huì)全部消失,2. 負(fù)載均衡器成為了一個(gè)有狀態(tài)的服務(wù)器,要實(shí)現(xiàn)容災(zāi)會(huì)有麻煩。
????????? ? 方式2.? Session Copy
? ? 實(shí)現(xiàn)原理:Application之間會(huì)copy自身保存的session到其他服務(wù)器上,使得用戶通過(guò)負(fù)載均衡不論將請(qǐng)求發(fā)送至哪個(gè)Application,該Application都有該用戶的session信息。缺點(diǎn):1. 由于Application之間要不斷的同步session信息,可能造成帶寬不夠的問(wèn)題。2. 當(dāng)大量用戶在線的時(shí)候,Application會(huì)占用大量的內(nèi)存,不適合做大規(guī)模集群。
方式3. 基于cookie
????? ? 實(shí)現(xiàn)原理:用戶攜帶含有session信息的cookie去訪問(wèn)Application。缺點(diǎn):1. cookie的長(zhǎng)度是有限制的? 2. cookie保存在瀏覽器上,安全性是一個(gè)問(wèn)題。
????方式4. 使用session服務(wù)器
? ? 實(shí)現(xiàn)原理:所有用戶的session信息都統(tǒng)一保存在session server中。缺點(diǎn):1. session server是個(gè)單點(diǎn)的,如何解決該server的單點(diǎn),保證其高可用性 ?
5. 數(shù)據(jù)庫(kù)的讀寫(xiě)分離:
? ? 當(dāng)用戶量達(dá)到一定量的時(shí)候,數(shù)據(jù)庫(kù)的讀寫(xiě)操作的都是同一個(gè)數(shù)據(jù)庫(kù),這個(gè)時(shí)候數(shù)據(jù)庫(kù)就成為了一個(gè)瓶頸,這個(gè)時(shí)候就可以進(jìn)行數(shù)據(jù)庫(kù)的讀寫(xiě)分離
????? ? 包含主庫(kù)和從庫(kù),同時(shí)應(yīng)用要接入多數(shù)據(jù)源,并且通過(guò)統(tǒng)一的數(shù)據(jù)訪問(wèn)模型進(jìn)行數(shù)據(jù)訪問(wèn),數(shù)據(jù)庫(kù)讀寫(xiě)分離將所有的讀操作全部引入到Slave這個(gè)數(shù)據(jù)庫(kù)中,將所有的寫(xiě)操作全部引入到Master這個(gè)數(shù)據(jù)庫(kù)中,同時(shí)由于進(jìn)行了讀寫(xiě)數(shù)據(jù)分離,我們?cè)趹?yīng)用中實(shí)現(xiàn)了數(shù)據(jù)訪問(wèn)模塊,使得上層寫(xiě)代碼的人不知道數(shù)據(jù)讀寫(xiě)分離的情況,這樣我們多數(shù)據(jù)源的讀寫(xiě)對(duì)業(yè)務(wù)代碼就沒(méi)有了侵入。
????? ? 這個(gè)時(shí)候引申的問(wèn)題就有:1. 如何支持多數(shù)據(jù)源,2.?如何封裝對(duì)業(yè)務(wù)沒(méi)有侵入,3. 如何使用目前項(xiàng)目使用的ORM框架完成底層的讀寫(xiě)分離,4. 是否需要更換ORM,又各有什么優(yōu)缺點(diǎn),如何取舍。
????? ? 當(dāng)數(shù)據(jù)量非常大的時(shí)候,數(shù)據(jù)庫(kù)的讀寫(xiě)分離又會(huì)遇到一下問(wèn)題:1. 主庫(kù)和從庫(kù)在同步的時(shí)候,有沒(méi)有延時(shí);如果我們將主庫(kù)和從庫(kù)進(jìn)行了夸機(jī)房部署,那么在跨機(jī)房數(shù)據(jù)傳輸?shù)臅r(shí)候,延時(shí)更是一個(gè)問(wèn)題。2. 應(yīng)用對(duì)數(shù)據(jù)源的路由問(wèn)題
?6. 曾加了CDN和反向代理服務(wù)器:
? ? 為了提高服務(wù)器,又增加了CDN 和反向代理服務(wù)器。使用CDN可以很好的解決不同地區(qū)訪問(wèn)速度的問(wèn)題;反向代理則可以緩存用戶的資源
?
?7. 文件服務(wù)器改為了分布式文件服務(wù)器:
? ? 需要考慮的問(wèn)題:1. 如何不影響已部署在線上的業(yè)務(wù)訪問(wèn)(不能出現(xiàn)某個(gè)圖片不能訪問(wèn)了),2. 是否需要業(yè)務(wù)部門幫忙清洗數(shù)據(jù) 3. 是否需要備份服務(wù)器 4. 是否需要重新做域名解析等等。
8. 數(shù)據(jù)庫(kù)分表:
? ? 數(shù)據(jù)量大的時(shí)候,數(shù)據(jù)的增刪改查又出現(xiàn)了瓶頸,這個(gè)時(shí)候我們選擇使用專庫(kù)專用的方式,進(jìn)行數(shù)據(jù)的垂直拆分,相關(guān)的業(yè)務(wù)都使用自己專有的庫(kù)。
? ? 需要考慮的問(wèn)題:1. 跨業(yè)務(wù)的事物,夸庫(kù)的事物 (可以考慮分布式事物,或者去掉事物,或者不追求強(qiáng)事物),2. 夸庫(kù)的join怎么實(shí)現(xiàn)
9. 數(shù)據(jù)庫(kù)分表
? ? 隨著訪問(wèn)量過(guò)大,業(yè)務(wù)量過(guò)大,可能出現(xiàn)某個(gè)業(yè)務(wù)的數(shù)據(jù)庫(kù)的數(shù)據(jù)達(dá)到了單個(gè)數(shù)據(jù)庫(kù)的瓶頸,這個(gè)時(shí)候就要考慮進(jìn)行數(shù)據(jù)庫(kù)的水平拆分(將同一個(gè)表的數(shù)據(jù)拆分到兩個(gè)數(shù)據(jù)庫(kù)中)
????? ? 需要考慮的問(wèn)題:1. sql路由的問(wèn)題(假設(shè)查詢某個(gè)用戶,如何確定用戶在哪個(gè)數(shù)據(jù)庫(kù)中)2. 主見(jiàn)的策略會(huì)有所不同 3 分頁(yè)的問(wèn)題
10.?添加了搜索引擎和NoSql服務(wù)器
? ? ? ? 假如發(fā)現(xiàn)我們應(yīng)用服務(wù)器上的搜索量飆升,或者因?yàn)槲覀儗?duì)外做了一個(gè)推廣,這個(gè)時(shí)候我們將Application中的搜索功能單獨(dú)拆分出來(lái),做了一個(gè)搜索引擎,同時(shí)部分場(chǎng)景可以使用NoSql提高性能,同時(shí)我們開(kāi)發(fā)一個(gè)統(tǒng)一的數(shù)據(jù)訪問(wèn)模塊,這個(gè)某塊下面連著數(shù)據(jù)庫(kù)集群、搜索引擎、還有NoSql,解決上層應(yīng)用開(kāi)發(fā)的數(shù)據(jù)源問(wèn)題。
?
?
轉(zhuǎn)載于:https://my.oschina.net/Declan/blog/2222455
總結(jié)
以上是生活随笔為你收集整理的大型Java项目架构演进的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: MYSQL timestamp NOT
- 下一篇: Docker容器内部署Java微服务的内