西安一码通“连连崩”,真实原因找到了!

共 2482字,需浏览 5分钟

 ·

2022-01-09 19:22

在下方公众号后台回复:JGNB,可获取杰哥原创的 6 份 PDF 手册。

近日,西安一码通半个月内连续崩溃两次,引发了业界关注,关于事件原因也引起外界诸多猜测。

西安一码通的二次崩溃,技术圈沸腾了,几乎每个技术群里都在吐槽和猜测,让我们一起来看看!

其中,知乎上的网友“27 岁是颗仙人掌”猜测,刚开始以为是服务器负载太大,但极有可能是图片优化上出现问题。

不仅如此,网络上还流传另一张图片,疑似西安一码通故障分析报告,其原因竟然是 cpu 转速过快导致内存溢出。

话说回来,吃瓜归吃瓜,但一码通崩溃的真正原因到底是什么?知乎“卢兴民”的分析较为到位,他提供了刷新二维码接口的返回数据(下图),确实很正常,并没有太大的问题。

西安健康码的接口数据:

真正的二维码数据是 /person/app/refreshQRCode 这个接口。

这位知友表示:

看下这个接口返回,设计上也没有太大的问题。


主要问题集中在所有的 js/css/img 这些静态资源全都从从一个出口进行提供,没上 CDN。


粗略估算了一下,js/css/img 数据总共约 500kB。


按照从某个群里得到的数据,暂且认为是准的,健康码的请求量峰值达到了 3.3w qps。


那按照这个量估计 33000 x 500 x 8 bps ≈ 125Gbps  这个出口量级很难用单机房承载,峰值一来,出口网卡打满,直接 gg。


到写这个回答时,西安健康码还是没有将静态资源上 CDN,之后看看访问量再起飞的时候,能不能扛得住吧。

还有一位知友 “知乎用户xv4Ddk” 就更详细了,扒证据的详细步骤都写出来了。知乎回答原文如下:

想直接抓 HTTP 包

惦记通过 PC 微信打开「西安市民一码通」抓个包,结果发现「个人电子码」注册时需要以西安的地址注册。

常住或临时地址都只能选择西安的区/县,怕万一给我健康码搞红了,所以没敢继续……

简单的路走不通,只能换一条复杂点的,那就看看这个小程序咋写的吧!

因为自己是苹果手机,于是找出之前用过的安卓模拟器(为啥不是虚拟机?因为我电脑里没有 Android Studio 之类…)

PS:我真的不是拿这个(安卓模拟器)玩游戏,我发誓……

具体步骤如下:

在安卓模拟器登微信小号,打开大号转发来过来的「西安市民一码通」小程序。

然后找到此路径下的新增文件(*.wxapkg)。

Wxapkg 就是缓存到本地的微信小程序包

把它们拷到电脑上,用一个叫「wxappUnpacker」的东西解包,拿到微信小程序源代码。

解包出来的小程序源代码

从源码的 pages\index\index.wxml 中找到了个人电子码,及其绑定的点击事件「onElectronCode」,进而跟踪到「onYmtLogin」->「toYmtLink」-> 「toElectronCode」。

找到了一码通的地址,原来是小程序打开外部网页

其中:

N = getApp(),

从源码的 app-service.js 中,找到 globalData.ymtUrl 的值:

拼接出完整 URL(就是参数不全),浏览器访问了一下。

然后发现了 qrcode.js,在里面找到了「personCodeShow」->「qrcodeColour」。

function qrcodeColour(e, t, a, o{
    var s = baseUrl + "/view/login.html?code=" + t
      , i = 300
      , r = 300
      , n = i
      , d = r
      , p = 80
      , l = 80
      , c = (i - p) / 2
      , u = (r - l) / 2
      , m = $(e).qrcode({
        render"canvas",
        text: s,
        width: i,
        height: r,
        background"transparent",
        foreground: a
    })
      , g = m.find("canvas").get(0)
      , C = new Image;
    C.src = g.toDataURL("image/png"),
    C.onload = function({
        g.width = n,
        g.height = d;
        var e = g.getContext("2d");
        e.fillStyle = "#ffffff",
        e.fillRect(00, g.width, g.height),
        e.drawImage(C, 00);
        var t = new Image(p,l);
        t.src = o,
        t.onload = function({
            e.drawImage(t, c, u, p, l)
        }
    }
}

最终结果:没有服务端生成二维码图片!

当然,目前所有的看法也都只是猜测,具体什么原因还得所在的开发团队挖掘,但是根本原因这是一起因流量过载、系统架构应对高并发不足,最终导致防火墙拦截数据无法返回的系统性故障。

总而言之,希望官方可以尽快解决好关于西安一码通的技术问题,避免因为技术故障影响正常防疫秩序。

近期推荐

网络故障的排错指南


40 张最全计算机网络基础思维导图


2021 编程语言排行榜出炉!


我的 2021 年终总结


在线运行 Linux,强的离谱!

浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报