1. 程式人生 > >軟體架構演變之路--微分享

軟體架構演變之路--微分享

                               微分享-2018.11.05

分享主題:軟體架構演變之路

分享人:shinians

專案編碼:003

  

分享要點:

  1. 瞭解資料交換系統現有架構設計
  2. 現有架構遇到的問題以及解決方案
  3. 前後端分離系統快速迭代方案優化
  4. 一鍵化部署方案VS傳統方式
  5. 流行架構設計

 

一、大型網站系統的特點

高併發,大流量:需要面對高併發使用者,大流量訪問;

高可用:系統24小時不間斷的提供服務;

海量資料:需要儲存、管理海量的資料,需要使用大量的伺服器;

使用者分佈廣泛,網路情況複雜:很多大型網站都是為全球使用者服務,使用者的分佈範圍廣泛,情況差異大;

安全環境惡劣:網際網路的開放性,導致網站更容易受黑客的攻擊;

需求快速變更,釋出頻繁:相比傳統軟體,網際網路產品為了快速適應市場,滿足使用者的

需求,產品釋出的頻率是極高的;

漸進式發展:

與傳統行業軟體不同,網際網路產品不是事先就規劃好了整個產品的全部功能,幾乎每個大型網際網路網站都是從一個小網站,慢慢根據市場和使用者的改變而慢慢漸進發展成大型網站的;

  • 大型網站架構發展歷程

大型網站的技術挑戰主要來自三個方面:龐大的使用者體系高併發的訪問以及海量資料的儲存管理。基於這三點,我們就來看看,整個架構設計方面是如何演變的。

 

初始階段:這個階段一般網站使用者量也不多,訪問量都不大,資料量也不多,因此一般一臺伺服器就能搞定,應用程式,資料庫和檔案都可以部署在一臺伺服器上.

 

應用服務和資料服務分離階段隨著使用者數量的增加,越來越多的使用者訪問導致效能越來越差,資料也越來越多導致儲存空間不足,此時我們就需要考慮將應用和資料分離,此時網站需要3臺伺服器:應用伺服器+資料庫伺服器+檔案伺服器,架構設計如下圖:

使用快取改善效能階段:隨著資料庫壓力越來越大,我們需要考慮從資料上優化效能,大家都知道80%的業務訪問集中在20%的資料上,既然大部分業務集中訪問這少部分資料,那為何我們不考慮把這部分資料快取在記憶體中呢,不就可以減小對資料庫訪問的壓力了嘛;

快取又分為2種,一種是本地快取(本地快取是基於記憶體的,因此資料量有限,但是訪問速度快),另一種是遠端快取(一些中介軟體快取伺服器例如redis,這部分資料理論上不限容量,而且可以做成叢集模式)。

應用伺服器叢集優化網站併發能力階段:當用戶越來越多時,對網站的訪問量也越來越多,應用伺服器處理請求越來越慢,此時我們可以考慮將應用伺服器做成叢集模式部署,再通過負載均衡排程器,將使用者的請求分發給叢集上不同的應用伺服器。

資料庫讀寫分離階段:網站在使用了快取之後,使部分資料可以不通過資料庫就能完成,但是對於資料庫的修改操作,還是需要訪問資料庫的,這個時候,資料庫的負載壓力過高,能為網站的效能瓶頸,此時我們就要考慮資料庫的讀寫分離了,資料庫的讀寫分離是建立在主從熱備的基礎上的,基本目前大多數主流資料庫都支援主從熱備,通過配置兩臺或者多臺資料庫的主從關係(1主1從,1主多從,多主多從),實現資料的讀(從庫)寫(主庫)分離,主庫主動將資料同步到從庫。

向代理和CDN加速網站響應階段:為了加快網站的訪問速度,我們主要考慮的手段為CDN和反向代理,CDN是部署在網路提供商的機房,使用者在訪問時,可以從距離自己最近的網路提供商機房獲取資料;反向代理是部署在網站自己的中心機房,當用戶請求到達機房時,優先訪問的伺服器是反向代理伺服器,如果反向代理中快取了使用者請求的資源,那麼就直接返回給使用者,加快了響應的速度,也減輕了後端負載的壓力。

分散式檔案系統和分散式資料庫系統階段:當讀寫分離之後如果還不能滿足網站的需求,那就只能考慮最後的手段了:分散式資料庫,網站常用的資料庫拆分手段是業務分庫,將不同的業務資料庫部署在不同的物理機上

NoSQL和搜尋引擎階段:隨著網站業務越來越複雜,對資料的檢索和儲存的需求也越來越複雜,網站需要採用一些非關係型資料庫(NoSQL)和非資料庫查詢(搜尋引擎)技術。

業務拆分階段:分而治之思想,將整個網站業務劃分為不同的產品線,根據不同的產品線劃分將網站拆成不同的應用,每個應用獨立部署維護如一個電商網站可以分為:首頁,訂單,商品,活動,優惠卷,個人中心,購物車等等多個應用,應用之間可以通過訊息佇列來傳遞資料。

分散式服務階段:隨著業務複雜度提升,我們會發現很多系統之間有著共同的業務,我們可以把這部分業務抽取出來,做成一個共通的基礎服務。

...

三、資料交換系統部分設計思路探索

1)前後端分離系統?面臨的問題以及解決方案

對接?文件?部署?

