edyang

我干了什么 究竟拿了时间换了什么
技术分享时间线软件开发、设备接入、视觉与运维实践

大型支付系统学习:超时、重试与结果未知

网络超时最危险的误解,是把“没有收到成功响应”当成“对方没有执行”。

网络超时最危险的误解,是把“没有收到成功响应”当成“对方没有执行”。 本文使用Java 7 与支持事务、唯一约束的关系数据库,代码为设计伪代码。支付系统同时面对用户请求、外部通道和本地账务,三者不共享一个事务。网络异常下必须保留“不确定”状态,并用查询、流水和对账逐步消除差异。 1. 从现象推到机制 请求可能在发送前失败,也可能已到达通道但响应丢失。无幂等约定的写操作不能盲目重发;先查...

大型支付系统学习:对账不是只比较总金额

双方总金额一样,仍可能存在一笔多记、一笔少记。

双方总金额一样,仍可能存在一笔多记、一笔少记。对账需要逐笔身份与汇总校验结合。 本文使用Java 7 与支持事务、唯一约束的关系数据库,代码为设计伪代码。支付系统同时面对用户请求、外部通道和本地账务,三者不共享一个事务。网络异常下必须保留“不确定”状态,并用查询、流水和对账逐步消除差异。 1. 从现象推到机制 先按通道流水、业务日期和币种对齐数据,再比较状态、金额和手续费。对账单缺失、...

大型支付系统学习:金额精度与账务分录

用浮点数计算金额,可能在累计和比较时产生难以解释的差异。

用浮点数计算金额,可能在累计和比较时产生难以解释的差异。账务模型需要先定义货币单位。 本文使用Java 7 与支持事务、唯一约束的关系数据库,代码为设计伪代码。支付系统同时面对用户请求、外部通道和本地账务,三者不共享一个事务。网络异常下必须保留“不确定”状态,并用查询、流水和对账逐步消除差异。 1. 从现象推到机制 可以用最小货币单位的整数,也可以用明确精度与舍入规则的十进制。构造 B...

大型支付系统学习:回调验签以后还要核对什么

一个通知通过签名校验,不代表金额、订单和状态都可以直接写入本地。

一个通知通过签名校验,不代表金额、订单和状态都可以直接写入本地。 本文使用Java 7 与支持事务、唯一约束的关系数据库,代码为设计伪代码。支付系统同时面对用户请求、外部通道和本地账务,三者不共享一个事务。网络异常下必须保留“不确定”状态,并用查询、流水和对账逐步消除差异。 1. 从现象推到机制 签名证明报文来自持有密钥的一方,并保护约定字段的完整性。还要核对商户身份、订单归属、币种、...

大型支付系统学习:用唯一键约束重复请求

用户重复点击、网关重试和超时补发都可能把同一个业务请求送来多次。

用户重复点击、网关重试和超时补发都可能把同一个业务请求送来多次。 本文使用Java 7 与支持事务、唯一约束的关系数据库,代码为设计伪代码。支付系统同时面对用户请求、外部通道和本地账务,三者不共享一个事务。网络异常下必须保留“不确定”状态,并用查询、流水和对账逐步消除差异。 1. 从现象推到机制 幂等键代表一次业务意图,不是每次网络调用都生成新键。数据库唯一约束决定哪一个请求首次占位,...

大型支付系统学习:订单状态不能只靠一个成功标记

用户页面显示成功,与服务端确认到账,必须来自不同可信度的证据。

用户页面显示成功,与服务端确认到账,必须来自不同可信度的证据。 本文使用Java 7 与支持事务、唯一约束的关系数据库,代码为设计伪代码。支付系统同时面对用户请求、外部通道和本地账务,三者不共享一个事务。网络异常下必须保留“不确定”状态,并用查询、流水和对账逐步消除差异。 1. 从现象推到机制 内部订单、支付尝试和通道流水分别建模。一笔订单可能重试多次,但每次通道请求应有独立身份。状态...

透彻学习 JDK:阻塞队列如何连接生产者和消费者

队列解耦了生产和消费速度,但不能消除速度差。

队列解耦了生产和消费速度,但不能消除速度差。队列满时的行为必须提前设计。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 有界阻塞队列用有限容量吸收短时波动,put 可以等待空间,offer 可以立即返回或带超时。消费者变慢后,等待会向生...

透彻学习 JDK:对象不可用了,为何还没被回收

业务不再使用对象,与垃圾回收器判定它不可达,是两套不同的标准。

业务不再使用对象,与垃圾回收器判定它不可达,是两套不同的标准。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 垃圾回收从根集合沿引用图寻找仍可达的对象。静态集合、长寿命线程和监听器都可能意外保留对象。把局部变量设为 null 只能断开其...

透彻学习 JDK:堆、线程栈与永久代怎样区分

都叫内存不足,扩大堆却未必有效。

都叫内存不足,扩大堆却未必有效。排查 JVM 问题要先读异常类型和对应区域。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 Java 7 的对象主要分配在堆,线程调用使用各自的虚拟机栈,类元数据涉及方法区及 HotSpot 的永久代实现...

透彻学习 JDK:Future 超时以后任务停了吗

等待结果超时,只说明调用方停止等待。

等待结果超时,只说明调用方停止等待。后台任务可能仍在运行,并继续占用资源。 本文使用JDK 7,示例为方法体或类定义片段。源码学习需要区分语言规则、公共接口约定与某个版本的实现。本文把讨论范围固定在 Java 7,不把后续版本的集合结构或语法写进来。 1. 从现象推到机制 Future.get 的超时不自动取消任务。cancel(true) 尝试中断执行线程,任务仍须检查中断或调用可中...