基於支付場景的微服務高可用架構實戰
講師介紹
程超
智慧支付首席支付專家
今天給大家帶來的分享是基於支付場景的一個微服務實戰,會更偏向於應用層的內容。
分享大綱:
1. SOA與微服務
2. 老支付架構所遇到的一些挑戰
3. 基於微服務怎麼做的一些改造
4. 未來計劃要做的一些事
一、SOA與微服務
在我看來,微服務雖是國外傳進來的技術,卻和咱們中國的一些理論是掛鉤的。所以在正式進入主題之前,先給大家簡單介紹一下麥田理論。
1.關於麥田理論
古代周朝時期,老百姓種地實際是沒有任何規劃的,也沒有任何區域的限制,一般來說在地里一會種水稻,一會種小麥,一會種蔬菜地交叉來種,可收成之後發現莊稼受陽光程度非常低,營養非常不均衡,後期維護成本非常高。直到戰國時期,有一位農業專家把地劃分為多個區域,每一個區域種一種莊稼,地跟地隔開,形成最初的微服務理念。
過去我們看到的很多文章都只是講到SOA和微服務之間的比較,我今天在這個基礎上加了一個DDD。下面就DDD、SOA以及微服務的演進過程先做個引子。
2.DDD、SOA與微服務
SOA是上一個時代的產物,大概是在2010年之前出現的,最早提出時是提供給傳統行業計算領域的解決方案,當時Oracle、IBM也提了很多方案,包括出現的很多流程引擎。
它的思想是將緊耦合的系統,劃分為面向業務的粗粒度、松耦合、無狀態的服務。在這之後,微服務的提出者基於SOA做了一個改進,就把它變成單一職責、獨立部署、細小的微服務,是一個相反的概念。
今天我們一說到微服務就會想到DDD,有不少朋友認為DDD就是為微服務而生的。其實不是這樣的,我在接觸DDD時它最早是用來做UML設計、領域建模的。
DDD講究充血模型,而J2EE模型以傳統的分層架構和Spring架構捆綁在一起形成了以貧血模型為主的架構模式,貧血模型的優點是容易入門、分層清晰,而充血模型要求設計者前期對業務理解較深,不然後期項目會產生混亂。
另外就是DDD思想比較寬泛,導致形成百家爭鳴的姿態,沒有形成一套固定的方法論。開發者不容易理解,所以後面關注DDD的人變少了,而微服務的提出巧妙地借鑒了DDD裡面的限界上下文、子域、領域事件等關鍵詞,在微服務得到越來越多業界認可的情況下,也給DDD帶來了重新的煥發。
二、老支付架構遇到的挑戰
1.判斷項目好壞的兩個角度
我們判斷一個優秀項目的好壞,可以從優秀的代碼和高可用架構兩個方向來講。我們在設計高可用架構的同時,也不能忽視代碼的重要性,優秀的代碼指的是冗錯能力、冥等操作、並發情況、死鎖情況等,並不一定是指代碼寫得多漂亮。
這就好比蓋樓一樣,樓房的基礎架子搭得很好,但蓋房的工人不夠專業,有很多需要注意的地方忽略了,那麼在往裡面填磚加瓦的時候出了問題,後果就是房子經常漏雨,牆上有裂縫等各種問題出現,雖然不至於樓房塌陷,但樓房也已經變成了危樓。
從代碼和設計的角度來看有:
再從整體架構角度來看:
基於以上兩點,我們可以清晰地看到以前老項目的存在問題,並開始思考新的微服務架構應該怎麼去做。
三、基於微服務怎麼做的改造
想做高可用的微服務架構,必須先確立以下五個點:
1.利用DDD來劃分限界上下文
這是根據一些業務場景做的業務架構圖,中間綠色部分是產品服務層。用DDD的思想來分析,產品服務層也就是產品服務域,這個域里包含三個子域,一個是收銀檯子域,一個是商戶子域,一個是個人子域。每一個域里都包含有限界上下文,收銀台包含兩個,商戶包含四個,個人包含兩個。
有些同學可能不太了解限界上下文概念,可以把它理解為一個系統、一個邊界或者一個實體。比如說我們每天上班要倒三次地鐵,這裡面的關鍵事件是什麼?就是上班,那限界上下文就是坐地鐵,中間切換三次。
限界上下文就可以把它理解為一個微服務,也可以把它理解為一個系統、一個模塊。
限界上下文的劃分可以根據我們的團隊規模來定,如果團隊規模沒有達到一定的程度,可以將邊界定的粗一些,如果項目規模和團隊規模不斷擴大,還可以再把大的領域和限界上下文繼續拆分成多個小的。
2.微服務治理架構圖
這是我們大致的一個微服務整體流程圖,採用的是Spring Boot+Dubbo的架構。
為什麼主張用Dubbo而不是Spring Cloud?有幾點原因:
上圖中間這塊的探針也是我們自主研發的,能夠實現把整個服務鏈路的各種信息,比如掉網時間、報錯、返回值以及參數全部採集到,採集完之後就把這些信息用把一個開源組件進行改造,把信息全部推給它,透過那個界面展示出我們要的東西。
後面這一套比如Hystrix熔斷、Dubbo Admin和Mock Server我們是參考Dubbo的思路做的智能化攔截和服務降級。後面的服務註冊、服務發現、服務路由、失敗重試和服務監控等是Dubbo本身提供的,也就是圖片綠色的部分是我們自研的新功能,未來我們會把這個Dubbo Cloud體系進行開源。
3.通道報警切換系統的演進
這是我們通道報警系統的框架演進。為什麼叫「通道」呢?因為我們的支付要接銀行,但銀行本身是相對偏傳統的,它們的通道不是很穩定,經常有各種各樣的問題,而每個銀行都有N個通道,我們無法得知哪個通道近期是穩定的或不穩定,都是會來回變的。
這裡我們自研了一個Agent,通過採集它通道里的一些使用數據,比如說這次我們連成功了,獲取到了數據,然後放到Kafka里,之後還有一個統計分析的東西,如果這個通道連接成功一次會對它統計加一次,最後把每隔一段時間的結果存到Redis集群里。
圖中的路由系統就是做通道選擇的。這是一個業務系統,路由系統每次在做通道選擇時要先從Redis集群里把這個銀行的通道拿出來,選出評分最高的一個。
拿出後再經過自己的一套路由選舉的配套做一個清洗或者選擇,最後得到一個最優的通道,直接連到銀行通道上,這樣我們就能知道哪些通道是高可用的。
底下的過程還是通過Kafka,並進行各種各樣的統計分析,也非常好用。然後這裡會有一個圖表,如果當前有問題,在界面上都能可以看到,同時可以給你發簡訊、發郵件。
為什麼我們這裡做了兩套?第一期的時候我們要做一個數據的比對,因為如果採集的數據不準確,這個通道就會存在問題,所以我們一方面是通過上面這種方式來做評分策略,另一方面是把數據採集過來以後放到一個庫里,通過這個庫再做一次,最後每次做一個比較,以統計正確率。
當這個通道也發生了問題,比如某一個銀行通道發生了問題,我們的監控系統就會直接把銀行通道設置為不可用,然後通知研發部門讓他們去解決,完了以後再把這個通道變為可用。如果這個過程數據不準確,會造成頻繁的通道切換,會產生有很多不必要的問題,所以在第一期時我們先做成半自動化的。
4.雙活體系架構的演進
雙活機房的演進,也是需要兩個階段。
其中,第一個階段是偽雙活:
第二個階段是泳道雙活:
雙活體系架構的演進,在ZK做數據同步的時候,採用兩種方式Curator的TreeCacheListener監控相應節點的變化從而同步數據,另一個是修改ZK源碼偽裝成Observer接收事務日誌數據從而實現數據同步。
ZK的同步最好還是不進行同步、泳道隔離,比如像使用Dubbo這種的時候,完全可以同步二套環境,如果使用噹噹的Elastic-Job,在做雙活的時候就會相對麻煩。
5.微服務架構全景圖
這個就是我們整個微服務的整體架構。圖中左半部分體現了怎麼把服務進行劃分,劃分了哪些領域,然後有哪些服務,資料庫內容怎麼劃分,網關層怎麼做的,是從業務角度來做的一個劃分。
右邊這塊是體現我們如何保障微服務的可靠性。第一層主要是給項目運營人員使用,第二層是我們為了保障微服務都做了什麼東西,有統一調度中心、雙活管控架構,還有大數據平台、分散式緩存,做了各種各樣的組件來保障微服務順利的開展。
再下面是一些監控,這裡我們用了APM分散式調鏈的監控,包括我們自己也做了一些監控平台。
6.持續集成測試
接下來講講我們的持續測試經驗。怎麼來保證代碼的質量?這裡就涉及到了集成測試的概念。
我們分了四個象限,一是單元測試,這是由開發自己來做的,一般覆蓋率在60-80%就不錯了;二是驗收測試和探索測試,這兩個實際上是我們的測試人員在做,一個是驗證業務的可行性,一個是採取一些非法條件或者是一些破壞性測試,最後是壓力測試,通過壓測看系統能承受的負載情況。
這是我們的整個測試流程。首先,我們參照了阿里和其它公司的一些編碼規範,制定一套自己的編碼規範,並跟所有開發人員達成共識。然後我們有自己的靜態代碼檢查,這裡也可以用阿里的組件,這是前兩步。
第三步就是單元測試,基本上前三部分都是由開發來保障代碼的健壯性和正確性。第四是持續集成,我們根據自己的規則和模板對它再進行一次代碼的掃描,掃描完後之後就組織一些架構師或是技術專家,對一些關鍵核心代碼再做一個代碼重構,大致是分了五步。
四、未來計劃要做的事
上圖幾點就是未來我們計劃要做的一些事情,因為現在業務量越來越大了,而不久後央行會再出一個文件,要考慮異地多活這個情況,這塊我覺得是一種趨勢,目前也很多公司在做這件事情。
然後我們也會有一個Dubbo Cloud,未來也是會開源的。後面就是大數據平台的持續建設,目前我們的大數據平台還不是特別完善,像數據的挖掘這塊還沒有做,而現在一般的金融公司還有支付公司的風控都要做得特別好,而我們才剛起步。
問答環節
【問題1】老師您這邊做的東西特別多,那人員架構是怎麼設置的?
答:微服務這邊是三十多人在做。
【追問】那麼Dubbo Cloud這邊的一些事,比如監控和下面一塊的操作,這都有是嗎?
答:對,這整個部門都是我在負責,我們有劃分了多個不同的部門,每個部門做不同的事,Doorco是我們部門的事,這個監控也是我在做,這個運維就是運維研發我們定位也是一個部門。
【追問】人員比例大概是怎樣的呢?
答:這裡大概有六七個人在做這個事,比如這裡有三四個,上面有七八個,上面有四五個,大概是這樣。因為現在如果保證每一個模塊都是幾個人去做也不太現實,因為需要人很多,而且可能每一個模塊都會交叉去做,每個人都會負責多個模塊。
【問題2】我們也做日誌的東西,您剛剛說20-30%的丟失率,這塊是怎麼優化的?
答:這塊尤其是ELK,我們最開始用的時候是有一個Flume採集,採集時經常丟失,壓力特別大。而壓力特別大時Flume就會出現性能問題,丟一些數據。後來我們改成Logtash,當然ES這塊也需要研究,因為ES搞不好的話也會丟數據。
【問題3】老師您好,我們也是做分散式監控的,構建的跟您這個比較相似,也是用Spring Boot+Dubbo,因為我們用了內部研發的新架構,有一個問題就是因為我們在用這個架構時發現如果服務比較多,性能會下降,有可能比較拖累,因為一個代碼鏈路過來之後,短的、中程的還好點,一個大程的項目過來整個服務壓力就扛不住了,這一點我們現在比較困惑,您有沒有什麼建議?
答:這個確實是一個問題。我們一開始也是用的這個東西,但在數據採集這塊有性能問題,壓力特別大時整個探針就有問題,因為探針採集數據是一方面,採集的數據也是有限的,比如一個鏈路里有一個系統搭錯了,但錯誤信息你是採集不到的。我們的做法是把錯誤信息採集到,正常情況下鏈路中的系統都是綠燈,如果報錯了系統就會亮紅燈,這樣就能很快定位到問題根源,同時能看到報錯信息。
【追問】這套東西會開源嗎?
答:這個現在還沒有考慮,後面可以多交流。
【問題4】您好,看到您的探針基本都加在服務上,但有一些服務可能因為服務起調時是在UI界面上發起的,而我們往往JS端可能也要採集一下,才能實現一個真正的閉環,您在JS端有做過這方面的探索嗎?
答:我們是做第三方支付的,主要是針對後台服務端的,我們只提供API和介面,提供一個收銀台,比如京東要對接我們時就直接把數據發過來,因為我們是收單的。
【追問】那麼這個探針輸出的數據不用落地的吧?
答:對,不用落地。
【追問】那您應該了解Egoi是吧?Egoi是落地的,當時我玩這個東西的時候,Egoi整套東西都是在Doorco上部署的,經常出現問題的就是當規劃量非常大時並不是寫日誌寫不進去,而是算掉鏈的時候經常出問題,經常會5個CPU、8個CPU都不夠用,往往跟業務系統都是混步的,經常會把業務系統干倒。您這邊我沒太了解,推特那邊算是用Storm還是什麼?
答:它不是Storm,是自己寫的一套東西,但比Storm要強。
【問題5】單元測試用的是什麼工具?
答:現在是JUnit來做的。
【追問】是自己寫程序,自己掛上的嗎?
答:對,在上線的時候我們是要求寫的,而且是能跑通的。
【追問】咱們進行代碼檢查的時候自己寫的規則多嗎?通過這塊查出問題,效果怎麼樣?
答:一般的、簡單的還是效果可以的,但深層次的還是發現不了,比如Redis建立一個連接關閉一個連接這種能檢查出來,但說要看看有沒有深層溢出這類的,看不出來。
【追問】後面第五步是做代碼,這個是有工具嗎?
答:這個我們用Gerrit這種方式,這個是代碼,上線之前要把代碼發給不同的人,可以在上面進行各種點評,點評完之後開發者要把所有點評的東西關閉掉以後才能上線。
【問題6】因為您提到會開源,咱們這塊開源是說比如您這兒研究了一下然後覺得不錯就拿到團隊用了還是有什麼機制?這塊能分享一下嗎?對於開源工具的選擇。
答:首先我們要看需求是什麼,根據需求的不同來看是選擇特別重的開源組件還是輕量級的,像我們在做分散式定製任務和統一配置中心,這兩個我們是用的開源產品,其中統一配置中心我們用了攜程的一個組件阿波羅,因為它本身是用Spring Cloud來做的。
彩蛋來了
新規說明:同一個月份里,已獲贈者將不可重複拿書。
特別鳴謝圖靈社區為活動供圖書贊助。
TAG:DBAplus社群 |