關於架構,筆者認為並不是越複雜越好,而是相反,簡單就是硬道理也提現在這裡。這也是微服務能夠流行的原因,看看市場上曾經出現的服務架構:EJB、SCA、Dubbo等等,都比微服務先進,都比微服務功能完善,但它們都沒有微服務這麼深入民心,就是因為他們過於複雜。簡單就是高科技,蘋果手機據說專門有個團隊研究如何能讓使用者更加簡單的操作。大公司都是由小公司發展起來的,如果小公司在開始技術選型時感覺某個框架費時費力就不會選擇,而小公司發展到大公司的過程,一般也伴隨著系統不斷優化的過程,而不斷優化往往不會重新選擇開發技術和框架,而是在原來基礎改進,這也許就是簡單框架流行的本質。 

  假設我們需要為超高業務量的保險代理企業設計一個“網際網路+”保險平臺。假設這家保險代理企業網上保險註冊使用者規模為2千萬,門店及加盟商銷售人員2萬,年保單量2億單(中國平安總使用者規模達1.67億,擁有超過79.8萬名壽險銷售人員和約24.6萬名正式僱員。截至2015年6月30日,集團總資產達4.63萬億元,歸屬母公司股東權益為3,311.90億元。而目前網際網路保險領頭羊眾安保險,經營以小額貸款為主,由於背靠阿里巴巴,日保單銷售量可達1億,不過別人很難複製眾安保險的模式)。因此我們取大型網際網路企業和眾安保險的折衷來考慮這個保險O2O平臺。

l 需求分析

參考保險業務相關文件(文件不全),獲得如下核心需求矩陣(因為涉及功能太多,只取大的功能點)。

分類

功能

質量

約束

電子商務(B2C)

產品展示(搜尋、詳情展示等)

及時響應、安全性、健壯性、易用性

多種險種,處理方式可能不同

產品購買(提交訂單、支付)

及時響應、安全性、健壯性、易用性

多種險種,處理方式可能不同

使用者中心(我的保單、我的理賠等)

及時響應、安全性、健壯性、易用性

多種險種,處理方式可能不同

代理人管理(加盟商管理)

車險投保(詢價、錄單、繳費)

及時響應、健壯性、可擴充套件性

多種險種,處理方式可能不同

非車險投保(詢價、錄單、繳費)

及時響應、健壯性、可擴充套件性

多種險種,處理方式可能不同

保單查詢

及時響應、健壯性、可擴充套件性

單證管理

及時響應、健壯性、可擴充套件性

我的賬戶(我的保單、佣金結算等)

及時響應、安全性、可靠性、易用性

多種險種,處理方式可能不同

案卷管理

案卷錄入

及時響應、健壯性、可擴充套件性

多種險種,處理方式可能不同

索賠資料收取

及時響應、健壯性、可擴充套件性

案卷交接

及時響應、健壯性、可擴充套件性

案卷跟蹤

及時響應、健壯性、可擴充套件性

客戶管理

客戶資訊維護

及時響應、健壯性、可擴充套件性

上傳大量檔案

客戶活動管理

及時響應、健壯性、可擴充套件性

商機管理

及時響應、健壯性、可擴充套件性

我的工作臺(訊息、活動、商機)

及時響應、健壯性、可擴充套件性

保險公估

車險定損過程跟蹤協助

及時響應、健壯性、可擴充套件性

多種險種,處理方式可能不同

人傷出險協助

及時響應、健壯性、可擴充套件性

多種險種,處理方式可能不同

法律援助服務

及時響應、健壯性、可擴充套件性

多種險種,處理方式可能不同

  從O2O的概念來看:“O2O即Online To Offline,也即將線下商務的機會與網際網路結合在了一起,讓網際網路成為線下交易的前臺。這樣線下服務就可以用線上來攬客,消費者可以用線上來篩選服務,還有成交可以線上結算,很快達到規模。該模式最重要的特點是:推廣效果可查,每筆交易可跟蹤(百度百科)”,不是每一種服務都適合O2O。商品類的銷售不適合O2O,因為你直接從網店就可以購買根本不需要線下店。但保險類服務的確需要線下和線上結合,如果是純線上將不能滿足客戶的服務需求。O2O的線下服務可以是加盟商、代理人,也可以是直營店。

  上面的需求是按照使用者角度提出的,雖然使用“系統”一詞,但這裡的系統是一個抽象概念,可能包括軟體系統以及人事、制度等在內。上面的需求可以分為三大類,一類是針對終端使用者純線上服務:電子商務網站(B2C);一類是專門針對代理人服務的:代理人系統;剩下的是一些公共服務,有可能電子商務網站和代理人系統都會用到的一些服務。另外保險業務最大的一個問題是多個險種,不同險種處理方式有很大不同,這跟普通電子商務網站區別很大,比如天貓,所有商品都是同樣的下單方式,同樣售後服務(主要就是快遞這塊),而保險產品即使是線上B2C網站下單操作,短險、壽險、車險等也是不同的,更何況保險有一大堆售後服務,這些售後服務更加不相同。傳統保險公司在處理這方面時,一般會做多個系統,比如壽險系統,車險系統等等。

