首页 > 代码库 > 休斯顿,我们遇到了一个问题
休斯顿,我们遇到了一个问题
最近和前端同学聊得比较多,聊着聊着发现前端回报了一个诡异的错误,服务器端发给客户端的JSON错了,解不开。前端同学bs了一下服务器用的JSON库,居然连编码都会出错。我检查了所用的库,前后端的确用的不是同一个json.lua,于是跑了一次简单的压测。当然,没有发现问题。过了两天,又遇到同一个问题了,这次我留心了一下错误的详细内容:
coco/game.lua:86: coco/lib/json.lua:525: coco/lib/json.lua:240: expected colon at char 119 of: [{"res_amount":5,"id":1,"status":2,"res_type":1},{"res_amount":50000,"id":2,"status":0,"res_type":2},{"res_amount2:5,"id":3,"status":2,"res_type":1},{"res_amount":50000,"id":4,"status":0,"res_type":3},{"res_amount":7,"id":5,"status":0,"res_type":1},{"res_amount":50000,"id":6,"status":0,"res_type":5},{"res_amount":8,"id":7,"status":0,"res_type":1}]
可以看到,具体错误:
{"res_amount2:5,"id":3,"status":2,"res_type":1}
本来是引号的地方,变成了2。比较一下两者的二进制表示:
0011 0010 | 2 |
0010 0010 | " |
两者只差一个比特!再找到上一次的错误,是一个,变成了<:
0010 1100 | , |
0011 1100 | < |
看来,我们遇到了传说中的比特反转!相关的资料可以参考这篇文章。
一时好奇心起来,就写了个爬虫,爬了最近十天的日志记录(没有权限查数据库Orz),分析了约80万条日志,总共扫出了6例类似的报错。发生的机型以国产机居多,以下是点名时间(啪啪啪):
SM-G3502 |
Coolpad 8705 |
Coolpad 8720L |
HUAWEI G521-L076 |
ASUS_T00F |
vivo X3t |
品牌从三星到华为,再到接地气的coolpad都有。
相信实际上发生的比特反转几率会比这个还要多,因为发生在json字符串中间,或者json数值中间的,都不会被发现。另外,二进制打包是用protobuf做的,pb包损坏的报错其实也不少,只是这个就没法确认是1比特坏了还是多个比特坏了。据参考资料说,4G内存的PC机,每小时3bit错误到每个月3bit错误都有,而移动设备的数量比PC要多得多,所以出现这种情况一点都不奇怪。
及后,我分析了一下我们的协议收发过程,当时实现的时候没有加上验证码。如果加上了,可以补上一个包重发机制,遇到错误的包要求服务器重发。或者添加某些校验码,类似服务器内存使用的ECC,可以让只错了1bit的包恢复回来。第一次发现TCP也会不可靠,哈哈
休斯顿,我们遇到了一个问题
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。