• 休斯顿,我们遇到了一个问题


    最近和前端同学聊得比较多,聊着聊着发现前端回报了一个诡异的错误,服务器端发给客户端的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也会不可靠,哈哈

    
    
  • 相关阅读:
    k8s 资源管理
    Kubernetes核心组件
    python复习
    项目发布
    tornado
    斯巴达系统(一)
    Tornado-第三篇-tornado支持websocket协议
    Tornado-第二篇-异步非阻塞
    Tornado-第一篇-搭建网页
    python--面向对象的特殊方法(反射,内置方法)
  • 原文地址:https://www.cnblogs.com/Lifehacker/p/bitsquatting_in_tcp.html
Copyright © 2020-2023  润新知