转载自:http://m.zhihujingxuan.com/26957.htmlhtml
推出一款互联网金融理财产品,如何安全高效的处理用户高并发的购买请求?mysql
2015-10-06 20:00:09来源:知乎精选redis
【梁川的回答(17票)】:sql
此类问题比较相似电商网站的秒杀/抢购、微信抢红包。数据库
此类业务通常都涉及分布式系统。而对于分布式系统而言,因为所谓的CAPS理论:服务的可用性、可靠性、数据的一致性三个要素并不能同时知足,所以通常都遵循所谓的BASE理论。缓存
CAP理论:安全
Consistency:一致性, 数据一致更新,全部数据变更都是同步的服务器
Availability:可用性微信
Partition tolerance:分区容错性,系统可靠性网络
BASE理论:
Basically Available:基本可用
Soft-state:软状态/柔性事务
Eventual Consistency:最终一致性
所以依赖于不一样的场景,你们的处理方式不尽相同。
例如像微信红包,发放的红包是能够没被抢到的。而秒杀、抢购通常会被抢光。
又好比像小米抢购手机,因为其限量的手机台数是小米本身定义的,抢购的手机台数能够有必定程度的偏差的(多或少一点)。而对于淘宝秒杀、抢购通常要求保证很少也很多。
在具体使用场景上,互联网金融的投标过程更相似于电商的秒杀和抢购。
此类应用重点要解决以下一些问题:
一、超卖
例如融资金额为1000万,在最后的抢购中,可投金额只剩下1万元,可能会有多个投资者同一瞬间都投标成功,致使用户投资的金额超过了融资额。
解决超卖问题的方案是保证用户投标过程,对投资金额的增减采用事务,且要保证事务操做的原子性。
二、少卖
典型场景题主提到了:用户投标抢到了,但因支付失败等缘由没正常完成抢购到订单支付。
解决少买问题的方案是对抢购订单设定时效性,定时对超过期效未支付的订单释放掉。
三、刷单做弊
例如黄牛采用批量注册多个帐户并用多帐户并发抢购、用秒杀工具(按键精灵/autohotkey、触摸精灵、phantomjs、selenium等)或自行开发的工具抢购、变换IP地址(例如ADSL、代理服务器) 来抢购。
解决办法通常采用限制同一帐户并发请求数、验证码、token、IP地址限制、帐户黑名单等方式。
四、服务器过载保护
解决办法通常采用服务降级、限流。能够参考微信红包的思路: 有损服务,柔性可用,大系统小作。谈谈微信红包海量运营--发10亿个红包难在哪里?
五、外部渠道的瓶颈
相似秒杀、抢购、抢红包这样的活动,外部最大的瓶颈在于支付渠道。
支付渠道的瓶颈主要分为两大类:
第一类:第三方支付平台的稳定性、流量瓶颈、系统并发性能等
第二类:某个银行渠道自己稳定性和流量瓶颈,例如使用工行卡支付的占比太高,致使工行流量过载。
解决办法:
对支付渠道的稳定性及流量瓶颈,能够多接入几家第三方支付或直连银行,在多家支付渠道将备份容灾、分流。
对银行渠道的稳定性及瓶颈,第三方支付通常会在同一家银行的多个接口作渠道路由及分流。
另外在产品层面,除了实时秒杀/抢购外,能够考虑预定、引导用户提早进行帐户充值使用帐户支付的方式。
六、网络、服务器及硬件设备容灾
例如网络瘫痪、服务器瘫痪、网卡、存储出问题之类。
解决办法通常采用系统升级扩容(水平扩展、垂直扩展)、容灾、备份等。
七、性能
在性能上,常规的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高可用性。
网上关于微信红包、电商网站的秒杀架构讨论比较多,如下几篇文章值得参考。