成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一旦參透這九個電商系統(tǒng)架構,全能型架構師無疑了

開發(fā) 架構 新聞
面對這么多的業(yè)務域,有沒有通用技術經(jīng)驗可以抽取,讓我們可以 以一應百。

做為一名程序員,發(fā)展方向大致可以分為兩個方面: 一個是業(yè)務架構,一個是技術架構(中間件方向)。

業(yè)務架構,取其核心關鍵詞,主要是圍繞這不同的業(yè)務場景、業(yè)務規(guī)則,完成業(yè)務系統(tǒng)的落地建設,為用戶提供在線化的信息服務。

既然說到業(yè)務,那方向可就多了去了,如:出行、外賣、充電寶、O2O、內(nèi)容、社交、生鮮、電商,不同的業(yè)務有不同的特點。

面對這么多的業(yè)務域,有沒有通用技術經(jīng)驗可以抽取,讓我們可以 以一應百。

這里,首推電商業(yè)務,電商系統(tǒng)的復雜性很高,對 高并發(fā)、高性能、高可用、高擴展, 等方面要求很高。你在其他業(yè)務中可能遇到的問題,在電商系統(tǒng)中基本都會遇到。

作為開發(fā),希望自己成為某幾個業(yè)務領域的 技術專家, 最好能先精通 電商領域, 有很強的借鑒意義。對于你后續(xù)拓展熟悉其他業(yè)務領域的個性化玩法有很大幫助。

那么,電商領域的技術架構有哪些常見問題?

一、避免重復下單

用戶快速點了兩次 “提交訂單”  按鈕,瀏覽器會向后端發(fā)送兩條創(chuàng)建訂單的請求,最終會創(chuàng)建兩條一模一樣的訂單。

1、解決方案

解決方案就是采用冪等機制,多次請求和一次請求產(chǎn)生的效果是一樣的。

1)方案一

利用數(shù)據(jù)庫自身特性 “主鍵唯一約束”,在插入訂單記錄時,帶上主鍵值,如果訂單重復,記錄插入會失敗。

操作過程如下:

  • 引入一個服務,用于生成一個“全局唯一的訂單號”;
  • 進入創(chuàng)建訂單頁面時,前端請求該服務,預生成訂單ID;
  • 提交訂單時,請求參數(shù)除了業(yè)務參數(shù)外,還要帶上這個預生成訂單ID。

2)方案二

前端通過js腳本控制,無法解決用戶刷新提交的請求。另外也無法解決惡意提交。

不建議采用該方案,如果想用,也只是作為一個補充方案。

3)方案三

前后約定附加參數(shù)校驗。

當用戶點擊購買按鈕時,渲染下單頁面,展示商品、收貨地址、運費、價格等信息,同時頁面會埋上 Token 信息,用戶提交訂單時,后端業(yè)務邏輯會校驗token,有且匹配才認為是合理請求。

同一個 Token 只能用一次,用完后立馬失效掉。

<form action="/add-name-v2" method="post">
{% csrf_token %}
<input type="text" name="name">
<input type="submit" value="提交">
</form>

二、訂單快照,減少存儲成本

商品信息是可以修改的,當用戶下單后,為了更好解決后面可能存在的買賣糾紛,創(chuàng)建訂單時會同步保存一份商品詳情信息,稱之為訂單快照。

同一件商品,會有很多用戶會購買,如果熱銷商品,短時間就會有上萬的訂單。如果每個訂單都創(chuàng)建一份快照,存儲成本太高。另外商品信息雖然支持修改,但畢竟是一個低頻動作。我們可以理解成,大部分訂單的商品快照信息都是一樣的,除非下單時用戶修改過。

如何實時識別修改動作是解決快照成本的關鍵所在。我們采用摘要比對的方法?。創(chuàng)建訂單時,先檢查商品信息摘要是否已經(jīng)存在,如果不存在,會創(chuàng)建快照記錄。訂單明細會關聯(lián)商品的快照主鍵。

