点击「京东金融技术说」可快速关注

支付网关研发与运营小伙伴合家欢

二零一七年六月二十一日,就是京东年中大促刚结束的那一天,我午饭时间独在办公室里徘徊,遇见X君,前来问我道,“可曾为这次大促写了一点什么没有?”我说“没有”。他就正告我,“还是写一点罢;小伙伴们很想了解支撑起这么大的用户支付流量所采用的技术。”

「摘要」由于设计时我跟小伙伴们把系统的定位更偏向于具有用户支付事务处理能力的消息总线。业务深度耦合涉及比较广,感觉一次性到位说清楚不太可能。故本篇分为上下两篇,上篇仅对支付网关架构和支付业务流程进行基本介绍,采用的全时在线技术里的基础部分说明也放在上篇,下篇则着重介绍全时在线技术的具体化应用以及下级系统重构和迁移过程中的备份切量逻辑。更详尽或代码层级的文章将后续单独推出。

        上  篇

  • 支付网关架构和支付业务流程基本简介

  • UUID并发序列生成器

  • 平行迁移

  • 本地化存储

  • 缓存双备

        下  篇

  • 自行收单、

  • 补单

  • 异步交互

  • 路由分流功能

支付网关作为京东支付目前的总入口,在最近一次618大促的实战检验中:

☀  承载的峰值用户支付流量TPS为2.2万以上

☀  承载了期间用户支付的全部流量

经过持续的优化,尤其是支付业务部成立后推动的与间联渠道融合,使整个京东支付在用户层就具备了完整的自我闭环能力,完全解决业内普遍存在依赖单支付机构的瓶颈问题。在日常和大促期间我们的系统定位主要集中在3个方面:

一、提供高效稳定的扣款支付能力

二、保障友好化的商城客户支付体验

三、高并发场景下的全时在线服务:

a)        业务模块降级

b)        基础工具模块热插拔

c)        流量分布式平行转移

本次618预先启用了分流和缓冲机制,在保证支付体验的情况下,尽可能的预防了核心业务系统、各支付机构被流量冲击打垮的情况。

支付网关架构和支付业务流程基本简介

1、支付网关的架构模块体系:

按照功能主要分为:业务模块、支付渠道模块、体验保障与高速化模块、基础工具模块。大体的纵向各个功能模块的组织谱系关系如下:

2、支付渠道(以下称为:渠道)主要为支付网关(以下称为:网关)提供了支付工具的扣款能力,网关综合各渠道的扣款能力屏蔽机构间的差异,生成核心支付组件。再结合核心的业务控制能力(风控、路由、商品订单)进行流程化封装生成对支付接口。收银台增添一些先决认证条件:生物识别,手机认证(短信、尾号)、SSO登录、设备认证通过后调用网关的支付接口进行支付。

3、详细的业务交互时序流程,以其中一个支付流程为例,大体时序为:

根据业务时序图,做过大型企业ERP、BOSS系统的人看来并不复杂。但在互联网最大的挑战就是大并发的情况。

4、网关的技术架构思想为:

  • 1. 保障核心业务逻辑稳定或无损平行转移,极端情况的下的failback

  • 2. 拆解非核心业务逻辑到异步分支流程.

  • 3. 非核心业务逻辑性能差或故障时降级,并实现failover

  • 4.   取消数据库依赖

  • 5.   基础工具组件双备甚至多备下的热插拔

UUID并发序列生成器

UUID是于2016年2月完全自主研发的业务单号生成系统,对代码进行了开源,完全遵循LGPL协议。支付单号生成是我们收单最重要的一步,由支付单号来流转整个支付流程。

它理论基础是按照能有效组织资源的最细粒度拆分服务单元,根据服务单元的属性差异进行唯一化。唯一化的服务单元互相隔离,由于具有唯一性各节点构成分布式,服务单元内部再按照能有效组织的最细粒度资源进行功能克隆拆分子服务单元,共享资源需要被其中一个子服务单元使用是进行排它独占。

实际解决的问题:生产单号多采用数据库、随机数生成,在请求量较少时问题不显著。随着请求量的加大出现重复、卡死的概率逐渐增加且部署数据库、运营成本较高。很多公司的数据库也不光给uuid使用,在海量事务处理时是常出现仅为生成id就耗费CPU时间片,造成正常业务处理延时。

具体技术实现:

