忻州内厩机械设备有限公司

熱門系統(tǒng)產(chǎn)品
電商交易類產(chǎn)品
渠道/經(jīng)銷商產(chǎn)品
AI人工智能產(chǎn)品
業(yè)務協(xié)同系統(tǒng)產(chǎn)品
其他產(chǎn)品與服務
沒有你合適的?
我要定制 >

冪等和高并發(fā)在電商系統(tǒng)中的使用

發(fā)布時間: 2018-11-07 文章分類: 技術(shù)干貨
閱讀量: 0

在Java web項目開發(fā)中,經(jīng)常會聽到在做訂單系統(tǒng)中生成訂單的時候,要做冪等性控制和并發(fā)控制,特對此部分內(nèi)容作出總結(jié),在高并發(fā)場景下,代碼層面需要實現(xiàn)并發(fā)控制;但是冪等性,其實更多的是系統(tǒng)的接口對外的一種承諾,承諾一次請求和多次請求會返回同樣的數(shù)據(jù)。關(guān)于冪等性將分別從高等代數(shù)中的冪等性、HTTP中的冪等性和訂單生成系統(tǒng)中的冪等性闡述;并發(fā)性控制則提供了分布式鎖等方式來對并發(fā)場景進行Java網(wǎng)上電子商城系統(tǒng)代碼實現(xiàn)。