public class DigestTest {
public static void encodeStr(String data) {
String encodeS = DigestUtils.md5Hex(data);
System.out.println(encodeS);
}
public static void main(String[] args) {
String data = "網(wǎng)銷投連險是保險公司的一款保險產(chǎn)品,在互聯(lián)網(wǎng)金融上還是很常見的。" + "比如京東天天盈,網(wǎng)易有錢零錢++。這些保險削弱了保險的保障功能,降低成本,從而提高保險的理財功能提高理財收益。"
+ "投連險基本和銀行結構性理財產(chǎn)品一樣,信息披露度不高,但是有保險公司兜底,不至于整個平臺跑路。"
+ "投資投連險可以想象為投資一個起點低的銀行理財產(chǎn)品吧。網(wǎng)銷投連險一般都受益在4-6%,不承諾保本。"
+ "經(jīng)常爆出保險公司的保障型長期投連險出現(xiàn)投資虧損新聞,但是網(wǎng)銷短期投連險投資型投連險目前沒有出現(xiàn)虧損,基本也能按照預期收益兌付。"
+ "網(wǎng)銷投連險安全性和收益性都比較居中,短期產(chǎn)品危險系數(shù)不高,但是在債券違約的大環(huán)境下,長期產(chǎn)品安全性沒有太大保障。" + "不過好在保險公司沒有跑路風險,至少不會把本金損失殆盡啊。";
encodeStr(data);
}
}

由于訂單快照屬于非核心操作,即使失敗也不應該影響用戶正常購買流程,所以通常采用異步流程執(zhí)行。

三、購物車,混合存儲

購物車是電商系統(tǒng)的標配功能,暫存用戶想要購買的商品。分為添加商品、列表查看、結算下單三個動作。

技術設計并不是特別復雜,存儲的信息也相對有限(用戶id、商品id、sku_id、數(shù)量、添加時間)。這里特別拿出來單講主要是用戶體驗層面要注意幾個問題:

添加購物車時,后端校驗用戶未登錄,常規(guī)思路,引導用戶跳轉(zhuǎn)登錄頁,待登錄成功后,再添加購物車。多了一步操作,給用戶一種強迫的感覺,體驗會比較差。有沒有更好的方式?

如果細心體驗京東、淘寶等大平臺,你會發(fā)現(xiàn)即使未登錄態(tài)也可以添加購物車,這到底是怎么實現(xiàn)的?

細細琢磨其實原理并不復雜,服務端這邊在用戶登錄態(tài)校驗時,做了分支路由,當用戶未登錄時,會創(chuàng)建一個臨時Token,作為用戶的唯一標識,購物車數(shù)據(jù)掛載在該Token下,為了避免購物車數(shù)據(jù)相互影響以及設計的復雜度,這里會有一個臨時購物車表。

當然,臨時購物車表的數(shù)據(jù)量并不會太大,why?用戶不會一直閑著添加購物車玩,當用戶登錄后,查看自己的購物車,服務端會從請求的cookie里查找購物車Token標識,并查詢臨時購物車表是否有數(shù)據(jù),然后合并到正式購物車表里。

臨時購物車是不是一定要在服務端存儲?未必。

有架構師傾向前置存儲,將數(shù)據(jù)存儲在瀏覽器或者 APP LocalStorage, 這部分數(shù)據(jù)畢竟不是共享的,但是不太好的增加了設計的復雜度。

  • 客戶端需要借助本地數(shù)據(jù)索引,遠程請求查完整信息;
  • 如果是登錄態(tài),還要增加數(shù)據(jù)合并邏輯;

考慮到這兩部分數(shù)據(jù)只是用戶標識的差異性,所以作者還是建議統(tǒng)一存到服務端,日后即使業(yè)務邏輯變更,只需要改一處就可以了,畢竟自運營系統(tǒng),良好的可維護性也需要我們非常關注的。

四、庫存超賣

常見的庫存扣減方式有:

  • 下單減庫存: 即當買家下單后,在商品的總庫存中減去買家購買數(shù)量。下單減庫存是最簡單的減庫存方式,也是控制最精確的一種,下單時直接通過數(shù)據(jù)庫的事務機制控制商品庫存,這樣一定不會出現(xiàn)超賣的情況。但是你要知道,有些人下完單可能并不會付款。
  • 付款減庫存: 即買家下單后,并不立即減庫存,而是等到有用戶付款后才真正減庫存,否則庫存一直保留給其他買家。但因為付款時才減庫存,如果并發(fā)比較高,有可能出現(xiàn)買家下單后付不了款的情況,因為可能商品已經(jīng)被其他人買走了。
  • 預扣庫存: 這種方式相對復雜一些,買家下單后,庫存為其保留一定的時間(如 30 分鐘),超過這個時間,庫存將會自動釋放,釋放后其他買家就可以繼續(xù)購買。在買家付款前,系統(tǒng)會校驗該訂單的庫存是否還有保留:如果沒有保留,則再次嘗試預扣;如果庫存不足(也就是預扣失敗)則不允許繼續(xù)付款;如果預扣成功,則完成付款并實際地減去庫存。