我总共写过三种实现:netty、tomcat做中间件各一版、linuxC一版。我们目前生产环境中使用tomcat版本

1、注册中心的实现:因为只起到分配实例号的作用。正常情况下tomcat实例终身也只在第一次启动时获取一次实例号。由于压力不在生成实例号,简单实现的话使用数据库单表,表的自增主键作为实例号,表中的md5值为唯一键。自己也可以生成一个注册中心,只需要注意号记录md5和实例号所在文件的文件锁问题即可。生产环境当中我们使用的是mysql.

2、三种生成id的细节性问题:

  • 第一种方式是性能最高最可靠的方式。但由于加入了时间维度,如果在极短的时间内重启完毕,存在单位时间里内存递增变量归0递增后重复的概率,于是加入了延时等待的功能让单个实例启动后延时一段时间再提供id。延时的时间>=时间的维度步长。如:时间维度为1s则实例启动后至少应该延时1s在提供生成服务。

  • 第二方式:适合id号必须连续的场景,比如会计凭证号.但是第二种方式由于没有操作系统文件文件锁的保护,只能当单台机器上只有一个tomcat实例的情况下使用。

  • 第三种方式:适合id号必须连续的场景,比如会计凭证号。由于有操作系统文件锁保护适合单个机器上存在多个tomcat实例的情况使用。

注意:第二、三种方式linux系统对同时打开的文件句柄有数量限制,由于序列名跟文件名一一对应,存在文件句柄资源池管理的机制控制文件句柄能最大效率的使用和按需关闭。

3、有一些公司往往在一台机器上部署多个tomcat实例,所以向注册中心注册时使用的是$catalina.base 而不是$catalina.home.  由于我们用的是docer和jvm虚拟机,一台虚拟机上只能部署一个tomcat不用顾虑这个问题。当然程序进行通用性兼容可以让PE们部署的时候放心用。当然这也就为什么会存在第二种方式获取id方式的原因。

4、Id分单个获取和批量获取,批量获取时采用共享变量直接+批量步长的方式,而不是for循环。减小cpu时间片占用和减少锁长时间占用导致类似starvation现象的发生.

5、存在堆gc对生成id的性能影响,虽然看来非常细微,但是生成id是持久化的第一步。它的每延迟增加1ms往往带来全链路的延时放大。我们后来找到办法,在大促时段消除了gc影响。这个方法我们在后续的技术文章中会专门说明。

6、uuid的功能比较全,一个seqName对应一把线程锁或一把文件锁。

但是业务系统往往只使用一种生成方式和一个seqName。这样就不能存在多个锁和多个文件句柄有效管理的问题,因此我们业务系统的团队在这个开源代码的基础上进行了裁剪和本地化,能一直保持seqNmae对应的文件句柄打开、程序内只存在单个锁供单业务使用,进一步消除了频繁上下文切换的问题。

7、开源代码内部git地址:http://source.jd.com/app/uuid.jd.local.git

     开源代码内部svn地址:http://svn1.360buy-develop.com/buy/Finance/trunk/new_pay/code/uuid

平行迁移

B平行迁移功能,是我们做故障迁移,流量定位转移的工具。基于UUID生成实例号的原理,所有的实例数量都已经存在了注册中立里,区别在于还要把能标记自己的资源定位符也一起给出来.于是注册中心摇身一变成管理端,起到中介者的角色。以一次业务调用为例:

正常情况下:

当实例1故障时:

1、调用端并不是每次都到管理中心拿映射关系,正常情况下调用端只在第一次系统启动时到管理中心获取对端的URI并记录到本地,只要对端正常就一直会访问。实际我们调用端有个开关工功能控制出现异常时查询还是每次都查询。

2、如果每次都查询管理中心,那管理中心的性能如何保证。目前我们采用纯本地JVM的K-V类型Map + ReentrantReadWriteLock+数据库 进行解决.

3、在第1条中有说过调用端存在开关机制是异常时查询或每次都查询的开关,我们在进行服务端取余结果跟实例对应关系的时候,如果NormalCache赋值的时候以非常小的概率遇到了赋值非原子性操作的问题,无非是两种情况:

  • 一种情况:调用端在利用返回URI访问实例的时候出现异常,这个时候调用端会再去访问管理端查询URI从而避免。

  • 另一种情况:调用端利用返回的URI能正常访问实例,但是我们已经调整映射关系到希望它能访问另外一个实例。其实这个时候场景一般出现在我们密集调整对应关系的时候,这种调整和效果观察的持续时间往往不会短(肯定是秒级以上吧),这个时候我们会打开每次都查询管理中心的开关并持续一段时间,观察访问到了再切回这个开关到异常时查询从而避免。

