这两天,因为西安一码通的二次崩溃,几乎我所在的每个技术群里都在吐槽和猜测。
权威媒体也在拷问着,西安大数据资源管理局局长停职检查...。
知乎上也开了个贴讨论:一码通崩溃的技术原因是什么?
昨天看到的最热回复如下:
注意这里一个细节!答主跟大部分人一样,开始以为是服务器负载太大,但之后又转到了图片优化上的表达,这里提到了一篇陕西电信的文章。
小编我找了找,想不到有网友直接贴出来了。
看完之后,我的第一反应是老血差点喷出来...。亏得西安曾经宣传将打造“中国程序员之都”。
这下直接在微博引起热搜,微博有很多大V说出了自己的看法,大部分直接认为是技术跑偏了...,直接生成图片下发啦。
这里我要说的是,“ 一码通的技术团队在菜,也不会犯这种低级错误,直接low到服务器生成图片进行下发这么蠢。”
首先先看一下西安健康码的接口数据。
真正的二维码数据是从上图 /person/app/refreshQRCode这个接口生成。
然后又找到了qrcode.js,在里面找到了「personCodeShow」->「qrcodeColour」。
代码语言:javascript复制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(0, 0, g.width, g.height),
e.drawImage(C, 0, 0);
var t = new Image(p,l);
t.src = o,
t.onload = function() {
e.drawImage(t, c, u, p, l)
}
}
}
这段代码表示人家根本没有直接生成图片,而是 canvas (动态)。所以不要再狂喷了...。
接下来在看这个接口返回,设计上也没有太大的问题。
主要问题集中在所有的js/css/img这些静态资源全都从从一个出口进行提供,没上CDN。
CDN可能有些小伙伴不太懂,CDN也叫作CDN服务器。可以理解成一个离和你距离很近的、方便从上面获取完整的原始数据的服务器,为保证用户可以从上面获取到最新的内容,它会定期和拥有原始内容的服务器进行同步更新。
通俗的解释:比如你的城市有很多一模一样的连锁超市,一家离你的住所很近,另一家很远,那么你会选择去哪一家?一般人都会选去近的那家,对吧?CDN服务器就相当于是离你近的那家超市。
如果只有一家超市,大家同一时间购买,超市还不堵死...,就是这么个道理。
回归正题,粗略估算了一下,js/css/img数据总共约500kB。按照从某个群里得到的数据,暂且认为是准的,健康码的请求量峰值达到了3.3w qps。
那按照这个量估计 33000 x 500 x 8 bps ≈ 125Gbps 这个出口量级很难用单机房承载,峰值一来,出口网卡打满,直接挂掉。
如果西安健康码还是没有将静态资源上CDN,之后看看访问量再起飞的时候,看能不能扛得住吧?