一、冪等性 idempotence  ['a?d?mpo?t?ns]

1.高等代數(shù)中關(guān)于冪等idempotence概念解釋:

獨立商城網(wǎng)站的建設(shè)單目運算, x為某集合內(nèi)的任意數(shù), 如果滿足f(x)=f(f(x)), 那么我們稱f運算為具有冪等性(idempotent)。比如在實數(shù)集中,絕對值運算就是一個例子: abs(a)=abs(abs(a))。

雙目運算,x為某集合內(nèi)的任意數(shù), f為運算子如果滿足f(x,x)=x, f運算的前提是兩個參數(shù)都同為x, 那么我們也稱f運算為具有冪等性。比如在實數(shù)集中,求兩個數(shù)的最大值的函數(shù): max(x,x) = x, 還有布爾代數(shù)中,邏輯運算 "與", "或" 也都是冪等運算, 因為他們符合AND(0,0) = 0, AND(1,1) = 1, OR(0,0) = 0, OR(1,1) = 1。

在將冪等性應用到軟件開發(fā)中,需要一些更深的理解,我的理解如下:數(shù)學處理的是運算和數(shù)值, 程序開發(fā)中往往處理的是對象和函數(shù). 但是我們不能簡單地理解為數(shù)學冪等中的運算就是函數(shù),而數(shù)值就是對象。如Person對象有兩個屬性weight和age,但是所有的function只能對其中一個屬性操作。所以從這個層面我們可以理解為: 函數(shù)只對該函數(shù)所操作的對象某個屬性具有冪等性, 而不是說對整個對象有運算冪等性。 

冪等和高并發(fā)在電商系統(tǒng)中的使用

還有一點必須要澄清的是: 冪等性所表達的概念關(guān)注的是數(shù)學層面的運算和數(shù)值, 并沒有提及到數(shù)值的安全性問題.如上面的Person的setAge函數(shù), 有兩種case不是冪等性所關(guān)心的, 但程序開發(fā)卻又必須要關(guān)心的:

兩個線程同時調(diào)用

因為age從業(yè)務上講不可能遞減, 如果前一次調(diào)用設(shè)置是30歲, 后一次調(diào)用變成了10歲或是更離譜的 -1 歲

冪等性是系統(tǒng)的接口對外一種承諾(而不是實現(xiàn)), 承諾只要調(diào)用接口成功, 外部多次調(diào)用對系統(tǒng)的影響是一致的。聲明為冪等的接口會認為外部調(diào)用失敗是常態(tài), 并且失敗之后必然會有重試。所以RESTful設(shè)計中將冪等性和安全性作為兩個不同的指標來衡量POST,PUT,GET,DELETE操作的。因此,post不是冪等性的,put get delete都是冪等性的,也即在生成訂單的post請求中,我們要做冪等性的控制。如下圖,一個ajax請求是一次post請求的示例,如果這個post請求被調(diào)用多次,它會向表插入多條記錄,很顯然post請求并不是冪等性的,所以冪等性的控制交由我們程序中來控制。

冪等和高并發(fā)在電商系統(tǒng)中的使用

2.HTTP協(xié)議中的冪等性

項目中中的SOA和restful API接口的流行,都需要應用層HTTP協(xié)議的支持,目前的項目結(jié)構(gòu):Web API + RIA(Rich Internet Applications富互聯(lián)網(wǎng)應用),Web API專注于提供業(yè)務服務,RIA專注于用戶界面和交互設(shè)計,從此兩個領(lǐng)域的分工更加明晰。正如簡單的Java語言并不意味著高質(zhì)量的Java程序,簡單的HTTP協(xié)議也不意味著高質(zhì)量的Web API。要想設(shè)計出高質(zhì)量的Web API,還需要深入理解分布式系統(tǒng)及HTTP協(xié)議的特性。在HTTP1.1規(guī)范中定義冪等性。

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects   of N > 0 identical requests is the same as for a single request.

從定義上看,HTTP方法的冪等性是指一次和多次請求某一個資源應該具有同樣的作用。冪等性是分布式系統(tǒng)設(shè)計中十分重要的概念,而HTTP的分布式本質(zhì)也決定了它在HTTP中具有重要地位。比如有這樣一個業(yè)務邏輯,假設(shè)有一個從賬戶取錢的遠程API(可以是HTTP的,也可以不是),我們暫時定義接口:

bool withdraw(account_id, amount)

withdraw的語義是從account_id對應的賬戶中扣除amount數(shù)額的錢;如果扣除成功則返回true,賬戶余額減少amount;如果扣除失敗則返回false,賬戶余額不變。值得注意的是:和本地環(huán)境相比,我們不能輕易假設(shè)分布式環(huán)境的可靠性。一種典型的情況是withdraw請求已經(jīng)被服務器端正確處理,但服務器端的返回結(jié)果由于網(wǎng)絡(luò)等原因被丟掉了,導致客戶端無法得知處理結(jié)果。如果是在網(wǎng)頁上,一些不恰當?shù)脑O(shè)計可能會使用戶認為上一次操作失敗了,然后刷新頁面,這就導致了withdraw被調(diào)用兩次,賬戶也被多扣了一次錢。如下圖所示:

冪等和高并發(fā)在電商系統(tǒng)中的使用

這個問題的解決方案一是采用分布式事務,通過引入支持分布式事務的中間件來保證withdraw功能的事務性。分布式事務的優(yōu)點是對于調(diào)用者很簡單,復雜性都交給了中間件來管理。缺點則是一方面架構(gòu)太重量級,容易被綁在特定的中間件上,不利于異構(gòu)系統(tǒng)的集成;另一方面分布式事務雖然能保證事務的ACID性質(zhì),而但卻無法提供性能和可用性的保證。

另一種更輕量級的解決方案是冪等設(shè)計。我們可以通過一些技巧把withdraw變成冪等的,比如:

int create_ticket() bool idempotent_withdraw(ticket_id, account_id, amount)

create_ticket的語義是獲取一個服務器端生成的唯一的處理號token,它將用于標識后續(xù)的操作。idempotent_withdraw和withdraw的區(qū)別在于關(guān)聯(lián)了一個token,一個token表示的操作至多只會被處理一次,每次調(diào)用都將返回第一次調(diào)用時的處理結(jié)果。這樣,idempotent_withdraw就符合冪等性了,客戶端就可以放心地多次調(diào)用。也就是說,多次點擊提交的時候,附帶提交的還有服務端生成的token,由于多次提交帶的是同一個token,所以服務端對于同一個token的post訂單,至多只會處理一次,所以間接的實現(xiàn)了冪等性的控制。