当然如果你考量这个应用场景还是觉得不放心,那可以在读取的时候用writeLock实现.实际由于全部是内存操作、并且数据库读取在获取Lock之前,这种情况下采用Lock的性能损失接近于无,也非常好。

4、Hash一致性问题,由于这个实例号的生成逻辑是稳定的,由于是实例号是累增不会中间插入,所以目前不存在Hash一致性问题。当然有一些应用场景可能我没遇到,也欢迎大家探讨。

本地化存储

本地存储主要分为两类:

1、一般消息性存储,即把要对外发送的消息出现异常时先存储到本地,然后单独再起线程向原来的接受方进行  传输。由于目前应用场景主要面向消息队列,已经逐渐被我们的部门统一研发的mqSender取代,是对消息队列在客户端的failover机制的一种扩充。如果要是自己实现的话,单就存储而言在采用MappedByteBuffer做内存和刷盘工具+ ReentrantReadWriteLock进行线程隔离就能满足需求,就不多说了。

2、有顺序保障的结构性存储,是我们进行自行收单的基础下篇会详细讲到。如:同一笔支付需要创建支付单(类似财务的应收概念)、写支付结果(类似财务的实收概念)两个动作.业务上要顺序发生并且必须要用数据库进行持久化存储。问题是创建支付单、写支付结果这两个动作实际流程里因为中间涉及用户交互,延时掉单等问题往往存在支付结果先有,而创建支付单延时的情况或者创建支付单的很久以后支付结果才通过别的方式写入(通过银行发异步接口回调,对账单核对)。

  • 首先交易系统层的小伙伴已经把支付结果和支付单放到不同的表内,做insert操作而不是update。其次是如果入库操作出现异常他们首先也会入缓存,等数据库情况变好后再调度入库。等同一笔支付的支付单、支付结果都存在缓存或数据库时再发起下级非实时业务。

  • 而在支付网关的场景是:调用交易系统出现网络失败,写入延时较高的情况下先断掉与交易系统的交互自行发送保存创建支付单和支付结果到缓存和本地。是由于取消了数据库存储,不使用扫描库的方式。而是使用java的io事件selector进行。通过监听SelectionKey.OP_READ事件,根据同一个payid到本地文件和缓存内进行条件判断。判断创建支付单、写支付主任务都成功后再发送消息。

缓存双备双切

在京东研发体系内有两个自主研发类似redis的缓存系统:JIMDB和R2M,我们同时采用。目的是预防其中中一个出现问题能自动或立即切换到另外一个,采用主从异步模式进行互切:

1、写入时同步写数据到主缓存,异步写数据到从缓存。

2、读取时采用先从主缓存读取,出现异常和超时再在从缓存中读取。如果主缓存使用写入失败,立即调整主从对应的实际缓存。

其实只需要在set和get的时候加一个中间层,与Concurrent框架里的Executor的newCachedThreadPool(ThreadFactory threadFactory)类似,这个结构和实现比较简单:

未完待续

那上篇就到此结束了,下篇将会重点介绍基于这些技术的上层应用功能:

  • 为取消数据库依赖而使用的自行收单、补单功能。

  • 为增加并发量而使用的异步交互功能。

  • 最重要的为预防支付机构挂掉而使用的路由分流功能。

  • 为保证下级系统进行重构使用的切量平移功能。

  • 以及为保障历次618,双11活动提前进行的保障和洪峰消解工作。

京东金融技术说

▼▼▼

原创·实用·技术·专业

不只一技之长

我有N技在手

你看,我写,共成长!

