推出一款互聯網金融理財產品,如何安全高效的處理用戶高並發的購買請求?
現在互聯網金融逐漸發展起來了,隨之而來的是各大互聯網金融產品的推出。現問題如下:假設公司需要新推出一款理財產品,產品的募集資金為10000000(1千萬)元,每位顧客都可以進行購買交易,購買金額為1000元或者1000元的整數倍,只要剩餘募集金額>=購買金額則客戶購買成功,進行扣款或者凍結資金,相應的募集資金進行更新。此處還需要考慮到,客戶如果扣款失敗的話,需要再次返還佔有的額度。 由於目前市場情況,每推出一款這樣的產品,將會有大量用戶進行搶購。那麼該如何進行處理這種相對高並發的問題,以保證安全性和高效性呢?類似的產品如:騰訊的理財通
此類問題比較類似電商網站的秒殺/搶購、微信搶紅包。
此類業務一般都涉及分散式系統。而對於分散式系統而言,由於所謂的CAPS理論:服務的可用性、可靠性、數據的一致性三個要素並不能同時滿足,因此一般都遵循所謂的BASE理論。CAP理論:
Consistency:一致性, 數據一致更新,所有數據變動都是同步的Availability:可用性
Partition tolerance:分區容錯性,系統可靠性BASE理論:
Basically Available:基本可用 Soft-state:軟狀態/柔性事務 Eventual Consistency:最終一致性因此依賴於不同的場景,大家的處理方式不盡相同。
例如像微信紅包,發放的紅包是可以沒被搶到的。而秒殺、搶購一般會被搶光。
又比如像小米搶購手機,由於其限量的手機台數是小米自己定義的,搶購的手機台數可以有一定程度的誤差的(多或少一點)。而對於淘寶秒殺、搶購一般要求保證不多也不少。在具體使用場景上,互聯網金融的投標過程更類似於電商的秒殺和搶購。
此類應用重點要解決如下一些問題:
1、超賣
例如融資金額為1000萬,在最後的搶購中,可投金額只剩下1萬元,可能會有多個投資者同一瞬間都投標成功,導致用戶投資的金額超過了融資額。解決超賣問題的方案是保證用戶投標過程,對投資金額的增減採用事務,且要保證事務操作的原子性。2、少賣
典型場景題主提到了:用戶投標搶到了,但因支付失敗等原因沒正常完成搶購到訂單支付。解決少買問題的方案是對搶購訂單設定時效性,定時對超過時效未支付的訂單釋放掉。3、刷單作弊
例如黃牛採用批量註冊多個賬戶並用多賬戶並發搶購、用秒殺工具(按鍵精靈/autohotkey、觸摸精靈、phantomjs、selenium等)或自行開發的工具搶購、變換IP地址(例如ADSL、代理伺服器) 來搶購。解決辦法一般採用限制同一賬戶並發請求數、驗證碼、token、IP地址限制、賬戶黑名單等方式。
4、伺服器過載保護
解決辦法一般採用服務降級、限流。可以參考微信紅包的思路: 有損服務,柔性可用,大系統小做。談談微信紅包海量運營--發10億個紅包難在哪裡?5、外部渠道的瓶頸
類似秒殺、搶購、搶紅包這樣的活動,外部最大的瓶頸在於支付渠道。支付渠道的瓶頸主要分為兩大類:第一類:第三方支付平台的穩定性、流量瓶頸、系統並發性能等第二類:某個銀行渠道本身穩定性和流量瓶頸,例如使用工行卡支付的佔比過高,導致工行流量過載。解決辦法:
對支付渠道的穩定性及流量瓶頸,可以多接入幾家第三方支付或直連銀行,在多家支付渠道將備份容災、分流。對銀行渠道的穩定性及瓶頸,第三方支付一般會在同一家銀行的多個介面做渠道路由及分流。
另外在產品層面,除了實時秒殺/搶購外,可以考慮預約、引導用戶提前進行賬戶充值使用賬戶支付的方式。
6、網路、伺服器及硬體設備容災
例如網路癱瘓、伺服器癱瘓、網卡、存儲出問題之類。解決辦法一般採用系統升級擴容(水平擴展、垂直擴展)、容災、備份等。7、性能
在性能上,常規的CDN、頁面靜態化、資料庫讀寫分離、緩存、非同步化(消息隊列)、柔性事務等方案都可以用上。這裡重點說一下超賣問題,超賣問題的本質善於高並發情況下資料庫事務瓶頸的技術解決辦法。
超賣問題有兩種方案:
a、採用資料庫事務ACID來保證如果使用的mysql,可以採用mysql的線程池技術,通過請求排隊及請求合併,提高資料庫事務並發處理能力。
由於在秒殺這樣高並發的事務處理情況下,資料庫由於死鎖檢測等因素性能直線下降。具體可以參考淘寶在秒殺業務的解決方案:秒殺場景下MySQL的低效--原因和改進l淘寶是採用修改mysql源代碼方式來定製的,開源方案可以參考MariaDB的thread_pool系列參數,尤其是thread_pool_oversubscribe參數。可以參考:秒殺應用的MySQL資料庫優化此種方式的思路適合於需要完全保證ACID的場合,像支付系統核心交易、賬戶、賬務。b、採用redis+mysql結合的方式
由於redis本身的高性能,可以將投資總金額及餘額存放在redis,用redis完成投資用戶的搶購排號,然後通過消息隊列或日誌同步(例如kafka)方式將數據同步到mysql中。為保證redis操作原子性,建議採用redis lua腳本在redis伺服器端完成總的投資金額/餘額的操作。此種方式可能存在如下兩個問題:
redis與mysql數據同步延遲問題:可以在用戶取號後,等待幾秒,保證消息隊列或日誌同步到mysql。
redis癱瘓問題:通過限流等方式避免redis過載,通過redis集群保證redis高可用性。網上關於微信紅包、電商網站的秒殺架構討論比較多,以下幾篇文章值得參考。談談微信紅包海量運營--發10億個紅包難在哪裡?雙十一資料庫核心技術京東商城雙十一技術實戰 -PPT-騰訊大講堂小米網搶購系統的設計經驗微信紅包【技術篇】——如何為紅包提供穩定支付體驗微信紅包系統設計 amp; 優化微信紅包【技術篇】——如何在服務有損的情況下保證用戶體驗
推薦閱讀:
※如何看待方濱興「升級 Win 7 或 8 比續用 XP 更危險,政府應扶植國產操作系統」的言論?
※基於現有的被拖庫的資料庫進行撞庫攻擊,密碼的安全性太弱了,那麼下一代身份識別的特徵會是指紋或虹膜嗎?
※參加CNSS2017招新賽是一種怎樣的體驗?