01 交易记录
1.1 完整性
在线支付交易记录通常应该包含以下信息:
信息 | 详情 |
交易编号 | 每笔交易的唯一标识符,用于查询和核对。注意:
|
商户信息 | 交易的接收方,包括商户名称和商户编号。 |
用户信息 | 进行交易的用户信息,用户唯一ID,用户名等。 |
交易金额 | 交易的金额,包括货币单位。 |
支付渠道 | 交易是通过哪个平台或服务进行的,例如支付宝、微信支付等。 |
交易类型 | 例如购买商品、服务费用、转账等。 |
支付方式 | 使用的支付方式,如信用卡、借记卡、电子钱包、银行转账等。 |
交易状态 | 交易是否成功、失败或待处理。 |
交易时间 | 记录交易发生的确切日期和时间。 |
手续费 | 如果适用,交易过程中产生的任何手续费。 |
退款信息 | 如果交易被退款,相关的退款详情。 |
其他信息 | 业务方透传信息等。 |
1.2 不可变更性
一旦交易被录入并确认(终态),为了保证交易的完整性和可追溯性,不应该被直接修改或删除。如果需要更正错误或取消交易,应该通过创建新的记录来进行。以下是实现交易记录不可变性的一些关键技术和方法:
方案 | 详情 |
---|---|
时间戳和数字签名 |
|
加密技术 |
|
共识机制 |
|
不可变数据结构 |
|
分布式存储 |
|
区块链技术 |
|
1.3 一致性
1.3.1 分布式事务
方案 | 简介 |
2PC | 两阶段提交(Two-phase Commit,2PC),通过引入协调者(Coordinator)来协调参与者的行为,并最终决定这些参与者是否要真正执行事务。
|
TCC | TCC 其实就是采用的补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。它分为三个阶段:
|
本地消息表 | 通过在每个本地事务中增加消息表的操作,来保证最终一致性。如果本地事务成功,消息会发送到消息队列;如果失败,则进行重试或补偿。 |
消息事务 | 使用消息中间件来异步处理分布式事务,通过发送prepare消息并根据本地事务的执行结果来提交或删除消息,适用于高并发场景 |
最大努力通知 | 适用于最终一致性要求不高的业务场景,通过不断尝试执行业务逻辑并处理失败情况,直到成功或放弃。 |
1.3.2 分布式缓存
热点参数缓存:热点参数数据的特点是读取频繁,更新较少。例如:机构数据、业务属性、业务规则等数据。热点参数数据进行缓存后,应用对热点参数的查询基于缓存实现,将大大减轻数据库的负载压力,加速应用访问。
1.3.3 不一致场景
-
主从延迟
现象 | 读写分离时,写操作走主库,读操作走从库,但是主库的变更还未同步至从库。 |
原因 |
|
解法 |
|
-
数据库和缓存不一致
现象 | 数据更新不同步,数据库中的数据更新后,缓存中的数据未及时更新,导致读取的是旧数据。 |
原因 |
|
解法 |
|
1.4 幂等性
1.4.1 数据库主键/唯一索引
-
select + insert + 主键/唯一索引
-
直接insert + 主键/唯一索引
-
抽取防重表
1.4.2 状态机+CAS
在支付系统中,状态机可以用于管理支付交易的生命周期,确保交易的每一步都按照既定的流程进行,同时处理可能出现的各种异常情况。
CAS(Compare-and-Swap)机制对于状态机的意义在于实现状态的原子性切换,保证状态的一致性。CAS机制是一种无锁并发控制技术,它允许多个线程在没有使用锁的情况下对共享资源进行操作,通过比较和交换的方式,确保只有一个线程能够成功更新共享资源的值。在状态机的上下文中,CAS机制可以用于实现状态的原子性转换,即多个线程可以同时尝试改变状态机的当前状态,但只有一个线程的操作能够成功,这保证了状态转换的原子性和一致性。在支付系统中,“状态机+CAS”是一种保证幂等性的重要手段。
TIPS:当我们设计系统时使用整数作为状态机状态时,建议状态之间预留间隙---状态扭转方向应当符合数字增长方向,预留间隙为后续状态机扩展状态时候依然满足该约束。
1.4.3 锁机制
-
悲观锁:悲观锁则适用于写操作频繁、数据竞争激烈的场景。乐观锁适用于写操作较少、数据冲突较少的场景,。
-
乐观锁:上文所述的“状态机+CAS”极为一种常用的乐观锁机制。
-
分布式锁:常使用Redis SETNX,zookeeper等技术实现,核心需要注意锁超时、延期、释放、重入等问题。
02 资金安全
资金安全是一个较为宏大的话题,将在后续文章《浅谈在线支付之资金安全》中进行介绍。
03 数据安全
3.1 加签验签
在线支付系统中的加签和验签是确保交易安全的重要技术手段,用于确保数据完整性,防止数据篡改,验证身份,提高交易安全性。
3.1.1 加签验签过程
3.1.2 注意事项
事项 | 详情 |
签名内容 | 在签名的时候需要注意前文所述的支付系统上下文信息应该被作为签名内容。 |
签名算法 | 使用非对称签名算法如RSA. |
签名协议 | 尽量使用统一的签名协议,常见的方式为使用同样的签名和验证签名的SDK。但实际开发场景中可能出现跨团队、跨技术栈等而难以统一,此时交互双方应该就签名协议达成一致,加签一方应该提供demo给验签方。 |
编码问题 | 在数字签名过程中,参数的编码(encode)和解码(decode)是确保数据一致性和安全性的关键步骤。 |
密钥更换 | 实现签名密钥的定期更换是确保在线支付系统和网络安全的重要做法,这里需要强调的是密钥变更的过渡期管理,在密钥变更的过渡期内,系统能够接受用旧密钥或新密钥签名的数据。过渡期的长度应根据系统的具体需求和用户的更新速度来确定。 |
3.2 加密解密
加密技术主要用于保护数据在存储和传输过程中的安全性,防止敏感信息被未授权访问或泄露。其中:
-
对称加密:对称加密使用同一个密钥进行数据的加密和解密,常用的对称加密算法包括DES(Data Encryption Standard),AES(Advanced Encryption Standard)等。
-
非对称加密:非对称加密使用一对密钥,即公钥和私钥。公钥用于加密数据,而私钥用于解密。这种加密方式常用于密钥交换和数字签名,其中RSA是支付行业中应用最广泛的非对称加密算法。
3.3 敏感信息
3.3.1 敏感信息内容
类型 | 详情 |
支付密码 | 支付密码是用于支付鉴权的重要信息,一旦泄露会对用户的财产安全造成严重危害。应采取加密措施确保其在传输和存储过程中的安全性 。 |
银行卡信息 | 包括银行卡号、银行卡磁道数据或芯片等效信息、卡片验证码(CVN)、卡片有效期等。这些信息在传输和存储时必须进行加密处理,避免明文传输和存储 。 |
个人身份信息 | 如身份证号码、护照号码、客户法定名称(姓名)、手机号码等。这些信息在展示和传输时需要进行屏蔽或脱敏处理,防止泄露 。 |
交易信息 | 包括交易金额、支付记录、交易日志等。在处理交易信息时,应确保其在传输过程中的保密性和完整性,避免被未授权的第三方获取 。 |
生物识别信息 | 如指纹、人脸、虹膜等生物特征样本数据。这些信息应符合国家、金融行业标准和相关信息安全管理要求,防止被非法存储、复制或重放 。 |
支付指令 | 支付指令应真实、完整、有效,且在支付交易完成后,应显示支付结果,支付失败的应显示失败原因 。 |
支付敏感信息 | 包括但不限于支付密码、银行卡密码、验证码、卡片有效期、生物特征以及未获客户授权的金融信息。应通过支付标记化技术应用等手段,从源头控制信息泄露和欺诈交易风险 。 |
3.3.2 敏感信息处理原则和措施
原则 | 详情 |
最小化原则 | 只收集与业务直接相关的信息,避免收集无关的个人信息 。 |
加密传输 | 使用加密通道或数据加密的方式进行传输,保障信息传输过程安全 。 |
安全存储 | 对敏感信息进行加密存储,避免明文存储 。 |
信息屏蔽 | 在展示敏感信息时,应采取信息屏蔽或脱敏处理,降低泄露风险。 |
用户授权 | 在收集和使用敏感信息时,应获得用户的明示同意 。 |
安全评估 | 在共享、转让或委托处理敏感信息时,应进行安全影响评估,并采取相应的保护措施。 |
04 性能和效率
4.1 分库分表
-
分库分表的作用
作用 | 详情 |
提升性能 | 通过分散数据存储和访问压力,提高数据库的读写速度和查询效率。 |
增加可用性 | 将数据分布到多个数据库中,降低单点故障的风险。 |
扩展能力强 | 可以根据业务需求灵活扩展数据库资源。 |
-
分库分表的实现方式
方式 | 详情 |
垂直分表 | 基于列字段进行拆分,适用于表字段较多且部分字段不常使用或数据量较大的情况。 |
垂直分库 | 针对系统中的不同业务进行拆分,如将用户、商品、订单等信息存储在不同的数据库中。 |
水平分表 | 按照某种规则(如范围、HASH取模等)将单张表的数据切分到多张表中。 |
水平分库分表 | 将数据切分到多个服务器上的不同数据库和表中,有效缓解单机和单库的性能瓶颈。 |
-
分库分表的步骤
步骤 | 详情 |
目标评估 | 根据当前数据量和未来增长预期,评估需要拆分成的库和表的数量。分库分表必然带来系统的复杂性,单库单表能够支持的情况下请勿过度设计。 |
拆分策略 | 选择合适的拆分策略,如按日期、主键范围、HASH切分等。 |
字段选择 | 选择最佳的分库分表字段,如主键ID、时间字段、地理信息字段等。 |
代码改造 | 修改应用程序中的查询和更新语句,以适应分库分表后的情况。 |
数据迁移 | 进行数据的全量和增量同步,确保数据从旧库迁移到新库的一致性。 |
校验和补偿 | 在迁移完成后,对比新老库数据,进行必要的数据补偿。 |
-
面临的挑战和问题
问题 | 详情 | 一般解决思路 |
数据一致性 | 在分库分表后,保持数据的强一致性变得更加困难。 | 分布式事务 |
路由问题 | 需要正确路由数据到对应的数据库和表。 | 本地路由或公共组件路由 |
查询优化 | 多库结果集合并、跨库join等查询操作可能受到限制。 | 使用ES、ClickHouse等聚合数据 |
数据倾斜 | 分库分表拆分策略和字段选择不合理时,可能带来数据倾斜问题。 | 在制定策略的时候需要对数据分布进行评估 |
4.2 异步化
4.2.1 外部调用异步化
在文章《浅谈在线支付之交易类型》中,我们对支付系统中不同的交易类型加以介绍,其中在涉及到同第三方支付渠道外部调用均为异步调用,如充值交易类型:
4.2.2 并行化
串行 | |
并行 |
4.2.3 非核心链路异步化
在线支付系统中,核心链路通常指的是直接参与交易处理、资金流转和用户交互的流程。而非核心链路不直接参与支付交易处理,可以异步化,如:
场景 | 详情 |
用户通知 | 交易完成后向用户发送的邮件通知、短信通知等,可以异步发送。 |
外部服务调用 | 与支付流程不直接相关的外部服务调用,如CRM系统更新、库存管理等。 |
营销活动触发 | 交易完成后触发的营销活动,如积分累计、优惠券发放等,可以异步处理。 |
风险评估与监控 | 交易风险的评估和监控,可以异步进行,不影响交易流程。 |
日志记录与存储 | 交易日志的记录和归档。 |
数据分析与报告 | 对交易数据的分析和生成报告,可以异步进行,不影响交易的实时处理。 |
审计 | 交易的审计跟踪记录。 |
4.3 热点账户
关于“热点账户”的处理思路请阅读文章《浅谈在线支付之热点账户》。
05 系统稳定性
关于稳定性建设的思路请阅读文章《关于“稳定性建设”的一些思考》,本节结合在线支付的业务场景对“隔离”进行介绍,以下是在线支付中实现隔离的一些思路。
隔离类型 | 详情 |
链路隔离 | 将支付系统中的关键服务和非关键服务在逻辑上分开。 |
业务隔离 | 在线支付系统通常涉及多个业务场景,不同业务场景的重要性、优先级存在差异,对于核心的业务应当重点保障。将不同业务场景隔离开来,可以减少相互之间的影响。如果一个业务出现问题,不会波及到其他业务。 |
物理隔离 | 将核心支付处理系统放置在与非核心系统物理上分开的服务器或数据中心,以减少潜在的物理安全风险。 |
服务隔离 | 为不同的服务分配独立的服务账户和权限,确保服务之间无法相互访问敏感数据或关键操作。确保支付应用和非支付应用在操作系统层面上隔离,比如使用容器化技术或虚拟化技术。 |
组件隔离 | 将支付系统中的不同组件(如前端、后端、数据库访问层等)进行隔离,减少一个组件的故障或安全漏洞影响到整个系统的风险。 |
故障隔离 | 设计支付系统时,考虑到故障转移和冗余,确保在某个组件或服务失败时,核心支付链路可以继续运行。 |