基于冪等性的解決方案中一個完整的取錢流程被分解成了兩個步驟:1.調(diào)用create_ticket()獲取token;2.調(diào)用idempotent_withdraw(token, account_id, amount)。雖然create_ticket不是冪等的,但在這種設(shè)計下,它對系統(tǒng)狀態(tài)的影響可以忽略,加上idempotent_withdraw是冪等的,所以任何一步由于網(wǎng)絡(luò)等原因失敗或超時,客戶端都可以重試,直到獲得結(jié)果。如圖2所示:

冪等和高并發(fā)在電商系統(tǒng)中的使用

和分布式事務相比,冪等設(shè)計的優(yōu)勢在于它的輕量級,容易適應異構(gòu)環(huán)境,以及性能和可用性方面。在某些性能要求比較高的應用中,冪等設(shè)計往往是唯一的選擇。

HTTP GET方法用于獲取資源,不應有副作用,所以是冪等的。比如:GET http://www.bank.com/account/123456,不會改變資源的狀態(tài),不論調(diào)用一次還是N次都沒有副作用。請注意,這里強調(diào)的是一次和N次具有相同的作用,而不是每次GET的結(jié)果相同。GET http://www.news.com/latest-news這個HTTP請求可能會每次得到不同的結(jié)果,但它本身并沒有產(chǎn)生任何副作用,因而是滿足冪等性的。
HTTP DELETE方法用于刪除資源,有副作用,但它應該滿足冪等性。比如:DELETE http://www.forum.com/article/4231,調(diào)用一次和N次對系統(tǒng)產(chǎn)生的副作用是相同的,即刪掉id為4231的帖子;因此,調(diào)用者可以多次調(diào)用或刷新頁面而不必擔心引起錯誤。
比較容易混淆的是HTTP POST和PUT。POST和PUT的區(qū)別容易被簡單地誤認為“POST表示創(chuàng)建資源,PUT表示更新資源”;而實際上,二者均可用于創(chuàng)建資源,更為本質(zhì)的差別是在冪等性方面。在HTTP規(guī)范中對POST和PUT是這樣定義的:

冪等和高并發(fā)在電商系統(tǒng)中的使用

POST所對應的URI并非創(chuàng)建的資源本身,而是資源的接收者。兩次相同的POST請求會在服務器端創(chuàng)建兩份資源,它們具有不同的URI;所以,POST方法不具備冪等性。而PUT所對應的URI是要創(chuàng)建或更新的資源本身。對同一URI進行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有冪等性。論壇網(wǎng)站防止重復發(fā)帖和訂單生成都用到token方式的冪等性控制。

3.總結(jié)

在電商系統(tǒng)中,常見問題:如何防范post請求的重復提交?HTTP POST 操作既不是安全的,也不是冪等的。當我們因為反復刷新瀏覽器導致多次提交表單,多次發(fā)出同樣的POST請求,導致遠端服務器重復創(chuàng)建出了資源。所以,對于電商應用來說,第一對應的后端 WebService 一定要做到冪等性,第二服務器端收到 POST 請求,在操作成功后必須跳轉(zhuǎn)到另外一個頁面,這樣即使用戶刷新頁面,也不會重復提交表單。

二、高并發(fā)

1.分布式鎖的定義

