zoukankan      html  css  js  c++  java
  • 支付系统中热点账户的性能问题

    支付系统中热点账户的性能问题

    热点账户类型

    账户属性

    实时需求

    锁需求

    处理方式

    性能

    业务大账户

    内部账户

    无实时余额查询

    无实时提现

    无需加锁

    异步MQ延时处理

    满足

    大代理商账户

    对外账户

    无实时余额查询

    无实时提现

    没有加锁需求

    异步MQ延时处理

    满足

    热门商户(推广)

    对外账户

    商户账户

    实时余额查询

    实时提现

    有加锁需求

    串行化同步

    亟待提升

    一、按业务场景尽量拆分热点账户,分散压力

    1)账户拆分,拆分主账户
    此时解决方法就是再办一张同行的卡,或者其它银行的卡,一起承担存钱和提现的需求

    2)新增多个子账户,
    向银行申请,为该主卡办理多个子卡,用子卡进行分流

    3)按功能进行划分
    申请一个专门接收打款的卡

    申请一个专门接受提现的卡

    二、异步方式

    4)异步队列延时处理
    先把所有的打款、提现的请求入队列,延时处理账户余额更新

    5)实在没招了,合并处理
    把某个特征相似的操作进行合并处理。即把别人一万次打款请求合并为一个打款请求,此时最终只需要申请一次打款,其它人的卡逐个扣款

    提现就不好解决了,可以增加一个提现缓冲卡,但是迫不得已,可以把多次提现请求,合并为一个请求,先从该账户把钱提到提现缓冲卡,再由提现缓冲卡分发给其它目标账户。

    支付结算账户系统针对上述问题做了如下处理:

    我们把热点账户按照金额变动方向分为加频账户(余额增加频繁)、减频账户(余额扣减频繁)、双频账户(余额增加扣减均频繁)。

    加频账户处理
    准实时更新余额。先将金额变动插入临时表中,由定时任务按照一定频率汇总发生额,并更新账户余额,而后删除临时记录。当加频账户减钱余额不足时,主动去汇总发生额。这里需要考虑主动汇总发生额和定时任务处理的并发情况,我们在该定时任务执行时设置redis锁,防止并发,主动汇总时会去判断这个redis锁是否存在,如存在证明定时任务正在执行,无需主动汇总,可能是真的余额不足。主动汇总同样会设置redis锁,定时任务同样会判断。

    减频账户处理
    将减频账户拆分多个子账户,减频子账户设置金额报警,如果某个减频子账户余额不足触发报警,会对该子账户做资金归集,将其他子账户余额归集到该子账户(每个子账户设置可归集金额限制)。如在交易过程中发现该子账户余额不足,转向使用其他子账户记账。由于拆分子账户,余额查询时需要汇总各个子账户余额返回;记录主账户流水需要记账后余额,这里需要异步计算汇总。当减频账户加钱时,需要平均分配入账到不通的子账户。

    双频账户处理
    将双频账户拆分多个子账户。加钱时,准实时更新余额,先将子账户金额变动插入临时表中,由定时任务按一定频率汇总发生额,将汇总的发生额更新进对应的子账户,并删除金额变动记录;减钱按照之前减频账户的逻辑执行。

    支付宝需要有个账户记账,现在很多业务已经出现了很多热点账户。比如互联网大商家,\

          账号有余额,主要用于不能扣成负数。 大并发交易下余额快速变化,导致数据库竞争等待。

          原则: 不同的业务要求,不同的设计,同时会影响业务需求. 

    三大需求,是否都容易满足:

    1.减款

    2.加款

    3.读取总金额

    最简单设计: 帐户表+流水表. 每次帐户加减款都需要增加流水,和帐户变动.

    业务需求: 高并发帐户.

    技术选择 1. 悲观锁(高并发帐户), 乐观锁(普通并发帐户).  3. 顺序化 同步转异步,mq 降低峰值.

    存储选择: redis 还是 数据库. redis本身并发能力就是比数据库要好. 但是单机支持的数据量不如数据库大. 只存放account的值的话到还好.

    账户转账分两个接口,一个可扣成负数,一个不能扣成负数.

     1 如何消除余额竞争呢?

       方案一:变成两个账户   模仿 担保交易,设置两个账户    1. 扣款账户  2. 加款账户

      1.1.  商家都是频繁加款 ,加款账户只记流水,不计算余额. 避免频繁竞争

      1.2.  加款帐户的流水定时汇总到扣款帐户上.

      1.3   扣款账户用于退款和提现, 因为频率不高.  即保证余额控制,也没有并发问题.  退款有些业务能扣成负数,有些业务不能.

      缺点: 进入的钱不一定能时时能用. (对小商家不适用,比较计较)

      优点: 这样就避免了热点账户的余额计算。

      方案二: 账户分普通账户,加频账户,减频账户,双频账户

    类型为加钱频繁账户,加钱不改变余额,定时任务收集改变。 捡钱操作时时进行。

    减频账户,拆分子账户。

    扣款只账户会有个问题,前面扣掉了,但是最后不够扣。

    最佳方案,回滚,即逆操作,加款。

    次佳方案, 使用只能扣成一次负数

    双频账户:加款依然如此,减款同上。

     延迟提现问题:即2天内收入只允许某种业务扣款(内部消费,代驾现金抵扣),但不允许提现扣款。

            采用普通账户,但是要满足提现延迟方案?

            小商家加的钱必须时时能用. 又要求延迟提现怎么办?

      只能通过订单维度,目前这个订单现在有多少钱冻结中(已退款的钱不应该冻结). 展现哪些订单是冻结的,冻结金额是多少.

                  一旦钱被消费了, 账户余额可能少于订单的冻结的金额,可提现余额可能为负数. 

           客户可能来投诉, 因为他自己意识不到钱被消费了(抵扣信息费)和提现金额变少有关联.


    原文链接:https://blog.csdn.net/xiaohanzuofengzhou/article/details/100938038

  • 相关阅读:
    《JavaScript语言精粹》小记
    JavaScript之单例实战
    浅谈requireJS
    细说gulp
    Javascript之自定义事件
    ClipboardJS复制粘贴插件的使用
    重新学习vue基础
    正则简单说明
    JavaScript字符串api简单说明
    移动端浏览器问题
  • 原文地址:https://www.cnblogs.com/duanxz/p/12463053.html
Copyright © 2011-2022 走看看