能退化的探索之旅
發現問題
這一切開始于一個警報,首頁應用的錯誤率高于 4% 的閾值。
顯示數千個錯誤頁面對我們的用戶產生了切實的影響(還好 CDN 緩存抵消一部分影響)。
被用戶看到的錯誤頁面
應用程序的錯誤日志顯示,該應用程序沒有任何有關 top stories 的數據。
診斷問題
首頁的工作原理是在一個時間間隔內輪詢 GraphQL api 以獲取數據,將該數據存儲在內存中并根據請求渲染它。從理論上講,如果請求失敗,應該保留之前穩定的數據。進一步深入日志,我們看到對 GraphQL api 的請求失敗了,但是是有錯誤而不是超時——或者至少是不同類型的超時。
FetchError: response timeout at https://….&source=next-front-page over limit: 5000
奇怪的是,API 的響應時間似乎遠低于首頁設置的 5 秒超時。這讓我們相信問題出現在首頁和應用程序之間的連接上。我們做了些嘗試——在兩者之間使用 keepAlive 連接,分散請求,這樣它們就不會同時發起。這些似乎都沒有產生任何影響。
更神秘的是 Heroku 上顯示的響應時間。第 95 百分位數約為 2-3 秒,而最大值有時達到 10-15 秒。由于首頁被 Fastly 高度緩存,包括 stale-while-revalidate 頭,許多用戶可能不會注意到。但這很奇怪,因為首頁真的不應該做很多工作來渲染頁面。所有數據都保存在內存中。
首頁的 Heroku 響應時間
因此我們決定對本地運行的應用程序副本進行一些分析。我們將通過使用 Apache Bench 每秒發出10個請求,共發出 1000 個請求來復制一些負載。
使用 node-clinic 和 nsolid,我們可以對內存、CPU 和應用程序代碼有更深的理解。運行它們,確認我們可以在本地復現該問題。首頁需要 200-300 s 才能完成測試,超過 800 個請求不成功。相比之下,在文章頁面上運行相同的測試需要大約 50 秒。
測試用時:305.629 秒
完成的請求:1000
失敗的請求:876
而且你看,n-solid 的圖表顯示事件循環的滯后超過 100 毫秒。
在做加載測試時事件循環滯后
使用 n-solid 的 CPU 分析器,我們可以精確定位阻塞事件循環的確切代碼行。
火焰圖顯示導致滯后的函數
修復問題
罪魁禍首是...
return JSON.parse(JSON.stringify(this._data));
對于每個請求,我們使用 JSON.parse/stringify 來創建數據的深克隆。這種方法本身不壞 —— 可能是深克隆比較快方法之一。但它們是同步方法,因此在執行時會阻塞事件循環。
在我們的案例中,這個方法在每個頁面渲染(對于每個被渲染的部分)中多次調用,具有大量數據(每次執行時整個頁面所需的數據),并且我們有幾個并發請求。由于 Javascript 是單線程的,因此這將對應用程序嘗試執行的所有其他操作產生連鎖反應。
深克隆數據的原因是,我們會根據請求中的一些信息(例如,是否啟用了特定功能的切換),來改變對象。
為了解決這個問題——并減輕克隆所有內容的需要——我們在檢索時對對象應用了深度凍結,然后在數據被改動的地方克隆特定位。這仍然執行同步克隆——但僅限于更小的數據子集。
結論
修復好后,我們重新運行了負載測試,并在很短的時間內完成,0 次錯誤。
測試用時:37.476 秒
完成的請求:1000
失敗的請求:0
我們發布了修復程序,看到響應時間和錯誤()立即減少,并希望一些用戶開心!
修復后首頁的響應時間
關于未來
作者:IridescentMia
鏈接:https://juejin.im/post/5b7bb6dfe51d4538bf55aa5f
迎點擊右上角關注小編,除了分享技術文章之外還有很多福利,私信學習資料可以領取包括不限于Python實戰演練、PDF電子文檔、面試集錦、學習資料等。
用 Python 快速實現 HTTP 服務器
有時你需臨時搭建一個簡單的 Web Server,但你又不想去安裝 Apache、Nginx 等這類功能較復雜的 HTTP 服務程序時。這時可以使用 Python 內建的 SimpleHTTPServer 模塊快速搭建一個簡單的 HTTP 服務器。
SimpleHTTPServer 模塊可以把你指定目錄中的文件和文件夾以一個簡單的 Web 頁面的方式展示出來。
假設我們需要以 Web 方式共享目錄 /Users/Mike/Docker,只需要以下這個命令行就可以輕松實現:
$ cd /Users/Mike/Docker $ python -m SimpleHTTPServer Serving HTTP on 0.0.0.0 port 8000 ...
SimpleHTTPServer 模塊默認會在 8000 端口上監聽一個 HTTP 服務,這時就可以打開瀏覽器輸入 http://IP:Port 訪問這個 Web 頁面。例如類似下面的 URL:
http://192.168.100.49:8000
如果你需要 Web 服務有一個默認頁,可以在目錄下創建一個名為 index.html 的文件。如果沒有默認頁,那么會以列表的形式將目錄中的內容顯示出來。
如果默認的 8000 端口已經被占用,你想換成使用其它端口號,可以使用如下的命令:
$ python -m SimpleHTTPServer 8080
用 Python 快速實現 FTP 服務器
有時當你想快速搭建一個 FTP 服務器來臨時實現文件上傳下載時,這是特別有用的。我們這里利用 Python 的 Pyftpdlib 模塊可以快速的實現一個 FTP 服務器的功能。
首先安裝 Pyftpdlib 模塊
$ sudo pip install pyftpdlib
通過 Python 的 -m 選項將 Pyftpdlib 模塊作為一個簡單的獨立服務器來運行,假設我們需要共享目錄 /Users/Mike/Docker,只需要以下這個命令行就可以輕松實現:
$ cd /Users/Mike/Docker $ python -m pyftpdlib [I 2018-01-02 16:24:02] >>> starting FTP server on :::2121, pid=7517 <<< [I 2018-01-02 16:24:02] concurrency model: async [I 2018-01-02 16:24:02] masquerade (NAT) address: None [I 2018-01-02 16:24:02] passive ports: None
至此一個簡單的 FTP 服務器已經搭建完成,訪問 ftp://IP:PORT 即可。例如類似下面的 URL:
ftp://192.168.100.49:2121
如果你要建一個有認證且可寫的 FTP 服務器,可使用類似以下指令:
$ python -m pyftpdlib -i 192.168.100.49 -w -d /tmp/ -u mike -P 123456
小插曲:測試時一直使用密碼 000000 這樣的弱密碼做認證密碼,在客戶端登陸時一直提示認證失敗。看來 Pyftpdlib 模塊還做了基本的安全策略喲,不錯的!
常用可選參數說明:
-i 指定IP地址(默認為本機所有可用 IP 地址) -p 指定端口(默認為 2121) -w 寫權限(默認為只讀) -d 指定目錄 (默認為當前目錄) -u 指定登錄用戶名 -P 指定登錄密碼
更多參數可以使用以下指令查詢:
$ python -m pyftpdlib --help Usage: python -m pyftpdlib [options] Start a stand alone anonymous FTP server. Options: -h, --help show this help message and exit -i ADDRESS, --interface=ADDRESS specify the interface to run on (default all interfaces) -p PORT, --port=PORT specify port number to run on (default 2121) -w, --write grants write access for logged in user (default read-only) -d FOLDER, --directory=FOLDER specify the directory to share (default current directory) -n ADDRESS, --nat-address=ADDRESS the NAT address to use for passive connections -r FROM-TO, --range=FROM-TO the range of TCP ports to use for passive connections (e.g. -r 8000-9000) -D, --debug enable DEBUG logging evel -v, --version print pyftpdlib version and exit -V, --verbose activate a more verbose logging -u USERNAME, --username=USERNAME specify username to login with (anonymous login will be disabled and password required if supplied) -P PASSWORD, --password=PASSWORD specify a password to login with (username required to be useful)
如果你需卸載 Pyftpdlib 模塊,可以通過以下命令:
前話
Hello,小伙伴們大家新年好,本篇是今年第一篇,也籌劃許久,本篇主題為美食,系html5網站模板,div加css布局,網頁資源分開存儲以便管理,網頁結構清晰簡單,希望本篇能夠助力各位萌新
主題
《周末の食記》
美食能撫平一切的憂傷
簡介
文件結構包含了css、fonts、images、js和html,運用html5技術,包括nav標簽、header標簽和footer標簽等,采用bootstrap進行布局
圖摘
目錄
編碼
<div class="ftco-46-row d-flex flex-column flex-lg-row">
<div class="ftco-46-text ftco-46-arrow-right">
<h4 class="ftco-46-subheading">Food</h4>
<h3 class="ftco-46-heading">揚州炒飯</h3>
<p class="mb-5">一碗不一樣的炒飯,讓你難以拒絕.</p>
<p><a href="#" class="btn-link">更多 <span class="ion-android-arrow-forward"></span></a></p>
</div>
<div class="ftco-46-image" style="background-image: url(images/img_3.jpg);"></div>
<div class="ftco-46-text ftco-46-arrow-up">
<h4 class="ftco-46-subheading">Food</h4>
<h3 class="ftco-46-heading">藍莓酸奶冰激凌</h3>
<p class="mb-5">觸動您的心靈,令人甜蜜至極,難以忘懷,心曠神怡的味覺享受,精選一級的夏威夷果仁,入口絲滑</p>
<p><a href="#" class="btn-link">更多 <span class="ion-android-arrow-forward"></span></a></p>
</div>
</div>
結語
如果人的一生總的能量是固定的話,那就節省開支,延長時間,喜怒哀樂不溢于言表,不困于心智,保持樂觀心態
*請認真填寫需求信息,我們會在24小時內與您取得聯系。