分布式鎖是控制分布式系統(tǒng)之間同步訪問共享資源的一種方式。在分布式系統(tǒng)中,常常需要協(xié)調(diào)他們的動作。如果不同的系統(tǒng)或是同一個系統(tǒng)的不同主機之間共享了一個或一組資源,那么訪問這些資源的時候,往往需要互斥來防止彼此干擾來保證一致性,在這種情況下,便需要使用到分布式鎖。分布式鎖是一個在很多環(huán)境中非常有用的原語,它是不同的系統(tǒng)或是同一個系統(tǒng)的不同主機之間互斥操作共享資源的有效方法。如在電商系統(tǒng)中,需要保證整個分布式系統(tǒng)內(nèi),對一個重要事物(訂單,賬戶等)的有效操作線程 ,同一時間內(nèi)有且只有一個。比如交易中心有N臺服務器,訂單中心有M臺服務器,如何保證一個訂單的同一筆支付處理,一個賬戶的同一筆充值操作是原子性的。

常見的實現(xiàn)分布式鎖的服務有:memcache zookeeper redis chubby hazelcast。

2.分布式鎖實現(xiàn)

分布式鎖在分布式應用當中是要經(jīng)常用到的,主要是解決分布式資源訪問沖突的問題。傳統(tǒng)的鎖ReentrantLock在去實現(xiàn)的時候是有問題的,ReentrantLock的lock和unlock要求必須是在同一線程進行,而分布式應用中,lock和unlock是兩次不相關(guān)的請求,因此肯定不是同一線程,因此導致無法使用ReentrantLock。

文章來源:博客園

<數(shù)商云(www.zhimaihui.cn)是國內(nèi)知名企業(yè)級電商平臺提供商,為企業(yè)級商家提供最佳的系統(tǒng)開發(fā)(多種模式電商平臺搭建:B2B/B2B2C/B2C/O2O/新零售等)、供應系統(tǒng)搭建電商解決方案服務>

點贊 | 0

數(shù)商云是一家全鏈數(shù)字化運營服務商,專注于提供SCM/企業(yè)采購/SRM供應商/DMS經(jīng)銷商/渠道商等管理系統(tǒng),B2B/S2B/S2C/B2B2C/B2C等電商系統(tǒng),從“供應鏈——生產(chǎn)運營——銷售市場”端到端的全鏈數(shù)字化產(chǎn)品和方案,致力于通過數(shù)字化和新技術(shù)為企業(yè)創(chuàng)造商業(yè)數(shù)字化價值。

添加企業(yè)微信獲取更多資料
添加企業(yè)微信獲取更多資料
相關(guān)文章

評論

剩余-200
發(fā)表
填寫以下信息, 免費獲取方案報價
姓名
手機號碼
企業(yè)名稱
  • 建筑建材
  • 化工
  • 鋼鐵
  • 機械設(shè)備
  • 原材料
  • 工業(yè)
  • 環(huán)保
  • 生鮮
  • 醫(yī)療
  • 快消品
  • 農(nóng)林牧漁
  • 汽車汽配
  • 橡膠
  • 工程
  • 加工
  • 儀器儀表
  • 紡織
  • 服裝
  • 電子元器件
  • 物流
  • 化塑
  • 食品
  • 房地產(chǎn)
  • 交通運輸
  • 能源
  • 印刷
  • 教育
  • 跨境電商
  • 旅游
  • 皮革
  • 3C數(shù)碼
  • 金屬制品
  • 批發(fā)
  • 研究和發(fā)展
  • 其他行業(yè)
需求描述
填寫以下信息馬上為您安排系統(tǒng)演示
姓名
手機號碼
你的職位
企業(yè)名稱

恭喜您的需求提交成功

尊敬的用戶,您好!

您的需求我們已經(jīng)收到,我們會為您安排專屬電商商務顧問在24小時內(nèi)(工作日時間)內(nèi)與您取得聯(lián)系,請您在此期間保持電話暢通,并且注意接聽來自廣州區(qū)域的來電。
感謝您的支持!

您好,我是您的專屬產(chǎn)品顧問
掃碼添加我的微信,免費體驗系統(tǒng)
(工作日09:00 - 18:00)
專屬顧問圖片
電話咨詢 (工作日09:00 - 18:00)
客服熱線: 4008 868 127
售前熱線: 189 2432 2993
掃碼即可快速撥打熱線