西安一碼通“連連崩”,真實原因找到了!
在下方公眾號后臺回復:JGNB,可獲取杰哥原創(chuàng)的 6 份 PDF 手冊。
近日,西安一碼通半個月內連續(xù)崩潰兩次,引發(fā)了業(yè)界關注,關于事件原因也引起外界諸多猜測。

西安一碼通的二次崩潰,技術圈沸騰了,幾乎每個技術群里都在吐槽和猜測,讓我們一起來看看!
其中,知乎上的網(wǎng)友“27 歲是顆仙人掌”猜測,剛開始以為是服務器負載太大,但極有可能是圖片優(yōu)化上出現(xiàn)問題。

不僅如此,網(wǎng)絡上還流傳另一張圖片,疑似西安一碼通故障分析報告,其原因竟然是 cpu 轉速過快導致內存溢出。

話說回來,吃瓜歸吃瓜,但一碼通崩潰的真正原因到底是什么?知乎“盧興民”的分析較為到位,他提供了刷新二維碼接口的返回數(shù)據(jù)(下圖),確實很正常,并沒有太大的問題。
西安健康碼的接口數(shù)據(jù):

真正的二維碼數(shù)據(jù)是 /person/app/refreshQRCode 這個接口。

這位知友表示:
看下這個接口返回,設計上也沒有太大的問題。
主要問題集中在所有的 js/css/img 這些靜態(tài)資源全都從從一個出口進行提供,沒上 CDN。
粗略估算了一下,js/css/img 數(shù)據(jù)總共約 500kB。
按照從某個群里得到的數(shù)據(jù),暫且認為是準的,健康碼的請求量峰值達到了 3.3w qps。
那按照這個量估計 33000 x 500 x 8 bps ≈ 125Gbps ?這個出口量級很難用單機房承載,峰值一來,出口網(wǎng)卡打滿,直接 gg。
到寫這個回答時,西安健康碼還是沒有將靜態(tài)資源上 CDN,之后看看訪問量再起飛的時候,能不能扛得住吧。
還有一位知友 “知乎用戶xv4Ddk” 就更詳細了,扒證據(jù)的詳細步驟都寫出來了。知乎回答原文如下:
想直接抓 HTTP 包
惦記通過 PC 微信打開「西安市民一碼通」抓個包,結果發(fā)現(xiàn)「個人電子碼」注冊時需要以西安的地址注冊。

常住或臨時地址都只能選擇西安的區(qū)/縣,怕萬一給我健康碼搞紅了,所以沒敢繼續(xù)……
簡單的路走不通,只能換一條復雜點的,那就看看這個小程序咋寫的吧!
因為自己是蘋果手機,于是找出之前用過的安卓模擬器(為啥不是虛擬機?因為我電腦里沒有 Android Studio 之類…)
PS:我真的不是拿這個(安卓模擬器)玩游戲,我發(fā)誓……
具體步驟如下:
在安卓模擬器登微信小號,打開大號轉發(fā)來過來的「西安市民一碼通」小程序。

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

把它們拷到電腦上,用一個叫「wxappUnpacker」的東西解包,拿到微信小程序源代碼。

從源碼的 pages\index\index.wxml 中找到了個人電子碼,及其綁定的點擊事件「onElectronCode」,進而跟蹤到「onYmtLogin」->「toYmtLink」-> 「toElectronCode」。

其中:
N?=?getApp(),
從源碼的 app-service.js 中,找到 globalData.ymtUrl 的值:

拼接出完整 URL(就是參數(shù)不全),瀏覽器訪問了一下。

然后發(fā)現(xiàn)了 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(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)
????????}
????}
}
最終結果:沒有服務端生成二維碼圖片!
當然,目前所有的看法也都只是猜測,具體什么原因還得所在的開發(fā)團隊挖掘,但是根本原因這是一起因流量過載、系統(tǒng)架構應對高并發(fā)不足,最終導致防火墻攔截數(shù)據(jù)無法返回的系統(tǒng)性故障。
總而言之,希望官方可以盡快解決好關于西安一碼通的技術問題,避免因為技術故障影響正常防疫秩序。
近期推薦