至于采用哪一種減庫存方式更多是業(yè)務層面的考慮,減庫存最核心的是大并發(fā)請求時保證數(shù)據(jù)庫中的庫存字段值不能為負數(shù)。

方案一

通常在扣減庫存的場景下使用行級鎖,通過數(shù)據(jù)庫引擎本身對記錄加鎖的控制,保證數(shù)據(jù)庫的更新的安全性,并且通過where語句的條件,保證庫存不會被減到 0 以下,也就是能夠有效的控制超賣的場景。

update ... set amount = amount - 1 where id = $id and amount - 1 >=0

方案二

設置數(shù)據(jù)庫的字段數(shù)據(jù)為無符號整數(shù),這樣減后庫存字段值小于零時 SQL 語句會報錯。

五、商家發(fā)貨,物流單更新 ABA 問題

舉個例子:

商家發(fā)貨,填寫運單號,開始填了 123,后來發(fā)現(xiàn)填錯了,然后又修改為 456。

此時,如果就為某種特殊場景埋下錯誤伏筆,具體我們來看下:

過程如下:

  • 開始「請求A」發(fā)貨,調(diào)訂單服務接口,更新運單號 123;
  • 但是響應有點慢,超時了;
  • 此時,商家發(fā)現(xiàn)運單號填錯了,發(fā)起了「請求B」,更新運單號為 456 ,訂單服務也響應成功了;
  • 這時,「請求A」觸發(fā)了重試,再次調(diào)用訂單服務,更新運單號 123,訂單服務也響應成功了;
  • 訂單服務最后保存的 運單號 是 123。

是不是犯錯了!!!!

那么有什么好的解決方案嗎?

很多人可能會說,不重試不就可以了,要知道 重試機制 是高可用服務的重要保障手段,很多重試是框架自動發(fā)起的。

理想的解決方案:

數(shù)據(jù)庫表引入一個額外字段 version ,每次更新時,判斷表中的版本號與請求參數(shù)攜帶的版本號是否一致。

update order
set logistics_num = #{logistics_num} , version = #{version} + 1
where order_id= 1111 and version = #{version}
  • 一致: 才觸發(fā)更新;
  • 不一致: 說明這期間執(zhí)行過數(shù)據(jù)更新,可能會引發(fā)錯誤,拒絕執(zhí)行。

六、賬戶余額更新,保證事務

用戶支付,我們要從買家賬戶減掉一定金額,再往賣家增加一定金額,為了保證數(shù)據(jù)的 完整性、可追溯性, 變更余額時,我們通常會同時插入一條 記錄流水。

賬戶流水核心字段: 流水ID、金額、交易雙方賬戶、交易時間戳、訂單號。

賬戶流水只能新增,不能修改和刪除。流水號必須是自增的。

后續(xù),系統(tǒng)對賬時,我們只需要對交易流水明細數(shù)據(jù)做累計即可,如果出現(xiàn)和余額不一致情況,一般以交易流水為準來修復余額數(shù)據(jù)。

更新余額、記錄流水 雖屬于兩個操作,但是要保證要么都成功,要么都失敗。要做到事務。

數(shù)據(jù)庫的事務隔離級別有: 讀未提交(RU)、讀已提交(RC)、可重復讀(RR)、串行化(Serializable)。

常用的隔離級別是 RC 和 RR ,因為這兩種隔離級別都可以避免臟讀。

當然,如果涉及多個微服務調(diào)用,會用到 分布式事務。

分布式事務,細想下也很容易理解,就是 將一個大事務拆分為多個本地事務, 本地事務依然借助于數(shù)據(jù)庫自身事務來解決,難點在于解決這個分布式一致性問題,借助重試機制,保證最終一致是我們常用的方案。

七、MySQL讀寫分離帶來的數(shù)據(jù)不一致問題

互聯(lián)網(wǎng)業(yè)務大部分都是 讀多寫少, 為了提升數(shù)據(jù)庫集群的吞吐性能,我們通常會采用 主從架構、讀寫分離。

