分享
分布式ID设计指南
输入“/”快速插入内容
分布式ID设计指南
本文根据具体业务场景取选项分布式ID生成方案
场景一:订单系统
商城买东西扫二维码,下单生成的订单号,使用到的优惠券码,这些是在购物经常使用到的单号,为什么有些单号很长,有些只有几位?下面展开分析下订单系统中不同场景的id服务的具体实现
一码付
定义
:一共二维码可以使用支付宝、微信进行扫码支付
原理
:二维码本质是一个字符串(聚合码,链接了微信、支付宝等地址),当客户用APP扫码后,网站后台会判断客户的扫码环境(微信、支付宝、云闪付等)。根据打开链接浏览器的HTTP header,header里有User-Agent(UA、用户代理)信息
◦
UA是一个特殊字符串头,服务器依次可以识别出客户使用的操作系统及版本、CPU类型、浏览器版本、浏览器渲染引擎、浏览器语言、浏览器插件等很多信息
各渠道对应支付产品的名称不一样
1.
微信支付:JSAPI支付
2.
支付宝:手机网站支付
3.
QQ钱包:公众号支付
其本质均在APP内置浏览器中实现HTML5支付
文库的研发同学在这个思路上,做了优化迭代。动态生成一码付的二维码预先绑定用户所选的商品信息和价格,根据用户所选的商品动态更新。这样不仅支持一码多平台调起支付,而且不用用户选择商品输入金额,即可完成订单支付的功能,很丝滑。用户在真正扫码后,服务端才通过前端获取用户 UID,结合二维码绑定的商品信息,真正的生成订单,发送支付信息到第三方(qq、微信、支付宝),第三方生成支付订单推给用户设备,从而调起支付
区别于固定的一码付,在文库的应用中,使用到了动态二维码,二维码本质是一个短网址,ID 服务提供短网址的唯一标志参数。唯一的短网址映射的 ID 绑定了商品的订单信息,技术和业务的深度结合,缩短了支付流程,提升用户的支付体验
订单号
订单号在实际的业务过程中作为一个订单的唯一标识码存在,一般实现以下业务场景
1.
用户订单遇到问题,需要找客服进行协助
2.
对订单进行操作,如线下收款,订单核销
3.
下单,改单,成单,退单,售后等系统内部的订单流程处理和跟进
很多时候搜索订单相关信息的时候都是以订单ID作为唯一标识符,由于订单号的生成规则唯一性决定的,从技术角度看,除了ID服务必要的特性外,在订单号的设计上需要体现几个特性:
1.
信息安全
:编号不能透露公司的运营情况,如日销、公司流水号等信息,以及商业信息和用户手机号,身份证等隐私信息。并且不能有明显的整体规律,任意修改一个字符就能查询另一个订单信息是不被允许的
2.
部分可读
:位数要便于操作,要求订单号的位数适中,且局部有规律,方便在订单异常、退货时找客服查询
a.
过长、易读性差的订单号会导致客服输入困难且易错率较高,影响用户体验的售后体验,因此在实际的业务场景中,订单号的设计通常都会适当携带一些允许公开的对使用场景有帮助的信息,如时间、星期、类型等
3.
查询效率
:常见的电商平台订单号大多是纯数字组成,兼具可读性同时,int类型相比varchar类型的查询效率更高,对在线业务更加友好
优惠券和兑换券
优惠券、兑换券是运营推广最常用的促销工具之一,合理使用它们,可以让买家得到实惠,商家提升商品销量
常见场景有:
1.
在文库购买【文库 VIP+QQ 音乐年卡】联合商品,支付成功后会得到 QQ 音乐年卡的兑换码,可以去 QQ 音乐 App 兑换音乐会员年卡
2.
疫情期间,部分地方政府发放的消费券
3.
瓶装饮料经常会出现输入优惠编码兑换奖品
从技术角度看,有些场景适合ID即时生成,如电商平台购物领取的优惠劵,只需要在用户领取时分配优惠劵信息即可。有些线上线下结合的场景,如疫情优惠券,瓶盖开奖,京东卡,超市卡等,需要先预先生成,预先生成的券码具有如下特性:
1.
预先生成,在活动正式开始前提供出来进行活动预热
2.
优惠券体量大,以万为单位,通常在10万级别以上
3.
不可破解、防止券码
4.
支持用后核销
5.
优惠券、兑换券属于广撒网的策略,所以利用率低,也就不适合使用数据库进行存储
设计思路上,需要设计一种有效的兑换码生成策略,支持预先生成,支持校验,内容简洁,生成的兑换码都具有唯一性,那么这种策略就是一种特殊的编解码策略,按照约定的编解码规则支撑上述需求
既然是一种编解码规则,那么需要约定编码空间(也就是用户看到的组成兑换码的字符),编码空间由字符 a-z,A-Z,数字 0-9 组成,为了增强兑换码的可识别度,剔除大写字母 O 以及 I,可用字符如下所示,共 60 个字符:
abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXZY0123456789
之前说过,兑换码要求尽可能简洁,那么设计时就需要考虑兑换码的字符数,假设上限为 12 位,而字符空间有 60 位,那么可以表示的空间范围为 60^12=130606940160000000000000(也就是可以 12 位的兑换码可以生成天量,应该够运营同学挥霍了),转换成 2 进制: