高併發高可、O2O、微服務架構用學習網站 https://www.itkc8.comhtml
很是感謝http://www.cnblogs.com/skyblog/p/5044486.html前端
關於架構,筆者認爲並非越複雜越好,而是相反,簡單就是硬道理也提如今這裏。這也是微服務可以流行的緣由,看看市場上曾經出現的服務架構:EJB、SCA、Dubbo等等,都比微服務先進,都比微服務功能完善,但它們都沒有微服務這麼深刻民心,就是由於他們過於複雜。簡單就是高科技,蘋果手機聽說專門有個團隊研究如何能讓用戶更加簡單的操做。大公司都是由小公司發展起來的,若是小公司在開始技術選型時感受某個框架費時費力就不會選擇,而小公司發展到大公司的過程,通常也伴隨着系統不斷優化的過程,而不斷優化每每不會從新選擇開發技術和框架,而是在原來基礎改進,這也許就是簡單框架流行的本質。 nginx
假設咱們須要爲超高業務量的保險代理企業設計一個「互聯網+」保險平臺。假設這家保險代理企業網上保險註冊用戶規模爲2千萬,門店及加盟商銷售人員2萬,年保單量2億單(中國平安總用戶規模達1.67億,擁有超過79.8萬名壽險銷售人員和約24.6萬名正式僱員。截至2015年6月30日,集團總資產達4.63萬億元,歸屬母公司股東權益爲3,311.90億元。而目前互聯網保險領頭羊衆安保險,經營以小額貸款爲主,因爲背靠阿里巴巴,日保單銷售量可達1億,不過別人很難複製衆安保險的模式)。所以咱們取大型互聯網企業和衆安保險的折衷來考慮這個保險O2O平臺。web
參考保險業務相關文檔(文檔不全),得到以下核心需求矩陣(由於涉及功能太多,只取大的功能點)。redis
分類spring |
功能數據庫 |
質量api |
約束緩存 |
電子商務(B2C)安全 |
產品展現(搜索、詳情展現等) |
及時響應、安全性、健壯性、易用性 |
多種險種,處理方式可能不一樣 |
|
產品購買(提交訂單、支付) |
及時響應、安全性、健壯性、易用性 |
多種險種,處理方式可能不一樣 |
|
用戶中心(個人保單、個人理賠等) |
及時響應、安全性、健壯性、易用性 |
多種險種,處理方式可能不一樣 |
代理人管理(加盟商管理) |
車險投保(詢價、錄單、繳費) |
及時響應、健壯性、可擴展性 |
多種險種,處理方式可能不一樣 |
|
非車險投保(詢價、錄單、繳費) |
及時響應、健壯性、可擴展性 |
多種險種,處理方式可能不一樣 |
|
保單查詢 |
及時響應、健壯性、可擴展性 |
|
|
單證管理 |
及時響應、健壯性、可擴展性 |
|
|
個人帳戶(個人保單、佣金結算等) |
及時響應、安全性、可靠性、易用性 |
多種險種,處理方式可能不一樣 |
案卷管理 |
案卷錄入 |
及時響應、健壯性、可擴展性 |
多種險種,處理方式可能不一樣 |
|
索賠資料收取 |
及時響應、健壯性、可擴展性 |
|
|
案卷交接 |
及時響應、健壯性、可擴展性 |
|
|
案卷跟蹤 |
及時響應、健壯性、可擴展性 |
|
客戶管理 |
客戶信息維護 |
及時響應、健壯性、可擴展性 |
上傳大量文件 |
|
客戶活動管理 |
及時響應、健壯性、可擴展性 |
|
|
商機管理 |
及時響應、健壯性、可擴展性 |
|
|
個人工做臺(消息、活動、商機) |
及時響應、健壯性、可擴展性 |
|
保險公估 |
車險定損過程跟蹤協助 |
及時響應、健壯性、可擴展性 |
多種險種,處理方式可能不一樣 |
|
人傷出險協助 |
及時響應、健壯性、可擴展性 |
多種險種,處理方式可能不一樣 |
|
法律援助服務 |
及時響應、健壯性、可擴展性 |
多種險種,處理方式可能不一樣 |
從O2O的概念來看:「O2O即Online To Offline,也即將線下商務的機會與互聯網結合在了一塊兒,讓互聯網成爲線下交易的前臺。這樣線下服務就能夠用線上來攬客,消費者能夠用線上來篩選服務,還有成交能夠在線結算,很快達到規模。該模式最重要的特色是:推廣效果可查,每筆交易可跟蹤(百度百科)」,不是每一種服務都適合O2O。商品類的銷售不適合O2O,由於你直接從網店就能夠購買根本不須要線下店。但保險類服務的確須要線下和線上結合,若是是純線上將不能知足客戶的服務需求。O2O的線下服務能夠是加盟商、代理人,也能夠是直營店。
上面的需求是按照用戶角度提出的,雖然使用「系統」一詞,但這裏的系統是一個抽象概念,可能包括軟件系統以及人事、制度等在內。上面的需求能夠分爲三大類,一類是針對終端用戶純線上服務:電子商務網站(B2C);一類是專門針對代理人服務的:代理人系統;剩下的是一些公共服務,有可能電子商務網站和代理人系統都會用到的一些服務。另外保險業務最大的一個問題是多個險種,不一樣險種處理方式有很大不一樣,這跟普通電子商務網站區別很大,好比天貓,全部商品都是一樣的下單方式,一樣售後服務(主要就是快遞這塊),而保險產品即便是線上B2C網站下單操做,短險、壽險、車險等也是不一樣的,更況且保險有一大堆售後服務,這些售後服務更加不相同。傳統保險公司在處理這方面時,通常會作多個系統,好比壽險系統,車險系統等等。
安裝以前提到的業務規模咱們分析(假設)出一些比較重要的性能需求:
a)產品方面:繼續上線當前沒有的保險產品
b)B2C網站日訪問量:5000萬PV
c)B2C產品購買併發高峯:2000 TPS
d)運維繫統同時在線:1萬(共有2萬銷售員或代理人)
e)運維繫統併發高峯:2000 TPS
f)短險訂單:每一年1.85億單
g)長險訂單:每一年500萬
h)車險訂單:每一年1000萬
i)案卷信息:每一年新增100萬單
日訪問量5000萬和產品併發2000 TPS是咱們假設的,客戶信息和案卷信息是隨訂單數據量變化而變化,在前面咱們雖然假設了總共每一年產生2億個訂單,可是根據保險種類,短險(旅遊險、傷殘險)明顯產生了90%的訂單量,這一點須要特殊處理。除此以外車險和長險(主要指壽險等)不管是投保仍是售後服務都有明顯不一樣,因此也須要特殊處理。
那麼咱們按照上面的需求,進行系統分析,首先按大的職責將職責相同的劃分爲一個服務。而且有了上面這個性能需求,全部功能需求都須要增長一項「質量」特性,那就是「高併發」,高併發會影響到全部設計。另外若是要將互聯網保險平臺質量特性排個序,最重要的是可擴展性、安全性,由於保險的種類多並且處理方式不一樣,除此以外,高併發和可靠性也會直接影響功能的實現,但並無可擴展性影響大。深刻分析職責後把每一種功能的實現關鍵技術列出,以下:
需求分類 |
實現需求 |
實現子系統及服務 |
軟硬件實現技術 |
客戶端 |
B2C電子商務網站 |
B2C Web客戶端 |
集羣部署、高速緩存、分佈式緩存、搜索引擎技術、靜態化 |
B2C電子商務網站手機客戶端 |
B2C App客戶端 |
|
|
代理人管理 |
代理人Web客戶端 |
集羣部署、高速緩存、分佈式緩存、搜索引擎技術、靜態化 |
|
代理人管理手機客戶端 |
代理人App客戶端 |
|
|
案卷處理管理 |
案卷處理Web客戶端 |
集羣部署、分佈式緩存 |
|
客戶管理管理 |
客戶管理Web客戶端 |
集羣部署、分佈式緩存 |
|
保險公估管理 |
保險公估Web客戶端 |
集羣部署、分佈式緩存 |
|
運維產品管理 |
產品管理Web客戶端 |
集羣部署、分佈式緩存 |
|
報表及財務統計 |
報表及財務統計Web客戶端 |
集羣部署、分佈式緩存 |
|
公共服務 |
運維產品管理、Web前端產品訪問 |
產品服務 |
集羣部署、分佈式緩存 |
電子商務或代理人訂單管理 |
訂單服務 |
集羣部署、分佈式緩存 |
|
電子商務或代理人等涉及財務操做 |
總帳服務 |
集羣部署、分佈式緩存 |
|
報表及財務統計 |
報表服務 |
集羣部署、分佈式緩存 |
|
業務服務 |
B2C電子商務網站及手機客戶端我的帳戶 |
B2C我的帳戶服務 |
集羣部署、分佈式緩存 |
代理人管理 |
代理人管理服務 |
集羣部署、分佈式緩存 |
|
案卷處理管理 |
案卷處理管理服務 |
集羣部署、分佈式緩存 |
|
客戶管理 |
客戶管理服務 |
集羣部署、分佈式緩存 |
|
保險公估管理 |
保險公估管理服務 |
集羣部署、分佈式緩存 |
|
短險開放式接入 |
開放式接入平臺服務 |
集羣部署、分佈式緩存 |
|
工具性服務 |
保險公司產品對接 |
產品對接服務 |
集羣部署、消息隊列 |
在線支付 |
第三方支付服務 |
集羣部署 |
|
短信郵件通知 |
通知服務 |
集羣部署、消息隊列 |
|
性能監控 |
日誌採集服務 |
集羣部署、消息隊列 |
|
文件服務器 |
文件服務 |
集羣部署、消息隊列 |
|
服務受權與審計 |
服務受權與審計服務 |
集羣部署 |
|
分佈式事務管理 |
分佈式事務管理服務 |
集羣部署 |
|
定時任務管理 |
定時任務服務 |
集羣部署 |
各個子系統及模塊的關係以下圖。
其中訂單服務、產品服務、財務服務、工具服務爲基礎服務,其它各個業務模塊的服務會調用這些基礎服務。各個業務模塊的服務都是根據業務領域進行劃分的,同一業務領域下實現技術不一樣會被劃分爲兩個服務,好比產品展現和訂單本來屬於同一個大的領域,但其由於實現技術和質量要求不一樣須要劃分爲兩個服務。由於短險接入量大,並且大部分是跟第三方合做接入,所以設計短險接入公共接口服務平臺處理大量短險訂單。
對於大型的高併發系統來說,最重要的當屬數據的架構。咱們在前面也提到過,web系統業務處理模塊自己就能夠集羣部署,當用戶出現高併發時最早遇到的瓶頸就是數據庫訪問的瓶頸。這也是咱們說數據架構最爲重要的緣由。其實web系統是典型的「計算機信息系統」,也就是說一切以數據(信息)爲基礎,全部的功能都是圍繞着數據來的。這也是咱們在這裏說數據是web系統最重要的,不少公司在作少用戶量web系統時直接設計好數據庫就能夠開發了。
按照上面劃分的業務領域咱們設計多個數據庫,技術選項包括「是否讀寫分離」、「是否水平切分」及「路由鍵」。其中路由鍵是指在進行水平切分後,咱們使用那個「標識」去查詢數據庫,通常來講會使用該業務領域聚合根對象的主鍵做爲路由鍵。
數據庫 |
是否讀寫分離 |
是否水平切分 |
水平切分路由鍵 |
產品數據庫 |
是 |
|
|
訂單數據庫 |
|
是 |
客戶ID |
公共數據庫(元數據、公共數據) |
是 |
|
|
客戶管理數據庫 |
|
是 |
客戶ID |
案卷管理數據庫 |
|
是 |
客戶ID |
代理人服務數據庫 |
|
是 |
代理人ID |
B2C電子商務我的帳戶數據庫 |
|
是 |
客戶ID |
保險公估數據庫 |
|
是 |
客戶ID |
工具數據庫(短信、支付、文件) |
|
是 |
客戶ID |
報表數據庫 |
是 |
|
|
日誌採集服務數據庫 |
|
是 |
日誌ID |
除工具數據庫外,其它的數據庫的劃分很容易理解。工具數據庫的數據也大都跟客戶或說用戶有關,好比「產品對接服務」,產品對接服務是指用戶在購買了保單後,系統會自動對接到具體的保險公司接口去上傳保單信息和下載保單,因此水平切分數據庫時能夠採用用戶ID做爲路由鍵。「在線支付」和「通知服務」也是相似,都是保存用戶相關的數據,在線支付服務保存的是用戶在線支付的流水,通知服務保存的是發送給某用戶的短信或郵件。
另外在數據架構中咱們也能夠看到一個規律,就是使用了水平分庫的存儲結構就不能再使用讀寫分離,緣由是防止存儲單元過分氾濫,由於使用了水平分庫以後,自己也要爲數據庫創建多個備份庫,這個時候若是再用讀寫分離須要創建一套只讀庫,數據庫的數量將增長一倍。使用了分庫後咱們能夠把熱點數據存儲在分佈式緩存中以起到讀寫分離相似的做用。
另外緩存也是存儲技術的一種,並且很是重要。從平常生活中咱們也能夠看到這一點。好比你要去購買一臺電腦,你會發現二級緩存和內存大的價格高出不少,若是你的顯卡顯存巨大,那將是頂級配置,發燒級配置。手機也是同樣,內存大的手機速度明顯快,價格也高,若是內存和持久化存儲都高,那也是頂級配置。對於web系統也是同樣,有些大型web系統只要緩存處理的好,數據庫不須要分庫就能夠承載億級的用戶,好比維基百科、新浪微博等。也所以,無論是電子商務網站仍是互聯網+大型應用,都會在它們的架構中看到緩存大量使用的狀況。
從整個web系統的架構來看,緩存在兩個層面大量使用,分別是展現層和邏輯層,展現層一般使用高速的頁面緩存,邏輯層一般使用高併發的分佈式緩存。固然有些分佈式緩存工具既能夠在邏輯層使用也能夠在顯示層使用。
系統 |
是否使用CDN |
是否使用高速緩存服務器(varnish) |
是否使用分佈式緩存(redis) |
B2C電子商務網站 |
是 |
是 |
|
報表及財務統計Web端 |
|
是 |
|
B2C我的帳戶服務 |
|
|
是 |
代理人管理服務 |
|
|
是 |
案卷處理管理服務 |
|
|
是 |
客戶管理服務 |
|
|
是 |
保險公估管理服務 |
|
|
是 |
B2C我的帳戶服務 |
|
|
是 |
短險公共平臺服務 |
|
|
是 |
在給出系統整體的邏輯架構前,咱們先看看系統前端和服務層直接的關係。前端是客戶端,能夠有多個客戶端,也能夠有多種客戶端,好比手機端(APP、WAP、微信)等。客戶端和服務之間的架構是典型的MVC架構,V是客戶端,C就是spring mvc或servlet開發的控制層,對於Web應用V和C在開發角度是一個工程,剩下的M就是服務層。這是對於web系統來講的,對於app或者使用html直接實現的客戶端,或者是.net實現的桌面客戶端,因爲這些客戶端是單獨開發的,沒有控制層,所以須要增長一層「API 網關」做爲這些客戶端的控制層。
圖中的服務組件就是指各個業務服務,這些服務能夠當作是組件的概念。一般前端界面一個界面中須要的數據一般不只僅來自於同一個服務,即便是來自於同一個服務,那也來自於不少不一樣的接口,servlet或api 網關做爲控制層,所起到的做用就是組合接口、組合數據,並處理接口間的事務性。另外服務組件也是分層的,圖中並無展示,通常能夠分爲3層,從低到高依次是工具性服務組件、基礎業務層服務組件、業務層服務組件。前端界面的請求按照從高到底向下傳遞和處理請求。
按照職責、通用性、技術特性綜合考慮和計量,邏輯架構設計以下圖:
十幾個子系統分別分佈在服務層、控制層、表現層(典型的三層架構)。實體層和接口訪問層雖然屬於「層」,但它們並不單獨發佈,而是使用Jar包類庫的方式提供給其它服務調用,是邏輯上的層。服務組件的構成大都是按照業務領域劃分的,只有一個除外,就是「B2C網站」,B2C網站因爲是面向終端用戶的高併發電子商務網站,爲了處理高併發,咱們將其拆分爲兩個業務領域(也能夠拆分紅多個業務領域,看實際併發量),分別是用戶帳戶和產品。用戶瀏覽產品併購買,這是電子商務網站最基本的兩個領域。其中產品瀏覽等功能由更底層的產品服務提供,用戶帳戶功能由會員服務提供。還有一些功能,好比推薦商品多是由其它服務提供,這些能夠在控制層直接組合這些服務。
服務框架採用典型的「服務註冊表」模式,註冊表使用redis。服務組件在啓動時將本身註冊進服務註冊表,web服務器或api 網關在訪問服務時查詢服務註冊表獲得服務的uri,而後調用某服務接口。
淘寶的dubbo使用的是zookeeper做爲服務註冊表,之因此使用zookeeper,主要是使用它的負載均衡的功能。筆者認爲restful接口沒有必要使用zookeeper作負載均衡,可使用nginx(負載均衡服務器均可以),因此不必選用動態的zookeeper做爲註冊表,而是使用「redis+心跳監測」機制(redis也能夠換爲LDAP等)來完成服務註冊和監控失效服務的功能。這個方案至少比dubbo簡單幾個數量級,簡單就是硬道理。
在註冊服務時只須要註冊nginx服務器的IP以及服務描述信息便可。反觀dubbo還要註冊接口進註冊表,筆者認爲這個不必,由於調用一個服務接口的充分必要條件就是知道服務器的IP便可。至於調用什麼服務接口,確定在代碼裏已經寫死,目標服務器一定存在這個服務接口。將服務接口註冊進服務註冊表若是是爲了監控審計服務的使用狀況,那這個功能使用訪問日誌來實現能作的更好。
整體的分佈式拓補結構以下圖:
對於服務集羣來說,看上去像是一個大哥(nginx)帶有衆多小弟的結構。訪問某服務羣組只須要訪問其nginx服務器便可,這裏nginx均採用高可用方案,防止單臺nginx出現問題。至於高層服務調用底層服務也是直接訪問其服務器組的nginx。這個執行的流程其實和平常生活中的概念很像,如公司內部的執行流也是如此:老闆分配任務給部門經理,部門經理分配任務給主管,主管分配任務給具體的我的(某單臺服務器)。領導們起到的做用也是負載均衡和監控,負載均衡就是把任務能夠分配給多我的同時執行(而且某個執行失敗自動切換),監控就沒必要說了就是監控任務完成狀況。在咱們的方案裏,會專門有個服務去監控全部服務器的執行狀況,很簡單的服務就能夠作到。
若是研究一下EJB就會發現,EJB和微服務的架構基本相同,甚至全部面向服務(SCA、SOA等等)的架構都相差不大。不少人反對EJB,並非EJB不夠強大,而是它不夠簡單,它給項目帶來的複雜性甚至超過了項目自己(這也是筆者不建議使用dubbo框架的緣由)。曾有人說過:你要麼把事情作的儘量簡單,讓人挑不出毛病;要麼把事情作的儘量複雜,讓人找不出毛病,EJB就是後者。EJB分佈式事務機制實現的很好,惋惜的是這種「一刀切」的事務機制,大大下降了web系統的性能,因此幾乎全部面向互聯網的應用都極少使用分佈式事務,也就不會採用EJB。互聯網應用自己事務性操做並很少,一些新聞、博客之類的網站甚至都不須要事務。另一個方面,即便出現一個或兩個分佈式事務應用場景,也能夠經過其它手段解決,好比事件機制等等。
在以前的文章中咱們也提到過對於分佈式事務最佳的策略是儘可能避免。若是避免不了將按如下方式實現。
1) 將分佈式事務性操做封裝在一個服務中,這個服務使用XA或鏈式分佈式事務管理。
2) 可使用事件機制協調事務管理(具體作法就是事務失敗後發失敗事件到可持久化的消息隊列,而後需回滾操做的接口監控此事件並執行回滾)。
3) 使用自定義分佈式事務管理器管理分佈式事務。
筆者設想的自定義分佈式事務管理器主要是封裝了流程及分佈式事務相關功能,筆者將在其它文章專門討論。如圖所示,假設有一個事務須要依次調用ABCDE五個接口,咱們首先調用分佈式事務管理接口建立這條「流程」的實例,實例中五個接口分別對應五個狀態,調用成功後將該接口對應的狀態設置爲「成功」,反之就是「失敗」,流程處理結束後,分佈式事務檢查狀態,而後按照必定的策略調用失敗接口的反向操做接口去回滾數據(前提條件也是參與分佈式事務操做的接口要開發反向操做接口)。這既是一個簡單的流程引擎,也是一個分佈式事務協調處理裝置,具體是否有必要作的複雜(好比處理並行流程),還要看實際環境下分佈式事務的狀況,但筆者認爲互聯網前端應用使用簡單流程應該足以應付。
系統所需的工程,「[ ]」裏面表示工程的名稱。
從圖中不難看出,咱們將運維相關前端界面合併爲一個前端系統,整體來說前端只有3種,B2C前端、APP前端、運維前端。把運維前端合併爲一個項目有利於加快前期的開發、部署的效率,在後期若是某子系統功能界面太多,能夠將前端系統獨立,好比公估系統、客戶管理系統等,獨立後的系統須要使用單點登陸,這樣就能夠在各個系統之間免登錄切換。
開發環境:
編碼:UTF-8
工具:Myeclipse 10
SVN:Site-1.8.22
Web服務器:Tomcat7
JDK: JDK1.七、 Java EE 5
開發環境:Maven 3
高併發高可、O2O、微服務架構用學習網站 https://www.itkc8.com
開發技術選型:
表現層:Bootstrap+Html+Jquery
MVC框架:Spring MVC 3.2
安全框架:Spring security 3.2
Rest接口實現:Spring boot
持久層:Mybatis3.2
分佈式緩存:Redis
數據庫:MySql 5.6