部署一個主庫實例,客戶端請求 所有寫操作 全部寫到主庫,然后借助 MySQL 自帶的 主從同步 功能,做一些簡單配置,可以近乎實時的將主庫的數(shù)據(jù)同步給 多個從庫實例 ,主從延遲非常小,一般 不超過 1 毫秒。

客戶端請求的 所有讀操作 全部打到 從庫 ,借助多實例集群提升 讀請求 的整體處理能力。

這個方案看似天衣無縫,但實際有個 副作用。

主從同步雖然近乎實時,但還是有個 時間差 ,主庫數(shù)據(jù)剛更新完,但數(shù)據(jù)還沒來得及同步到從庫,后續(xù) 讀請求 直接訪問了從庫,看到的還是舊數(shù)據(jù),影響用戶體驗。

任何事情都不是完美的,從主同步也是一樣,沒有完美的解決方案,我們要找到其中的平衡取舍點。

我們以電商為例,看看如何從 產(chǎn)品層面 來化解這個問題。

為了實驗的真實性,Tom哥 特意在淘寶下了一筆購物訂單。 在下單確認頁面,點擊購買按鈕,進入了支付頁面。

輸入支付寶支付密碼,進入支付成功頁面,頁面有查看訂單詳情的入口。

點擊 查看交易詳情 ,才跳到真正的 訂單詳情頁,可以查看訂單的支付狀態(tài)(訂單數(shù)據(jù)取自從庫)。

看懂了嗎?

我們在支付成功后,并沒有立即跳到 訂單詳情頁, 而是增加了一個 無關緊要的 中間頁(支付成功頁) ,一是告訴你支付的結果是成功的,錢沒丟,不要擔心;另外也可以增加一些推薦商品,引流提升網(wǎng)站的GMV。最重要的,增加了一個緩沖期,為 訂單的主從庫數(shù)據(jù)同步 爭取了更多的時間。

可謂一舉多得,其他互聯(lián)網(wǎng)業(yè)務也是類似道理。

是不是又學了一招?

八、歷史訂單,歸檔

根據(jù) 二八定律, 系統(tǒng)絕大部分的性能開銷花在20%的業(yè)務。數(shù)據(jù)也不例外,從數(shù)據(jù)的使用頻率來看,經(jīng)常被業(yè)務訪問的數(shù)據(jù)稱為熱點數(shù)據(jù);反之,稱之為冷數(shù)據(jù)。

在了解的數(shù)據(jù)的冷、熱特性后,便可以指導我們做一些有針對性的性能優(yōu)化。這里面有業(yè)務層面的優(yōu)化,也有技術層面的優(yōu)化。比如:電商網(wǎng)站,一般只能查詢3個月內(nèi)的訂單,如果你想看看3個月前的訂單,需要訪問歷史訂單頁面。

實現(xiàn)思路如下:

1、冷熱數(shù)據(jù)區(qū)分的標準是什么?

要結合業(yè)務思考,可能要找產(chǎn)品同學一塊討論才能做決策,切記不要拍腦袋。以電商訂單為例:

1)方案一

以“下單時間”為標準,將3 個月前的訂單數(shù)據(jù)當作冷數(shù)據(jù),3 個月內(nèi)的當作熱數(shù)據(jù)。

2)方案二

根據(jù)“訂單狀態(tài)”字段來區(qū)分,已完結的訂單當作冷數(shù)據(jù),未完結的訂單當作熱數(shù)據(jù)。

3)方案三

組合方式,把下單時間 > 3 個月且狀態(tài)為“已完結”的訂單標識為冷數(shù)據(jù),其他的當作熱數(shù)據(jù)。

2、如何觸發(fā)冷熱數(shù)據(jù)的分離?

1)方案一

直接修改業(yè)務代碼,每次業(yè)務請求觸發(fā)冷熱數(shù)據(jù)判斷,根據(jù)結果路由到對應的冷數(shù)據(jù)表或熱數(shù)據(jù)表。缺點:如果判斷標準是 時間維度,數(shù)據(jù)過期了無法主動感知。

2)方案二

如果覺得修改業(yè)務代碼,耦合性高,不易于后期維護。可以通過監(jiān)聽數(shù)據(jù)庫變更日志 binlog 方式來觸發(fā)。

3)方案三

常用的手段是跑定時任務,一般是選擇凌晨系統(tǒng)壓力小的時候,通過跑批任務,將滿足條件的冷數(shù)據(jù)遷移到其他存儲介質(zhì)。在途業(yè)務表中只留下來少量的熱點數(shù)據(jù)。

