这是《百图解码支付系统设计与实现》专栏系列文章中的第(3)篇。
?专栏地址:http://t.csdnimg.cn/2L7Mg
本章主要讲清楚支付系统中各子域的业务ID为什么要统一规范,以及最佳实践。
数据库一般都会设计一个自增ID做为主键,同时还会设计一个能唯一标识一笔业务的ID,这就是所谓的业务ID(也称业务键)。比如收单域有收单单号,支付域有支付号,渠道网关域有渠道支付号等,这些都属于业务ID。
为什么有了自增ID后,还需要有业务ID呢?一般来说有以下几个核心原因:
互联网支付系统基本都是微服务化部署,每个子域都是相对独立的一些同学在研发,架构实现差异非常大,但是业务ID是必须要统一的。主要有以下几个原因:
业务ID生成规则有很多种,比如知名的Snowflake算法,UUID算法,时间戳+随机数/序列号等。以下是部分规范的简要介绍。
组成:时间戳 + 数据中心标识 + 机器节点 + 序列号。
适用场景:无中心化的环境中生成大量的唯一ID,无具体业务语义,且性能要求极高。比如社交媒体的聊天消息记录。
高度唯一且随机。
适用场景:不想让外界感知内部系统的交易量级。比如调用外部渠道的请求号,如果使用序列号,有可能会让外部猜测出交易的规模。
特定组织中心化生成。
适用场景:药品或供应链管理,全球范围内标识或追踪商品。
把一些业务语义编码到ID中。
适用场景:金融支付、电商订单等。
下面以32位的支付系统业务ID生成为例说明。实际应用时可灵活调整。
第1-8位:日期。通过单号一眼能看出是哪天的交易。
第9位:数据版本。用于单据号的升级。
第10位:系统版本。用于内部系统版本升级,尤其是不兼容升级的时候,老业务使用老的系统处理,新业务使用新系统处理。
第11-13位:系统标识码。支付系统内部每个域分配一段,由各域自行再分配给内部系统。比如010是收单核心,012是结算核心。
第14-15位:业务标识位。由各域内部定,比如00-15代表支付类业务,01支付,02预授权,03请款等。
第16-17位:机房位。用于全球化部署。
第18-19位:用户分库位。支持百库。
第20-21位:用户分表位。支持百表。
第22位:预发生产标识位。比如0代表预发环境,1代表生产环境。
第23-24位:预留。各域根据实际情况扩展使用。
第24-32位:序列号空间。一亿规模,循环使用。一个机房一天一亿笔是很大的规模了。如果不够用,可以扩展到第24位,到十亿规模。
序列号通常采用数据库生成,保证机房内唯一性。
简要流程如下:
这里使用指定步长去更新数据库,主要是考虑提高性能。但是存在一定的损失,比如发布重启,缓存中的序列号就会被浪费掉。但因为是循环使用,所以基本上对业务没有影响。
本章主要讲了业务ID是什么,业界常见生成规则及适用场景,以及支付系统业务ID生成的最佳实践。
如果大家发现文章里面有写得欠妥的地方或想讨论的点,欢迎留言或发邮件到yinmo_sc@qq.com。