聚合支付架构从零到一

聚合支付架构从零到一

0 前言

聚合支付主要是就是一个将所有的第三方支付,通过借助形式融合在一起,相当于对接一个支付接口,就可以使用各种支付的场景。如便利店购物,贴个码,上有微信支付,支付宝等各种支付。

它主要是针对一个微小商户进行一个收款工具,让商家他那边会有一个收钱吧商户通,第一个可以实时的收听语音报告,当前用户付款多少钱,第二个就是他可以去实时查看账单,了解当天营业额。

还有一个产品就是pos机,主要是一款生态 pos,它里面不仅继承了我们一个我们这个具备支付系统提供的服务,就比如微信支付宝,它们还集成了一个刷卡的功能,就是磁条卡芯片卡,还有各种支付方式。本文聚合支付只涉及交易流,不涉及资金流。

1 V1.0系统

  • 工期短

    基本上所有新项目都这尿性,天天被领导鞭策赶进度

  • 业务不熟

    不知道聚合支付到底做啥的,支付流程啥样?毕竟每个公司支付业务其实完全不一样,无法照搬!

  • 交易量小

    当时的交易量是只有前端的一两个产品在使用,每天的交易笔数也很小

  • 人员缺乏

    新成立的团队做新项目研发,那就只有我和另一十年老鸟同事

该背景下完成 V1.0系统架构,即虚线圈,具体分工:

  • 交易前置
  • 交易网关

直接操作 DB 没做甚至缓存的优化。

  • 交易前置:支付核心业务处理,如记录商户交易流水、对接各个支撑服务
  • 风控系统:交易单日/单笔限额、商户黑名单、欺诈行为识别等风险因素控制
  • 路由系统:通过设定的优先级、限额等路由规则,选择合适的渠道,保证成功率,降低成本
  • 交易网关:负责所有支付渠道的报文包装、数据加密、协议转换、签名验证、状态映射

当时就做这样简单架构,第一个开发比较快,直接拿需求进行改代码,方便测试以及上线。经几个月交易猛增,发现

2 系统瓶颈

2.1 渠道隔离

当时对接了几个渠道,特别渠道不稳定的话,如资源不可用、网络问题,导致超时,就会把所有渠道交易全部影响,级联反应导致交易链路雪崩。系统哪边挂了之后立马要赶紧联系。所以说这个渠道隔离放在第一位首要的。

2.2 接口膨胀

特别涉及相似业务的,如消费、撤销、退款接口,就每个业务类型都有这几个接口,随业务发展,也难维护,开发每次来个需求都考虑到底是改哪个接口,要不要都改。

2.3 动态扩容

聚合支付很多交易异步,用户下单时,我们会立即返回就下单成功,或者下单失败,但是这个交易有没有消费成功,我们需要设置定时的任务去查询最终付款结果。

2.4 定时调度

它需定时、定点、定量拉取订单处理,如拉取数据太多OOM,太少很多交易得不到执行。分布式下如何充分提升并发前提下充分使用机器资源变紧迫。

2.5 配置分散

传统将配置文件存放在每个节点,每次升级都要运维手动改。风险高且不好维护。

3 V2.0系统

3.1 设计方向

  • 稳定:支付系统的根基
  • 支付体验:用户使用支付功能时感知零延迟
  • 低耦合:模块间减少依赖,需求变动风险控制在最小范围

过程试了多种方案,最终演变如下系统架构:

服务划分三条线,绿色和中间红色和最下面一条橙色:

  • 绿色:交易核心、交易网关

  • 任务作业和查询网关,独立部署

这俩业务线通过MQ解耦。

  • 再独立查询服务,对前端业务仅提供流水查询功能

3.2 业务流程

业务发起一笔消费,先进入支付核心初始化流水、风控风险识别、渠道路由、渠道网关报文组装、上送、渠道应答。异步交易发送消息至 MQ 集群,任务作业监听消息,put 缓存,定时任务拉取进行状态查询,业务方通过查询服务查看该笔交易支付状态。

3.3 前置优化水平方向

<img src="https://my-img.javaedge.com.cn/javaedge-blog/2024/06/e71bbccbed3f07350c4e9af3dc0f44f9.png" style="zoom: 33%;" />

  • 接入层:将共性接口统一。如下单,所有业务,不管微信支付还是啥,都归为下单,具体业务通过 serviceId 标识
  • 服务层:共性逻辑,也就是核心逻辑全部抽离出来,然后进行统一下沉,作为底层服务,上层业务全部通过 serviceId 配置化实现,这样的话尽量去少改动核心业务逻辑
  • 缓存层:随交易量增长,初代系统很多业务查询直连DB,有很大性能影响。所以就在 DB 之上将所有消费交易信息缓存,后续所有查询、更新操作全部打到缓存层,主要为提升服务性能

<img src="https://my-img.javaedge.com.cn/javaedge-blog/2024/06/5f72d08aad1d6c5ee454e909d6055b61.png" style="zoom:50%;" />

3.4 前置优化垂直拆分

  • 核心交易:交易核心链路,用户感知最明显。如支付失败,用户立马感知,投诉或电话客服,该模块也包含退款业务
  • 任务作业:将处理中的交易进行状态同步,和核心交易通过MQ解耦
  • 查询服务:仅对公司内部提供一个交易状态查询功能

3.5 任务作业