支付网关 | 京东618、双11用户支付的核心承载系统上篇相关推荐

  1. 互联网快讯:京东公布“双11”节奏;猿辅导、掌门教育布局素质教育

    零售电商 1.京东公布"双11"节奏:10月20日晚8点正式开启预售,10月31日晚8点提前开抢 2.达达快送发布即时配送SaaS系统"达达智配",赋能配送服务 ...

  2. “动员商家”策略相继而出,天猫京东吹响“双11”号角

    双11跨过十二个年头,现在正处于预热前奏. 各大电商平台"摩拳擦掌",吹响"商家动员"冲锋号.今年,天猫和京东的招商举措已然发布,对比两者的差异,这个双11能否 ...

  3. 2021年京东预售双11什么时候开始?

    2021年京东双十一详细时间,2021年京东预售双11什么时候开始? 前面小编赵一八笔记分享了淘宝.天猫双11活动时间节奏,本篇文章小编就来和大家分享2021年京东双11预售时间.跨店满减.正式售卖时 ...

  4. 实战:618/双11大促备战全流程点点滴滴

    目录 一.系统架构 二.备战流程简介 三.大促备战内容 四.技术备战流程 4.1.关于自动化 五.技术备战实操 5.1.应用篇 2.1.负载篇 2.3.监控篇 六.稳定性保障 6.1.容量规划 6.2 ...

  5. 京东发布双11首份战报:手机品类18秒销量突破万台

    11月1日消息,京东今天对外公布11.11全球好物节首份战报,从全平台的搜索数据来看,iPhone 11.华为Mate30.AirPods Pro成为消费者关注度最高的三个商品. 具体来看,家电产品方 ...

  6. 京东购物车双11实战

  7. 京东618技术解析之高可用多中心交易平台

    京东618技术解析之高可用多中心交易平台 分流是应对互联网业务流量峰值时保证系统高可用的常规方法,但涉及交易系统的分流是很难的.京东在备战2015年618时就开始了多中心交易的改造,让用户就近访问交易 ...

  8. 拿下618,京东祭出AI备战双11

    近日,京东与博文视点联合发布了书籍<决战618:探秘京东技术取胜之道>,会后,京东集团高级副总裁马松.京东商城首席架构师刘海锋.京东商城中台研发高级总监王晓钟三人,就京东如何备战即将到来的 ...

  9. 看懂“天猫双11”支付技术的前世今生,就看懂新商业的变革基础

    今年的"天猫双11支付技术沟通会"近日在杭州召开,蚂蚁金服副总裁胡喜等出席了沟通会,并对天猫双11支付技术进行了展示和解说. 过去两年,围绕天猫双11,蚂蚁金服对外强调较多的是支付 ...

  10. 【备战】双11未到战火先燃,天猫京东苏宁各打各的牌

    很快,一年一度的双11就要来临.去年双11,天猫已经连续第七年创造新的记录,交易额达到912亿元.今年突破千亿,似乎也毫无悬念. 事实上,如今的双11,已远不止于一次购物狂欢,它已经演变成一种商业奇迹 ...

最新文章

  1. 关于组织参加2021年全国大学生 智能汽车竞赛东北赛区比赛的报名通知
  2. thinkphp学习笔记7—多层MVC
  3. Verilog RTL 代码设计示例
  4. 10年软件开发教会我最重要的10件事[转]
  5. Java ClassLoader setDefaultAssertionStatus()方法与示例
  6. python远程登录并执行命令_Python - 远程SSH执行命令
  7. VScode同步配置和插件步骤
  8. pygame游戏_Pygame游戏——Pong游戏(三)
  9. Android SDK Setup如何使用?
  10. 通俗理解博弈论相关术语
  11. 布谷鸟优化算法 matlab,布谷鸟算法(Cuckoo Search,CS)MATLAB案例详细解析
  12. 排序算法整理(冒泡、选择、快排、堆排序、希尔、归并)
  13. C语言简易程序设计————7、输出特殊图案
  14. 屌丝程序员的2012
  15. java写 狐狸找兔子_狐狸找兔子(java 版)
  16. git最佳实践之feature和hotfix分支
  17. wiki服务器网页地址,搭建个人wiki站点
  18. python批量分析表格_python批量设置多个Excel文件页眉页脚的脚本
  19. 二分查找,返回第一次出现的位置
  20. SAT语法之指示代词知识点

热门文章

  1. 两个线程交替打印A1B2C3D4E5输出,6种实现方式
  2. 【JS】秒杀倒计时制作
  3. 法信智推搜索引擎_法学工具分享
  4. 鲁棒性的含义以及如何提高模型的鲁棒性
  5. OpenWRT配置 -- 网络配置network文件
  6. SQL中如何处理除数为0的情况?
  7. **一些常用的字体英文名**
  8. 猪齿鱼开源四周年庆典,邀您共享精彩瞬间
  9. 默安科技关键信息基础设施安全防护论文入选中文核心期刊
  10. 我的团长我的团第二十四集