一、序言
全渠道零售的背景下,随时随地购物已经融入了民众的生活,在此背景下对支付系统的要求也更高了。支付系统面临着线上场景无法预知流量的考验,支付系统很可能会变成一个秒杀系统;同样也面临着线下可能出现的“无法付款,付款慢,重复扣款”的问题,但线下没有线上的流量那么不可预测,也不会爆发式增长。如何打造一个适用于线上线下全渠道的7*24小时高可用支付系统呢?本文分享一下多点支付系统的经验,希望对您有所启发。
二、支付系统整体架构

多点支付系统总体上采用同城双活,异地灾备的部署方式,保证支付服务的可用性,并且针对线上业务和线下业务的不同特点在同一机房内拆分线上、线上服务。为了最大保证支付服务的可用性,采用“同城双活,异地冷备”的部署方案,即机房分属两个不同地区,同城当中两个机房是“双活”,即活跃的主机房;异地机房作为“冷备”,作备用机房。目前多点已经实现了线下支付业务主机房支付服务故障自动切换冷备机房,并且能做到主机房恢复后自动切回主机房。新零售线上与线下业务场景存在着天然的差异,线下受限于超市、便利店、商场的客流量、收银终端数量等因素,并不会出现流量的爆发增长,可以认为线下场景并发数的峰值就是收银终端的数量;另外线下出现问题更容易激发顾客与商户的矛盾,当超市因不能结账而排长队时,商户的面临的压力会非常大,当然作为系统、服务提供商也会面临很大的压力。线上业务不同于线下,线上的访问量存在不确定性,并发量难以预算,尤其是三方支付做营销活动时,就很可能出现访问量出现十倍、百倍的增长。大家思考一个问题,当线上业务访问量激增时,是不是不能影响线下的门店业务?正式由于对上述新零售线上、线下业务的思考,我们做出了拆分线上、线下服务的方案。
三、线上支付 - 这是个“秒杀”系统
常见问题
1.三方支付的整点秒杀支付优惠活动,导致系统流量瞬时提升(流量远大于正常的商户大促)
优惠力度较大的活动如下:
1)6.2银联节9:00满50元-25元,名额有限先到先得
2)电信翼支付9:00满60元-30元,名额有限先到先得
机智的顾客会在优惠活动开始前5分钟左右下好订单,并提前进入收银台选择好支付方式,在整点点击确定支付。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
2.三方支付故障导致无法支付
三方支付也会存在偶尔不可支付的极端情况,顾客只能更换可用的支付方式,完成支付操作。技术实现
1.限流
每个系统都有承受的流量极限,限流作为系统高可用的利器,必不可少,限流的目的是保护系统,但也不能影响业务,因此设置一个合理的限流阈值尤为重要。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
总:域名限流
根据系统的QPS,制定支付系统总的限流阈值。总阈值的大小一般都是通过接口压测来确定系统的阈值是多少,当然系统的阈值是否合理还要参考实际的业务流量。分:网关对单个支付方式限流
支付方式的流量占比各不相同,微信、支付宝两个支付方式占比较大,在设置阈值时需要结合实际流量情况制定每种支付方式的阈值大小。
2.缓存
缓存作为高可用的另一利器,也是必不可少的。缓存方案没有最正确的,只有适合自己的,结合自己的业务流量与公司的技术储备做出适合自己的缓存策略即可,下图是多点支付系统对基础配置的缓存策略。' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
1) 首选读取应用服务中的本地堆缓存,堆缓存采用guava cache实现
2) 没有命中本地堆缓存时,则会读取redis中缓存
3) 若redis缓存也未命中,则回源DB。此步需要注意,需要做好访问数据库的控制,避免大流量冲击数据库
4) 将数据异步写到redis
3.降级
最后介绍一下降级,主要从多点支付系统的角度来讲。
1) 非必要流程,可做服务降级
对于支付流程而言,最重要的莫非是订单号、支付金额、三方商户号,除此之外的例如支付营销是可以做降级处理的。要做到这一点首先要从支付产品、用户体验的角度去思考哪些是必要的流程,哪些是可以降级的非必要流程。2)系统自动降级
加载银台:系统内部异常时,可以考虑自动降级,返回兜底的支付方式,例如:只返回微信、支付宝。支付动作:作为聚合支付平台,通常对外暴露一个支付接口,自动降级的使用需要谨慎,很可能会出现一个支付占比较高的支付方式出现问题,导致整个接口被降级,最终所有的支付方式都不能支付。3)人工开关降级
多点目前服务的商家非常多,尽管做了通用的收银台配置,那也存在数十、甚至上百条的收银台支付方式配置。当某个支付方式出现问题需要下线时,一个一个修改配置做下线处理无疑是会让运营同学骂娘的。此时需要一个开关,通过控制开关就能实现快速下线、上线某个支付方式。仔细想一想线上曾经出现的故障或问题,你的支付系统中,是不是也需要这样的开关呢?四、线下支付
产品理念
7 * 24小时服务在线,顾客支付成功,就可拿货离店就像前文分析,线下门店内容易因为货款的问题发起矛盾,纠纷。所以我们对线下支付产品的理念是:支付服务永不宕机,顾客说的算,只要顾客提供支付成功的凭证,就可拿货离店。常见问题
1、顾客支付成功,POS未收到结果
这个问题应该是线下最普遍的问题了,导致该问题的原因比较多,例如:接口超时,网络问题等。2、支付系统依赖的内部系统故障,导致无法收银
就像降级一节中的分析,只要有支付环节必要的因素,就可完成支付。其余的流程例如,变更订单状态、写台账等都可通过最终一致性的方式保证业务系统数据的对齐。技术实现
1.冷备
为确保支付服务 7 * 24小时可用,在同城双机房的基础上,在加上异地冷备的方案,就基本上确保了支付服务的可用性。支付冷备环境简易架构如下
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
冷备环境的主要特点
无状态,只为支付这一件事负责
足够简单,不依赖任何内部的系统
不迭代,非必要则不进行版本迭代
冷备监控,保证冷备环境的可用性
“热 - 冷” 如何切换
1) 支付系统作为决策者:支付系统根据异常判断是否启动切换(数据库异常、内部系统异常),如需切换返回指定错误码,POS收到错误码则自动切换至冷备。
2) POS作为决策者:支付系统网络不通,支付接口连续报错等异常则自动切换至冷备。
■恢复切回“热”
1) 切回“热”的动作由POS端完成,POS会在切“冷”期间对“热”环境进行监控,当“热”环境连续多次都没问题时,则切回“热”。
注:如何对“冷”环境进行监控?可以使用一个过期的付款码进行支付,若返回付款码过期,则表明“冷”环境的链路已经打通。
增加手动切换,则又增加了一道保障,确保“热”环境出问题时能切到“冷”,确保业务正常。手动切换可在网关层面设置特殊错误码,POS收到错误码则切换至冷备。
2.“确认支付成功”
网络抖动、支付超时、三方响应慢等情况经常会造成顾客支付成功,但是POS没有收到支付成功的响应结果。遇到这种问题,收银员确认顾客已经支付的前提下,可以使用“确认支付成功”功能,因为顾客确实支付成功了,那么数据一致性的问题可以晚一点进行修复。五、上线流程
谈到高可用就必须面对系统上线的问题,你是否也面对着版本迭代快需要频繁发布上线、系统上线期间影响业务的问题?作为程序员,我们都能理解,系统存在bug是正常的,就连大厂、顶级公司的产品也会有问题。那有没有办法来减少因bug带来的影响呢?当然有,上线流程的标准化能帮我们将bug带来的影响降到最低。上线的原则:灰度先行,再走蓝绿
我们把线上的环境分为:灰、蓝、绿。
灰组:作为预发环境,新版本代码必须先发布到预付环境并且验证全流程,通常预发环境只有测试流量或少量的正式流量
蓝组:作为正式环境,默认承接50%的线上流量
绿组:作为正式环境,默认承接50%的线上流量
灰组发布就在展开讨论,只要正常的发不上线即可,当然前提是不要把正式的流量引入。接下来讨论一下蓝绿如何发布。主要流程如下:' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)
本文更多的是从多点支付系统出现的问题和解决方案的角度去讨论如何实现高可用,今年10月24日下午14:00-18:00,D+Talks 2021多点技术大会将拉开帷幕,欢迎识别下图二维码参加线下活动,与行业大咖共同探讨更多的可行方案!
' fill='%23FFFFFF'%3E%3Crect x='249' y='126' width='1' height='1'%3E%3C/rect%3E%3C/g%3E%3C/g%3E%3C/svg%3E)