欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

万恶的IEEE754规范直接让雪花算法全盘崩

程序员文章站 2022-01-07 09:48:48
万恶的IEEE_754规范 ,直接让雪花算法全盘崩1.事情为什么发生?事情还要从ID的架构说起...

万恶的IEEE_754规范 ,直接让雪花算法全盘崩

1.事情为什么发生?

事情还要从ID的架构说起,ID在架构师的要求下,我们改成了雪花算法(Snowflake)生成ID

简单的介绍一下雪花算法,SnowFlake算法生成id的结果是一个64bit大小的整数,它的结构如下图:
万恶的IEEE754规范直接让雪花算法全盘崩

SnowFlake可以保证:

  1. 所有生成的id按时间趋势递增
  2. 整个分布式系统内不会产生重复id(因为有datacenterId和workerId来做区分)

这样在遇到系统扩容,分库分表,数据迁移的场景下都不会出现太大的问题

大家伙一讨论,都觉得非常合理,就决定一股脑用雪花算法生成主键ID了

例如现在这样:

527574217068392807


527574217068392808

2.问题产生

问题是我们测试发现的,测试发现有些用户查询列表会没有值,我们把测试的ID放到数据库一查询,库内无此数据

后来我们发现后端返回的数据和前端提交上来的数据是不一样的,ID不同

万恶的IEEE754规范直接让雪花算法全盘崩

3.问题验证

也就是说,一个好好的数字:527183991665594368,经过浏览器一翻译,变成了527183991665594400。

我们在浏览器的devtools里面调试一下。

万恶的IEEE754规范直接让雪花算法全盘崩

4.为什么

这是因为。在JavaScript中,存在两种数字。Number和BigInt。最常用的,就是number。

最大的Number,叫做Number.MAX_SAFE_INTEGER,它的值为:

  • 2^53-1 或者

  • +/- 9,007,199,254,740,991

众所周知,Java中的Long,是64位的。Js中的这个安全Integer,完全达不到Java中定义的长度。

这就是万恶的IEEE_754规范,它在Long长度大于17位时会出现精度丢失的问题。

在最新的TypeScript3.2中,可是直接使用BigInt这个类型进行编码,或者使用long.js这种封装后的苦,但还是太麻烦了,需要编码太多,而且还可能漏掉。

使用数字类型,传输数据,实在是不太靠谱,转来转去,就物是人非了。

最好的方式,就是使用string进行传递。哪怕以后后台ID的长度变成了128位的,也不惧怕这种转换。

5.End

这问题,明显不是后端的锅。后端传递了正确的数据到前端,能不能处理、处理的正确不正确,根本和后端一点关系都没有

能力越强,责任越大。

实事求是,严谨细致。

本文地址:https://blog.csdn.net/u013605060/article/details/110530025