微信支付系统的单号原来是这样设计的

引言

在一般的分布式系统,或者是电商系统,用单号来索引到某一笔单据,或实体对象。

每个人都是独立无二的,在社会层面,国家用身份证号码来标记你的征信,追踪你的遵纪守法记录。在家庭层面,用昵称来表达对亲人的称谓。在群聊中,用花名彰显个性。

微信支付系统的单号原来是这样设计的_第1张图片

什么是内外部单号

就像同一个人在不同的场合,有不同的称谓一样,同一个实体在不同的上下文可能有多种表达方式。
比如下面的是商户请求微信支付系统分账用例的api:

微信支付系统的单号原来是这样设计的_第2张图片
  • 请求包的字段列表中包括商户分账单号字段,要求商户在请求微信支付系统时,需要填写一个外部单号,用来标识此次请求,也就是外部系统标记的微信支付系统的分账单号。
微信支付系统的单号原来是这样设计的_第3张图片
  • 返回包中的字段列表中包含微信分账单号字段,它是微信支付系统返回的,在其内部系统唯一的,用于标识分账单的单号,属于内部单号

内外部单号的区别

外部单号是外部传到内部系统的,内部单号是内部系统生成的。
此处的内部系统指微信支付系统,外部系统指使用微信支付系统的用户,因为此处为商户平台,所以外部系统指接入微信支付的电商系统,如沃尔玛京东等等。

外部单号的作用

外部单号一般有两个作用:

  1. 首先,外部系统用于记录自身的单据
  2. 更重要地,外部系统请求内部系统时,作为该次请求的幂等键,防止该请求被多次生效。

关于幂等可以看API中幂等的概念,简单来说就是为了防止各种原因(如手抖点击两次,或者系统因服务超时而自动重试),导致一个请求被内部系统收到两次,从而原本只想发生一次的请求,被实际执行两次。

微信支付系统的单号原来是这样设计的_第4张图片
如果幂等设计不好,点击一下「抽奖」,可能实际抽了两次。

内部单号

内部单号主要用于记录该实体的类型,存储信息(路由,分库分表等),日期信息。另外还有一个重要字段–随机数,用于区分不同实体。

组成部分:

  1. 单据类型;标记该单据是什么类型,是分账单,还是退款单
  2. 路由信息;标记该实体存放的路由信息,便于查找检索
  3. 日期信息;标记该实体的创建日期,便于数据迁移、存储优化、定位问题
  4. 随机数;上述参数相同时,区分不同实体

分布式随机数生成算法

雪花ID

  1. 生成算法:
    IP(机器标识/进程标识)+时间戳+局部唯一ID(在机器/进程内唯一)
  2. 关键点:
    机器时钟回拨时,可能引起单号重复
    在某一个时间毫秒内,最大可生成10^x个随机数;且是单调递增的

数据库自增ID

  1. 生成算法:
    依赖第三方数据库,利用每条Item主键表内唯一的特性,作为唯一ID
  2. 关键点:
    并发不高;数据规律暴露

纯随机数

  1. 生成算法:
    在雪花ID的基础上,用随机数发生器进行生成ID,在生成后写入DB,如果发现返回主键冲突则更换重新生成一个
  2. 关键点:
    适用于并发量特别大的场景,需要均衡好数据规模,平均重试次数等。

多级缓存

  1. 生成算法:
    使用随机生成服务器,服务器管理随机数号段,客户端每次从服务端获取一批数据。实际消耗完毕后再向服务端重新获取。
  2. 关键点:
    server和client都会本地缓存一些数据,减少频繁rpc获取数据的时间

两则轶事

  1. 「推测交易量」:

    关于单号中随机数的设计,如果是仅仅递增的话,可能被外界猜测到其生成规律,可推测出交易量等商业敏感数据。

  2. 「衣食无忧」:

    由于第三方支付机构对用户的渗透率较高,其单号被广泛认为是随机生成的,具有一定的权威性。据小道消息,黑产斥巨资报价购买某国民级第三方支付机构的单号生成算法,或进行实时查单服务。在2020年已爆出2kw/月价格,在20201年更是爆出3kw/月的天价。

微信支付系统的单号原来是这样设计的_第5张图片

如果真有dxd有这渠道并且与黑产交易成功的话,不出一个月,就能可以保证这辈子「衣食无忧」了吧。

参考:

唯一ID生成算法剖析
9种分布式ID生成方式

你可能感兴趣的:(互联网金融,分布式系统,业务建模)