l 系統分析

  安裝之前提到的業務規模我們分析(假設)出一些比較重要的效能需求:

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個人賬戶服務

叢集部署、分散式快取

代理人管理

代理人管理服務

叢集部署、分散式快取

案卷處理管理

案卷處理管理服務

叢集部署、分散式快取

客戶管理

客戶管理服務

叢集部署、分散式快取

保險公估管理

保險公估管理服務

叢集部署、分散式快取

短險開放式接入

開放式接入平臺服務

叢集部署、分散式快取

工具性服務

保險公司產品對接

產品對接服務

叢集部署、訊息佇列

線上支付

第三方支付服務

叢集部署

簡訊郵件通知

通知服務

叢集部署、訊息佇列

效能監控

日誌採集服務

叢集部署、訊息佇列

檔案伺服器

檔案服務

叢集部署、訊息佇列

服務授權與審計

服務授權與審計服務

叢集部署

分散式事務管理

分散式事務管理服務

叢集部署

定時任務管理

定時任務服務

叢集部署

       各個子系統及模組的關係如下圖。

   

       其中訂單服務、產品服務、財務服務、工具服務為基礎服務,其它各個業務模組的服務會呼叫這些基礎服務。各個業務模組的服務都是根據業務領域進行劃分的,同一業務領域下實現技術不同會被劃分為兩個服務,比如產品展示和訂單原本屬於同一個大的領域,但其因為實現技術和質量要求不同需要劃分為兩個服務。因為短險接入量大,而且大部分是跟第三方合作接入,因此設計短險接入公共介面服務平臺處理大量短險訂單。

l 儲存及快取架構

  對於大型的高併發系統來講,最重要的當屬資料的架構。我們在前面也提到過,web系統業務處理模組本身就可以叢集部署,當用戶出現高併發時最先遇到的瓶頸就是資料庫訪問的瓶頸。這也是我們說資料架構最為重要的原因。其實web系統是典型的“計算機資訊系統”,也就是說一切以資料(資訊)為基礎,所有的功能都是圍繞著資料來的。這也是我們在這裡說資料是web系統最重要的,很多公司在做少使用者量web系統時直接設計好資料庫就可以開發了。

  按照上面劃分的業務領域我們設計多個數據庫,技術選項包括“是否讀寫分離”、“是否水平切分”及“路由鍵”。其中路由鍵是指在進行水平切分後,我們使用那個“標識”去查詢資料庫,一般來說會使用該業務領域聚合根物件的主鍵作為路由鍵。

資料庫

是否讀寫分離

是否水平切分

水平切分路由鍵

產品資料庫

訂單資料庫

客戶ID

公共資料庫(元資料、公共資料)

客戶管理資料庫

客戶ID

案卷管理資料庫

客戶ID

代理人服務資料庫

代理人ID

B2C電子商務個人賬戶資料庫

客戶ID

保險公估資料庫

客戶ID

工具資料庫(簡訊、支付、檔案)

客戶ID

報表資料庫

日誌採集服務資料庫

日誌ID

       除工具資料庫外,其它的資料庫的劃分很容易理解。工具資料庫的資料也大都跟客戶或說使用者有關,比如“產品對接服務”,產品對接服務是指使用者在購買了保單後,系統會自動對接到具體的保險公司介面去上傳保單資訊和下載保單,所以水平切分資料庫時可以採用使用者ID作為路由鍵。“線上支付”和“通知服務”也是類似,都是儲存使用者相關的資料,線上支付服務儲存的是使用者線上支付的流水,通知服務儲存的是傳送給某使用者的簡訊或郵件。

       另外在資料架構中我們也可以看到一個規律,就是使用了水平分庫的儲存結構就不能再使用讀寫分離,原因是防止儲存單元過度氾濫,因為使用了水平分庫之後,本身也要為資料庫建立多個備份庫,這個時候如果再用讀寫分離需要建立一套只讀庫,資料庫的數量將增加一倍。使用了分庫後我們可以把熱點資料儲存在分散式快取中以起到讀寫分離類似的作用。

