這3個問題經常出現,不解決的話,一定會造成經濟損失的
1、同一個請求被髮送了多次
可能出現的地方:(1)和別人接口對接,別人同一份數據發送了多次
(2)用戶在“提交”按鈕裏點擊了多次
(3) 其他可能的一些惡意調用,尤其是涉及支付環節的,危險性非常大
解決辦法: (1) 在網頁端,用戶點擊“提交”後,將按鈕disable掉
(2) 對於收到的數據插入到數據庫或者其他一些地方,做好唯一鍵控制
能夠確定唯一的:訂單號,或者幾個字段拼湊在一起,或者把時間考慮進去,精確到分鐘。整個md5一次,放到一個字段裏,加個唯一鍵
2、同一秒內有多次請求
這個就是併發控制,涉及到抽獎等等需要控制到數量的地方,控制不好,會出現抽獎抽多了,賣東西賣超了等情況
出現的原因也很清晰,同一秒內收到多個請求,分佈式的,可能不同的請求會分佈到不同的機器或者程序上去執行,都去讀取一下計數器(記錄賣的數量),比如:1,每個請求都各自執行讀取操作,發現都是1,沒有超出1的限制,然後都來修改計數器爲0,然後各自都去發貨或者發送獎品,結果造成了賣超。
解決辦法:
利用數據庫或者其他有併發控制的程序來做一個鎖的邏輯
利用數據庫的話,有一個小技巧提供給大家
僞代碼如下:
- //字段A裏存儲的是計數器數字,控制最多獎品數量,1個獎品和多個獎品的邏輯有點不一樣,注意下面的僞代碼
- // 如果是1個獎品
- select A from 字段B;
- $a = A;
- if ( $a == 1)
- {
- update A=0 where A==1;
- //如果執行成功,則可以領取獎品
- //這樣可以控制併發時只賣掉一個獎品
- }
- // 如果是N個獎品
- select A from 字段B;
- $a = A;
- if ( $a <= N)
- {
- update A=A-1 where A<=N and A > 0;
- //如果執行成功,則可以領取獎品
- //這樣可以控制併發時只賣掉N個獎品
- }
3、分佈式系統裏的超時控制
如果有這樣一個分佈式業務:用戶購買東西,扣錢成功後發貨,發貨失敗的話,退錢給用戶
如果A負責處理業務邏輯
B負責扣錢 C負責發貨 D負責退錢
正常邏輯1:A調用 B扣錢成功的話,C發貨
正常邏輯2:A調用B扣錢,扣錢成功,調用C發貨,C發貨失敗,調用D退錢
那麼A調用C的超時時間一定要足夠大,大於C處理髮貨的時間
否則會出現一種情況:
A調用C發貨,超時了,A以爲發貨失敗了,調用D給別人退錢了,結果C發貨是成功的,D也把錢退了
所以A調用C發貨的系統超時時間一定要遠遠大於C處理髮貨的最大時間