内部查询策略设计为两个队列、一个批处理:

  • 内存队列:实现如延迟10s、间隔5s或很多银行使用 2 的 N 次方进行查询

    该队列主要针对单笔交易执行快速状态同步,提升用户体验

    "2的N次方进行查询"这个策略一般是在系统设计中对于状态查询的优化策略。如一个操作需要查询外部系统以确认状态,第一次查询在操作完成后立刻执行,若没有得到确认,那就等待一些时间后再查询一次。这里的"等待一些时间"就可能采取"2的N次方"的间隔策略。
    如第一次查询失败后,系统会等待21(也就是2)秒再查询一次,如果还是失败,那就等待22(也就是4)秒后再次查询,以此类推。这样做的好处在于可以避免在接口繁忙的时候造成过度查询,对接口进行压力保护,同时也节省了系统资源。

  • 缓存队列:基于Redis集群,结合分布式调度框架 Elastic-Job 设计。主要针对状态延迟的订单,进行批量状态同步

  • DB批处理:结合 Elastic-Job 设计,主要提供人工干预的入口,当渠道延迟比较长、或者渠道异常的情况下,执行批量状态同步

3.6 分片策略

任务分片:把一个任务分散到不同机器运行,既解决单机计算能力上限问题,也降低部分任务失败对整体系统影响。

elastic-job 不直接提供数据处理的功能,只将分片项分配各个运行中的作业服务器(即Job 实例,部署在一台机器上的多个 Job 实例也能分片)。开发需自行处理分片项与真实数据对应关系。

数据分片:订单号取模存储(zset)

3.7 数据结构

  • 有序集合(zset):按分片逻辑,将订单号取模,存放至对应队列
  • string:交易明细序列化存储

设计思路

  • MQ 消费者(作业节点),接收到消息后,将数据存入缓存
  • 作业节点根据分片项、score 范围,定时从对应的缓存队列中获取指定数量的订单号
  • 业务循环处理,根据订单号再去缓存中获取对应的详细信息
  • 执行查询逻辑

zset元素数据过期,需业务自己处理,可单独建立检测机制,也可每次执行业务时执行判断,过期则移除,不然集合越来越大。

4 高可用设计

4.1 渠道隔离

高并发访问下,系统所依赖渠道稳定性对系统影响很大,外部依赖存在大量不可控因素,如网络连接变慢,资源突然繁忙,暂时不可用,选型容错开源框架 Hystrix,隔离方案选择 thread。

4.2 查询网关

交易系统中,查询业务量一般是支付业务的 6 倍,甚至更高,这样对查询服务性能就会有更高的要求。减少对核心交易影响,提升稳定性。

4.3 通道商户缓存

通道信息(机构号、商户号、密钥等)属静态信息,初次使用时存入分布式缓存系统(设置TTL,防止僵尸数据),同时增加手动修改的入口,方便人工干预。

  • 千里之堤毁于蚁穴:用容错就是避免蚁穴变大,依赖服务不可用时,服务调用方通过技术手段,向上提供有损服务,保证业务柔性可用
  • 线程池资源隔离:Java 的 Servlet 容器 Tomcat或 Jetty 都是多线程模型,用 Worker 线程处理请求。当业务请求打满 Worker 线程的最大值后,剩余请求被放到等待队列(或拒绝),若等待队列也满,那这台 Web Server 就会拒绝服

QPS 较高的服务,那基本上这种场景下,你的服务也会跟着被拖垮。假如上游服务也没有设置合理的超时时间,故障就会扩散。这种故障逐级放大的过程,就是服务雪崩效应。采用容错框架 Hystrix 解决此问题。 通过 Hystrix 命令模式,将每个类型的业务请求封装成对应的命令请求。每个命令请求对应一个线程池,创建好的线程池是被放入到 ConcurrentHashMap 中。

尽管线程池提供线程隔离,也要有超时设置,不能无限阻塞以致于线程池一直饱和。

Hystrix 线程监控

实时展示各业务线程池资源,研发以此为参考评估资源是否够用、是否需升级机器资源等:

2.0全面对接内部监控平台,关注:

  • 节点耗时监控:如哪个时间点、哪个节点耗时较多,通过百分比直观看出瓶颈
  • 成功率监控:折线图定时刷新数据,将各个时间点的交易记录数、成功笔数、失败笔数进行汇总计算,渠道接口异常时可以第一时间发出告警
  • 应答码监控:应答码 TOP 排行榜,方便研发分析数据,提前将问题通知给渠道,减少后续可能出现更大的问题;部分应答码重点监控,通过设定告警阀值,超过阀值短信及电话告警,研发第一时间接入处理,减少可能造成的损失
  • 邮件巡检报告:用于第二天研发自助数据分析

5 规划

  • 动态分片:包括数据分片、任务分片,业务量持续倍数增长情况,各环节分片策略如何做到自动化,充分压榨各机器性能

  • 智能路由:遇到渠道异常、临时停用渠道等case,需将用户切换至其他渠道,当下是人工拉数据手工操作,后续思考如何让路由更智能

  • 全链路的监控:我们现在链路监控只是从前端到后端有一个请求的跟踪号,但是这个都分散在我们业务日志里面的。所以说我们下一步就准备做一个全链路的监控,就相当于把每一个每笔交易,它具体在哪个时间点在哪个机器上,然后在哪个渠道,然后它状态做的什么变更,做一个完整的记录,通过一个可视化的界面提供出来,方便客服、运营等其他协作部门使用

获取更多干货内容,记得关注我哦。

本文由博客一文多发平台 OpenWrite 发布!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容