另外快取也是儲存技術的一種,而且非常重要。從日常生活中我們也可以看到這一點。比如你要去購買一臺電腦,你會發現二級快取和記憶體大的價格高出很多,如果你的顯示卡視訊記憶體巨大,那將是頂級配置,發燒級配置。手機也是一樣,記憶體大的手機速度明顯快,價格也高,如果記憶體和持久化儲存都高,那也是頂級配置。對於web系統也是一樣,有些大型web系統只要快取處理的好,資料庫不需要分庫就可以承載億級的使用者,比如維基百科、新浪微博等。也因此,不管是電子商務網站還是網際網路+大型應用,都會在它們的架構中看到快取大量使用的情況。

從整個web系統的架構來看,快取在兩個層面大量使用,分別是展示層和邏輯層,展示層通常使用高速的頁面快取,邏輯層通常使用高併發的分散式快取。當然有些分散式快取工具既可以在邏輯層使用也可以在顯示層使用。

系統

是否使用CDN

是否使用快取記憶體伺服器(varnish)

是否使用分散式快取(redis)

B2C電子商務網站

報表及財務統計Web端

B2C個人賬戶服務

代理人管理服務

案卷處理管理服務

客戶管理服務

保險公估管理服務

B2C個人賬戶服務

短險公共平臺服務

l 邏輯架構

  在給出系統總體的邏輯架構前,我們先看看系統前端和服務層直接的關係。前端是客戶端,可以有多個客戶端,也可以有多種客戶端,比如手機端(APP、WAP、微信)等。客戶端和服務之間的架構是典型的MVC架構,V是客戶端,C就是spring mvc或servlet開發的控制層,對於Web應用V和C在開發角度是一個工程,剩下的M就是服務層。這是對於web系統來說的,對於app或者使用html直接實現的客戶端,或者是.net實現的桌面客戶端,由於這些客戶端是單獨開發的,沒有控制層,因此需要增加一層“API 閘道器”作為這些客戶端的控制層。

   

圖中的服務元件就是指各個業務服務,這些服務可以看成是元件的概念。通常前端介面一個介面中需要的資料通常不僅僅來自於同一個服務,即使是來自於同一個服務,那也來自於很多不同的介面,servlet或api 閘道器作為控制層,所起到的作用就是組合介面、組合資料,並處理介面間的事務性。另外服務元件也是分層的,圖中並沒有展現,一般可以分為3層,從低到高依次是工具性服務元件、基礎業務層服務元件、業務層服務元件。前端介面的請求按照從高到底向下傳遞和處理請求。

按照職責、通用性、技術特性綜合考慮和計量,邏輯架構設計如下圖:

  

  十幾個子系統分別分佈在服務層、控制層、表現層(典型的三層架構)。實體層和介面訪問層雖然屬於“層”,但它們並不單獨釋出,而是使用Jar包類庫的方式提供給其它服務呼叫,是邏輯上的層。服務元件的構成大都是按照業務領域劃分的,只有一個除外,就是“B2C網站”,B2C網站由於是面向終端使用者的高併發電子商務網站,為了處理高併發,我們將其拆分為兩個業務領域(也可以拆分成多個業務領域,看實際併發量),分別是使用者賬戶和產品。使用者瀏覽產品併購買,這是電子商務網站最基本的兩個領域。其中產品瀏覽等功能由更底層的產品服務提供,使用者賬戶功能由會員服務提供。還有一些功能,比如推薦商品可能是由其它服務提供,這些可以在控制層直接組合這些服務。

l 服務架構

  服務框架採用典型的“服務登錄檔”模式,登錄檔使用redis。服務元件在啟動時將自己註冊進服務登錄檔,web伺服器或api 閘道器在訪問服務時查詢服務登錄檔得到服務的uri,然後呼叫某服務介面。

   

       淘寶的dubbo使用的是zookeeper作為服務登錄檔,之所以使用zookeeper,主要是使用它的負載均衡的功能。筆者認為restful介面沒有必要使用zookeeper做負載均衡,可以使用nginx(負載均衡伺服器都可以),所以沒必要選用動態的zookeeper作為登錄檔,而是使用“redis+心跳監測”機制(redis也可以換為LDAP等)來完成服務註冊和監控失效服務的功能。這個方案至少比dubbo簡單幾個數量級,簡單就是硬道理。

