前端交易型系統(tǒng)設計原則

前端交易型系統(tǒng)設計原則

從畢業(yè)到現(xiàn)在已經快7年開發(fā)經驗了,做過基礎用戶系統(tǒng)、積分商城、偷菜游戲、論壇、博客等等;也一個人全棧開發(fā)在線視頻網站(http://sishuok.com/),也開發(fā)過幾萬、幾十萬、幾千萬、幾個億不同量級的系統(tǒng),踩過不少坑,也學到許多經驗。

設計了一些系統(tǒng),也有了一些自己的觀點,個人認為設計系統(tǒng)要因場景因時間而異,一個系統(tǒng)不是一下子就設計的非常完美,在有限的資源情況下一定是先解決當下最核心的問題,并預測/發(fā)現(xiàn)未來可能出現(xiàn)的問題,一步步解決最痛點的問題。也就是說系統(tǒng)設計是不斷迭代的過程,在迭代中發(fā)現(xiàn)問題修復問題;即滿足需求的系統(tǒng)是不斷迭代優(yōu)化出來的,不是一下子就架構的非常完美,這是一個持續(xù)的過程,個人不相信完美架構銀彈。不過如果一開始就有好的基礎系統(tǒng)設計,未來可以更容易達到一個比較滿意的目標。

在設計系統(tǒng)時應該多思考墨菲定律

1、任何事都沒有表面看起來那么簡單;

2、所有的事都會比你預計的時間長;

3、會出錯的事總會出錯;

4、如果你擔心某種情況發(fā)生,那么它就更有可能發(fā)生。

但是也要思考80/20法則,在系統(tǒng)設計初期將有限的資源用到刀刃上,我們的目標是系統(tǒng)滿足現(xiàn)有需求并能支持未來需求。

在持續(xù)開發(fā)系統(tǒng)過程中前輩們也總結了很多設計原則/經驗;而我個人也有幸運用了一些經驗/原則。設計原則是系統(tǒng)發(fā)展初期或進化過程中根據自己系統(tǒng)特征匹配使用的,如果剛開始不是核心問題請不要復雜化系統(tǒng)設計。

拆分

在系統(tǒng)設計初期,是做一個大而全的系統(tǒng)還是進行按功能拆分系統(tǒng)這個需要進行權衡;比如做私塾在線時本身用戶量/交易量不會特別大,而且開發(fā)就我一個人,資源有限,那就沒必要對系統(tǒng)拆分(比如拆分商品、訂單等等),就是做一個大而全的系統(tǒng)。而比如設計一個京東秒殺系統(tǒng),預測到一旦上線量會非常大,而且投入的資源還是蠻充足的,這種情況下就要考慮進行按功能拆分系統(tǒng)。

筆者遇到的拆分主要有如下幾種情況:

系統(tǒng)維度:按照系統(tǒng)功能/業(yè)務拆分,比如商品系統(tǒng)、購物車、結算、訂單系統(tǒng)等等;

功能維度:對一個系統(tǒng)進行功能再拆分,比如優(yōu)惠券系統(tǒng),可以拆分為后臺券創(chuàng)建系統(tǒng)、領券系統(tǒng)、用券系統(tǒng)等;

讀寫維度:根據讀寫比例特征進行拆分,比如商品系統(tǒng),交易的各個系統(tǒng)都會讀取,讀大于寫,因此就可以進行拆分:商品寫服務、商品讀服務;讀服務可以考慮全量緩存提升性能;比如寫的量太大,需要考慮分庫分表;還有些聚合讀取的場景,如商品詳情頁,請考慮數據異構拆分系統(tǒng),將分散在多處的數據聚合到一處存儲,提升讀的性能和可靠性;

AOP維度:根據訪問特征,按照AOP進行拆分,比如商品詳情頁,可以分為CDN、頁面渲染系統(tǒng);CDN就是一個AOP系統(tǒng);

模塊維度:比如按照基礎或者代碼維護特征進行拆分,如基礎模塊:分庫分表、數據庫連接池等等;還有如代碼維護一般按照三層架構(Web、Service、DAO)進行劃分。

服務化

首先判斷是不是只需要簡單的單點遠程服務調用即可,如果單機扛不住了需要集群,是不是可以在客戶端注冊多臺機器,使用Nginx進行負載均衡即可解決;如果隨著調用方越來越多,就要考慮使用服務自動注冊和發(fā)現(xiàn)(如Dubbo使用zookeeper);還要考慮服務的分組/隔離,比如有的系統(tǒng)訪問量太大導致把整個服務打掛,因此需要為不同的調用方提供不同的服務分組,隔離訪問;后期還會隨著調用量的增加還要考慮如服務的限流、黑白名單等等。還有一些細節(jié)需要注意,如超時時間、重試機制、服務路由(能動態(tài)切換不同的分組)、故障補償等等,這些都會影響到服務的質量。

總結為進程內服務--->單點遠程服務--->集群手動注冊服務--->自動注冊和發(fā)現(xiàn)服務---->服務的分組/隔離/路由---->限流/黑白名單。

數據版本化,可回滾

在設計時考慮是否需要進行數據的版本化,數據維護出問題是否需要回滾。比如商品的維護是不是需要版本化。我們目前有一些非常重要的系統(tǒng)需要對數據進行版本化并且支持可回滾。整體設計類似于下圖設計:

流程可定義

如果接觸過保險業(yè)務,會發(fā)現(xiàn)不同的保險理賠服務是不一樣的,因此我們在系統(tǒng)設計時就設計了一套理賠流程服務。而承保流程和理賠流程是分離,然后進行關聯(lián),從而可以復用一些理賠流程并提供個性化的理賠流程。

狀態(tài)與狀態(tài)機

在設計交易訂單系統(tǒng)時,會存在正向狀態(tài)(待付款、待發(fā)貨、已發(fā)貨、完成)和逆向狀態(tài)(取消、退款)等,正向狀態(tài)和逆向狀態(tài)應該根據自己系統(tǒng)的特征來決定是不是需要分離存儲。

另外還有訂單狀態(tài)的變遷,比如待支付、已支付待發(fā)貨、待收貨、完成的遷移;要考慮是不是需要使用狀態(tài)機來驅動狀態(tài)的變更和后續(xù)流程節(jié)點操作。

還要考慮并發(fā)狀態(tài)修改問題,同時對同一個訂單只存在一個修改;狀態(tài)變更的有序問題,狀態(tài)變更消息的先到后到問題,如支付成功消息和用戶取消消息的時間差。

消息隊列

消息隊列,用來解耦一些不需要同步調用的服務或者訂閱一些自己系統(tǒng)關心的變化;使用消息隊列可以實現(xiàn)服務解耦(一對多消費)、異步、緩沖(削峰)等。比如電商系統(tǒng)中的交易訂單數據,該數據有非常多的系統(tǒng)關心并訂閱,比如訂單生產系統(tǒng)、定期送系統(tǒng)、訂單風控系統(tǒng)等等;如果訂閱者太多,那么訂閱單個消息隊列就會成為瓶頸,此時需要考慮對消息隊列進行多個鏡像復制。

大流量緩沖持久化

在電商搞大促時,此時的系統(tǒng)流量會高于正常流量的幾倍甚至幾十倍,此時就要進行一些特殊的設計來保證系統(tǒng)平穩(wěn)度過這段時期;而解決的手段很多,一般都是犧牲強一致性,而是保證最終一致性即可。

比如扣減庫存,可以考慮這樣設計:

直接在Redis中扣減,然后記錄下扣減日志,通過Worker去同步到DB。

還有如交易訂單系統(tǒng),可以考慮這樣設計:

首先結算服務調用訂單接單服務將訂單存儲到:訂單Redis和訂單隊列表,訂單隊列表可以按照需求水平擴展N個表,通過隊列緩沖表提升接單的能力;然后通過同步Worker同步到訂單中心表;假設用戶支付了訂單,訂單狀態(tài)機會驅動狀態(tài)變更,此時可能訂單隊列表的訂單還沒有同步到訂單中心表,此時狀態(tài)機就要根據實際情況進行重試。

如果用戶查看單個訂單詳情可以直接從訂單Redis就能查到;但如果查詢訂單列表需要考慮訂單Redis和列表的合并。

同步Worker在設計時需要考慮并發(fā)處理和重復處理的問題,單機串行掃描處理(每臺Worker只掃描其中的一部分表)還是集群處理(Map-Reduce),另外需要考慮是否需要對訂單隊列表添加相關字段:處理人(哪個應用正在處理)和處理狀態(tài)(正在處理、已處理、處理失敗)。

數據校對

在使用了消息異步機制的場景下,可能存在消息的丟失,需要考慮進行數據校對和修正來保證數據一致性和完整性。可以通過Worker定期去掃描原始表進行補償,掃描周期根據實際場景進行定義。

數據異構化

訂單分庫分表一般按照訂單ID進行分,那么如果要查詢某個用戶的訂單列表就需要聚合N個表的數據然后返回,這樣會導致訂單表的讀性能很低;此時需要對訂單表進行異構,異構一套用戶訂單表,按照用戶ID進行分庫分表;另外還需要考慮對歷史訂單數據進行歸檔處理。

還一種異構場景,如商品詳情頁,因為數據來源太多,影響服務穩(wěn)定性的因素就太多了,因此最好的辦法是把使用到的數據進行異構存儲,形成數據閉環(huán);提升服務的性能和穩(wěn)定性。而有些數據異構的意義不大,如庫存價格可以考慮異步加載,或者并發(fā)請求合并。

后臺系統(tǒng)操作可反饋

在我接觸過的很多系統(tǒng),很多場景都需要反饋,比如修改了某些內容想預覽看看最終效果,即想得到一些反饋;還有一些是規(guī)則系統(tǒng),希望看到這些規(guī)則在系統(tǒng)數據下的反饋。因此在設計后臺系統(tǒng)請考慮效果的可預覽、可反饋。

后臺系統(tǒng)審批化

對于有些重要的后臺功能需要設計審批流,比如調整價格,并對操作進行日志記錄從而保證操作可追溯、可審計。

防重設計

比如結算頁需要考慮重復提交,還有如下單扣減庫存時需要防止重復扣減庫存。解決方案可以考慮防重KEY、防重表。而有些場景如重復支付,如有的電商網站同時支持微信支付、京東支付,渠道不一樣是無法防止重復支付的,但是系統(tǒng)設計時需要將支付的每筆情況記錄下。比如下圖是我在京東使用京東支付和微信支付模擬的重復支付之后進行退款的支付明細:

冪等設計

在交易系統(tǒng)中經常會用到消息,而現(xiàn)有消息中間件基本不保證不發(fā)生重復消息的消費;因此需要業(yè)務系統(tǒng)考慮在重復消息消費時進行冪等處理。還有如使用第三方支付時,第三方支付會進行異步回調,因此也要考慮做好回調的冪等處理。

文檔&注釋

我接觸的一些系統(tǒng)是完全沒有文檔、代碼沒有注釋的,完全都是人傳人;這將導致后來人接手很痛苦,而且對有些代碼是完全不敢改動的,比如有些代碼完全是因為業(yè)務的一些特殊情況而寫的,可以說是沒有注釋是完全不懂為什么那么做的。因此在一個系統(tǒng)發(fā)展的一開始就應該有文檔庫(設計架構、設計思想、數據字典/業(yè)務流程、現(xiàn)有問題)、業(yè)務代碼/特殊需求有注釋。

本文只是整理了一小部分原則,還有很多好的原則無法在一篇文章中全部闡述,比如可回滾(系統(tǒng)出問題時第一時間應該回滾處理,必要情況下摘除并保留一臺問題機器進行問題排查)、有損服務(故障功能降級/屏蔽、部分人可用、部分系統(tǒng)可用)、灰度發(fā)布(功能只對部分人開發(fā),從而保證假設出問題只是影響一小部分人)等等,每一個原則都可以寫一篇文章好好闡述。

前端交易型系統(tǒng)本身是非常復雜的,以上原則只是筆者在實際開發(fā)時遇到過并使用的一些原則,而還有很多好的原則和經驗是可以借鑒的,如果您有好的想法歡迎整理成文章分享給更多的人。另外筆者對支付/結算、供應鏈、庫房生產等部分也不熟悉,只進行了前端交易系統(tǒng)的一些原則的總結,也希望更多人加入進來來完善設計原則庫。

===========================

喜歡我的內容請關注我的公眾號。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容