介绍
在一般的分布式系统或者电商系统中,订单号被用来索引某个文档或者实体对象。
每个人都是独一无二的,在社会层面,国家用你的身份证号来标记你的信用,追踪你的守法记录;在家庭层面,昵称是用来表达亲人姓名的;在群聊中,昵称是用来彰显个性的。
内部和外部订单号是什么?
正如同一个人在不同的语境中可能会有不同的名字,同一个实体在不同的语境中也可能有多种表达方式。
例如以下是商户请求微信支付系统分账的API:
内部订单号和外部订单号的区别
外部订单号是由外部传递到内部系统,内部订单号由内部系统生成。
这里的内部系统指的是微信支付系统,外部系统指的是使用微信支付系统的用户。因为这是一个商家平台,所以外部系统指的是接入微信支付的电商系统,比如沃尔玛、京东等。
外部订单号的作用
外部订单号一般有两个作用:
首先,它用于外部系统记录自己的文档,更重要的是,当外部系统请求内部系统时,它作为请求的幂等性键,避免请求被多次验证。
关于幂等性的更多信息,可以参见 API 中的幂等性概念。简单来说,就是为了防止一个请求因为各种原因(比如手抖导致点击两次,或者服务超时导致系统自动重试)被系统内部接收两次,从而使得原本只打算发生一次的请求,实际却被执行了两次。
如果幂等设计不好,点击一下「抽奖」,可能实际抽了两次。
内部订单号
内部订单号主要用来记录实体的类型,存储信息(路由,分库分表等),日期信息。还有一个重要字段-随机数,用来区分不同的实体。
成分:
单据类型:标记单据的类型,是子发票还是退款单。 路由信息:标记实体存储的路由信息,方便查找和检索日期信息;标记实体的创建日期,方便数据迁移、存储优化、问题定位。 随机数:当以上参数相同时,区分不同的实体。 分布式随机数生成算法 ID 生成算法:
IP(机器ID/进程ID)+时间戳+本地唯一ID(机器/进程内唯一)重点:
当机器时钟回拨时,订单号可能会重复
在一定的时间毫秒内,最多可以生成10^x个随机数;并且数据库自增ID生成算法是单调递增的:
依赖第三方数据库,利用每件商品主键表的唯一特征作为唯一ID的关键点:
并发性不高;数据规律暴露纯随机数生成算法:
根据雪花ID,使用随机数生成器生成ID,生成后写入DB,若发现主键冲突,则生成新的关键点:
适合并发特别大的场景,需要均衡数据大小,平均重试次数等多级缓存生成算法:
使用随机生成服务器,服务器管理随机数段,客户端每次从服务器获取一批数据,实际消费完成后再从服务器获取。重点:
两者都会在本地缓存一些数据,以减少通过频繁的RPC获取数据所花费的时间。
「预估交易量」:
关于订单号中的随机数的设计,如果只是增加,外界可能会猜测其生成模式,从而推断出交易量等商业敏感数据。
“不愁吃不愁穿”:
由于第三方支付机构在用户中的普及率较高,其订单号被普遍认为是随机生成的,具有一定的权威性。据八卦消息称,黑产曾花费巨资竞标某全国性第三方支付机构的订单号生成算法,或提供实时对单服务。2020年被曝2kw/月的价格,2019年又被曝3kw/月的天价。
如果真有人有这个渠道,并且跟黑产行业交易成功的话,一个月之内就能保证他一辈子不愁吃穿。
参考:
唯一ID生成算法分析
9 种分布式 ID 生成方法