在註冊服務時只需要註冊nginx伺服器的IP以及服務描述資訊即可。反觀dubbo還要註冊介面進登錄檔,筆者認為這個沒必要,因為呼叫一個服務介面的充分必要條件就是知道伺服器的IP即可。至於呼叫什麼服務介面,肯定在程式碼裡已經寫死,目標伺服器必定存在這個服務介面。將服務介面註冊進服務登錄檔如果是為了監控審計服務的使用情況,那這個功能使用訪問日誌來實現能做的更好。

  總體的分散式拓補結構如下圖:

   

       對於服務叢集來講,看上去像是一個大哥(nginx)帶有眾多小弟的結構。訪問某服務群組只需要訪問其nginx伺服器即可,這裡nginx均採用高可用方案,防止單臺nginx出現問題。至於高層服務呼叫底層服務也是直接訪問其伺服器組的nginx。這個執行的流程其實和日常生活中的概念很像,如公司內部的執行流也是如此:老闆分配任務給部門經理,部門經理分配任務給主管,主管分配任務給具體的個人(某單臺伺服器)。領導們起到的作用也是負載均衡和監控,負載均衡就是把任務可以分配給多個人同時執行(並且某個執行失敗自動切換),監控就不必說了就是監控任務完成情況。在我們的方案裡,會專門有個服務去監控所有伺服器的執行情況,很簡單的服務就可以做到。

l 關於分散式事務

  如果研究一下EJB就會發現,EJB和微服務的架構基本相同,甚至所有面向服務(SCA、SOA等等)的架構都相差不大。很多人反對EJB,並不是EJB不夠強大,而是它不夠簡單,它給專案帶來的複雜性甚至超過了專案本身(這也是筆者不建議使用dubbo框架的原因)。曾有人說過:你要麼把事情做的儘可能簡單,讓人挑不出毛病;要麼把事情做的儘可能複雜,讓人找不出毛病,EJB就是後者。EJB分散式事務機制實現的很好,可惜的是這種“一刀切”的事務機制,大大降低了web系統的效能,所以幾乎所有面向網際網路的應用都極少使用分散式事務,也就不會採用EJB。網際網路應用本身事務性操作並不多,一些新聞、部落格之類的網站甚至都不需要事務。另外一個方面,即使出現一個或兩個分散式事務應用場景,也可以通過其它手段解決,比如事件機制等等。

  在之前的文章中我們也提到過對於分散式事務最佳的策略是儘量避免。如果避免不了將按以下方式實現。

  1)  將分散式事務性操作封裝在一個服務中,這個服務使用XA或鏈式分散式事務管理。

  2)  可以使用事件機制協調事務管理(具體做法就是事務失敗後發失敗事件到可持久化的訊息佇列,然後需回滾操作的介面監控此事件並執行回滾)。

  3)  使用自定義分散式事務管理器管理分散式事務。

   

  筆者設想的自定義分散式事務管理器主要是封裝了流程及分散式事務相關功能,筆者將在其它文章專門討論。如圖所示,假設有一個事務需要依次呼叫ABCDE五個介面,我們首先呼叫分散式事務管理介面建立這條“流程”的例項,例項中五個介面分別對應五個狀態,呼叫成功後將該介面對應的狀態設定為“成功”,反之就是“失敗”,流程處理結束後,分散式事務檢查狀態,然後按照一定的策略呼叫失敗介面的反向操作介面去回滾資料(前提條件也是參與分散式事務操作的介面要開發反向操作介面)。這既是一個簡單的流程引擎,也是一個分散式事務協調處理裝置,具體是否有必要做的複雜(比如處理並行流程),還要看實際環境下分散式事務的情況,但筆者認為網際網路前端應用使用簡單流程應該足以應付。

l 開發架構

  系統所需的工程,“[ ]”裡面表示工程的名稱。

   

  從圖中不難看出,我們將運維相關前端介面合併為一個前端系統,總體來講前端只有3種,B2C前端、APP前端、運維前端。把運維前端合併為一個專案有利於加快前期的開發、部署的效率,在後期如果某子系統功能介面太多,可以將前端系統獨立,比如公估系統、客戶管理系統等,獨立後的系統需要使用單點登入,這樣就可以在各個系統之間免登陸切換。

開發環境:

編碼:UTF-8                                          

工具:Myeclipse 10

SVN:Site-1.8.22

Web伺服器:Tomcat7

JDK: JDK1.7、 Java EE 5

開發環境:Maven 3

開發技術選型:

表現層:Bootstrap+Html+Jquery

MVC框架:Spring MVC 3.2

安全框架:Spring security 3.2

Rest介面實現:Spring MVC Rest

持久層:Mybatis3.2

分散式快取:Redis

資料庫:MySql 5.6

轉載自http://www.cnblogs.com/Leo_wl/p/5049722.html