3、如何實現(xiàn)冷熱數(shù)據(jù)分離?

過程大概分為三步:

  • 判斷數(shù)據(jù)是冷、還是熱;
  • 將冷數(shù)據(jù)插入冷數(shù)據(jù)表中;
  • 然后,從原來的熱庫中刪除遷移的數(shù)據(jù)。

4、如何使用冷熱數(shù)據(jù)?

1)方案一

界面設計時會有選項區(qū)分,如上面舉例的電商訂單。

2)方案二

直接在業(yè)務代碼里區(qū)分。

九、訂單分庫分表,多維度查詢

如果電商網(wǎng)站的訂單數(shù)過多,我們一般會想到 分庫分表 解決策略。沒問題,這個方向是對的。

但是查詢維度很多:

  • 買家,查詢 我的訂單 列表,需要根據(jù) buyer_id 來查詢;
  • 查看訂單詳情,需要根據(jù) order_id 來查詢;
  • 賣家,查詢 我的銷售 列表,需要根據(jù) seller_id 來查詢。

而訂單分表只有一個分表鍵,如何滿足多維度 SQL 操作呢?

我們一般是基于買家維度來設計,下圖是 淘寶 的訂單列表:

一個訂單號 19 位,我們會發(fā)現(xiàn)同一個用戶不同訂單的最后 6 位都是一樣的,沒錯,那是用戶id的后6位。

這樣,上文中 場景1、場景2 的查詢可以共性抽取, 采用 buyer_id  order_id  的 后六位 作為分表鍵,對 1000 000 取模,得到買家維度的訂單分表的編號。

至于 場景3 賣家維度的訂單查詢,我們可以采用數(shù)據(jù)異構方式,按 seller_id 維度另外存儲一份數(shù)據(jù),專門供賣家使用。

責任編輯:張燕妮 來源: 微觀技術
相關推薦

2022-03-15 17:35:20

電商系統(tǒng)架構

2012-10-26 15:11:56

云計算Puppet

2013-02-18 13:39:00

HP打印機

2025-01-22 08:00:00

架構秒殺系統(tǒng)Java

2024-03-21 14:21:48

系統(tǒng)重構

2021-08-02 08:18:14

Typescript編譯代碼

2015-11-04 14:08:34

公有云存儲EMC

2013-10-12 13:48:57

2012-06-17 12:58:04

架構師架構

2011-04-28 14:17:05

架構設計

2019-07-31 07:36:12

架構運維技術

2022-02-24 18:31:30

低代碼架構數(shù)字化

2012-04-13 14:22:54

2019-09-04 16:06:56

戴爾Latitude

2017-03-03 14:10:50

電商基礎架構建設

2011-11-01 09:02:26

系統(tǒng)架構師

2011-10-31 09:22:07

系統(tǒng)架構

2017-10-18 15:19:23

架構師技術開發(fā)

2011-12-26 12:56:39

惠普大幅面打印機

2012-09-27 09:38:42

微軟Visual Stud
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人黄色在线观看 | 91在线视频观看免费 | 国产精品一区二区三区四区 | 中文字幕在线免费观看 | 99精品久久 | 国产综合视频 | 国产精品a久久久久 | 日韩在线播放中文字幕 | av在线三级 | 精品亚洲二区 | 欧美精品日韩 | 久久精品一 | 日本成年免费网站 | 国产精品久久久久久久久久三级 | 影音先锋中文字幕在线观看 | 亚洲狠狠丁香婷婷综合久久久 | 美女日批免费视频 | 国产在线a视频 | 亚洲欧美国产精品一区二区 | 特黄一级 | 美女131mm久久爽爽免费 | 日本亚洲精品成人欧美一区 | 欧美日韩综合 | 亚洲精品久 | 天天躁日日躁狠狠躁2018小说 | 成人午夜精品 | 日日草夜夜草 | 亚洲3级 | 国产伦精品一区二区三区精品视频 | 91精品久久久久 | 免费国产视频在线观看 | 男女视频免费 | 久久99精品久久久久久噜噜 | 亚洲欧美在线免费观看 | 成年免费大片黄在线观看一级 | 中文字幕韩在线第一页 | 欧美久久久久久久 | 国产精品一区二区三区四区 | 精品久久久久久亚洲精品 | 九九久久精品 | 国产一区二区精品在线 |