1.一般來說,要實現前後端分離,前端就需要開啟一個本地的伺服器來執行自己的前端程式碼,以此來模擬真實的線上環境,並且,也是為了更好的開發。因為你在實際開發中,你不可能要求每一個前端都去搭建一個java環境(之前有過類似專案),並且在java環境下開發,這對於前端來說,學習成本太高了。但如果本地沒有開啟伺服器的話,不僅無法模擬線上的環境,而且還面臨到了跨域的問題,因為你如果寫靜態的html頁面,直接在檔案目錄下開啟的話,你是無法發出ajax請求的(瀏覽器跨域的限制),因此,你需要在本地執行一個伺服器,可是又不想搭建陌生而龐大的java環境,怎麼辦法呢?nodejs正好解決了這個問題。在我們專案中,我們利用nodejs的express框架來開啟一個本地的伺服器,然後利用nodejs的一個http-proxy-middleware外掛將客戶端發往nodejs的請求轉發給真正的伺服器,讓nodejs作為一箇中間層。這樣,前端就可以無憂無慮的開發了

2.由於前後端分離後,前端和後臺同時開發時,就可能遇到前端已經開發好一個頁面了,可是卻等待後臺API介面的情況。比如說A是負責前端,B是負責後臺,A可能用了一週做好了基本的結構,並且需要API介面聯調後,才能繼續開發,而此時B卻還沒有實現好所需要的介面,這種情況,怎麼辦呢?在我們這個專案裡,我們是通過了mock來提供一些假資料,我們先規定好了API介面,設計出了一套API文件,然後我們就可以通過API文件,利用mock(http://mockjs.com)來返回一些假資料,這樣就可以模擬傳送API到接受響應的整一個過程,因此前端也不需要依賴於後端開發了,可以獨立開發,等到後臺的API全部設計完之後,就可以比較快速的聯調。

初期解決方案

對接:

後端開發人員必須介面測試通過方可與前端對接,否則是耽誤雙方時間

後端開發人員釋出consumer對接以後對接是消費者(consumer)

...

文件:

初期採用swgger2作為對接介面文件,消費者的介面統一加註釋

後端部分開發註釋

   其它型別註解:

啟動後前端訪問地址訪問 http://localhost:8002/swagger-ui.html

測試

前端部署方式:

採用打包成靜態檔案-->tomcat中

 

API文件規劃:

現有方案:1.程式碼有侵入性 2.介面改變 通知前端不及時3 依賴第三方外掛 4無歷史呼叫情況

 

方案升級版:融合現有API介面註冊方案,形成文件。

解決 後端程式碼侵入性 、依賴第三方外掛、無歷史訂單情況

而且可以自動化測試,可以檢視介面呼叫引數的預設引數。

缺點:需要手動註冊?(日誌模組->自動化註冊)

介面發生變化及時通知前端(訊息模組&自動測試模組)

 

2)交換系統Session問題&登陸邏輯

1、Session Sticky。session sticky就是把同一個使用者在某一個會話中的請求,都分配到固定的某一臺伺服器中,這樣我們就不需要解決跨伺服器的session問題了,常見的演算法有ip_hash法。

優點:實現簡單。

缺點:應用伺服器重啟則session消失。

2、Session Replication。session replication就是在叢集中複製session,使得每個伺服器都儲存有全部使用者的session資料。

優點:減輕負載均衡伺服器的壓力,不需要要實現ip_hasp演算法來轉發請求。

缺點:複製時寬頻開銷大,訪問量大的話session佔用記憶體大且浪費。

3、Session資料集中儲存:session資料集中儲存就是利用資料庫來儲存session資料,實現了session和應用伺服器的解耦。

優點:相比session replication的方案,叢集間對於寬頻和記憶體的壓力減少了很多。

缺點:需要維護儲存session的資料庫。

4、Cookie Base:cookie base就是把session存在cookie中,有瀏覽器來告訴應用伺服器我的session是什麼,同樣實現了session和應用伺服器的解耦。

優點:實現簡單,基本免維護。

缺點:cookie長度限制,安全性低,寬頻消耗。

 

5.資料交換系統採用的方式

 

什麼是JWT

根據維基百科的定義,JSON WEB Token(JWT,讀作 [/dʒɒt/]),是一種基於JSON的、用於在網路上宣告某種主張的令牌(token)。JWT通常由三部分組成: 頭資訊(header), 訊息體(payload)和簽名(signature)

JWT訊息構成

一個token分3部分,按順序為

頭部(header)

其為載荷(payload)

簽證(signature)

由三部分生成token

3部分之間用“.”號做分隔。例如

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

 

 

  1. 針對不同客戶的部署的架構模組設計?

如何給客戶快速部署?如何部署精簡版本(單機版部分模組單機版、外掛的可裝載性)?如何規劃去中心化(消費者職責)?

  1. 中介軟體升級

1)路由(Zuul 1.x--> spring cloud gateway):功能和效能上有明顯的提升

2)註冊中心Eureka-->(consul):consul是一個分散式高可用的服務網格(service mesh)解決方案,提供了服務發現、配置和分段功能在內的全功能控制平面。

3)Springboot 1.X- springboot2.x

5.其他

自動化部署

Jenkins+docker+批處理+kubernetes(k8s )

https://www.kubernetes.org.cn/doc-11