發表文章

目前顯示的是 六月, 2015的文章

使用 Node.js 實作 server push

前幾天才說用 Tornado 實作 server push 很簡單, 且可以直接用在上線環境裡。今天要來自打嘴巴說我要改用 Node.js 了。有興趣了解相關基本知識的人, 可以參閱之前的說明。 Python 圈 event-based framework 的問題如這篇文章所述, Python 天生不是 async, 既有函式庫自然也不是 async, 使用 event-based framework (*1) 後, 要另外找配套的函式庫。比方說 http client 用慣了 requests, 直接拿到 Tornado 裡用會出事, 因為 Tornado 是 single process single thread 的架構, 一發出網路連線就會 block 住全部動作。要嘛改用 Tornado 提供的 httpclient, 不然就要找別人用 Tornado 提供的 API 包好的 requests。 每套函式庫都這樣找頗麻煩的 (資料庫、第三方服務的 SDK、etc), 而且不見得找得到牢靠又有效率的版本, 比方說 Google API Python Client 就沒有 Tornado 版的, 要自己想辦法弄。以前用 gevent 時作過類似的事, 先搞定 Dropbox Python SDK, 再來搞不定 Google Drive API, 只好用 gevent monkey patch。感覺不是很可靠。 Node.js 的優勢反觀 Node.js 天生就是 async, 既有函式庫自然也是 async。Google 也有提供 Google API Node.js Client。既有的社群也滿龐大的, 可以用的套件很多。對我來說, 這點最重要。 效能方面, 因為使用 V8 轉成 native code 執行, 表現也不錯。從這裡這裡的 benchmark 來看, 數值計算大勝 CPython, 然後和 PyPy 持平。我自己比較常用 dictionary, 作個簡單的 benchmark 測試使用 for, if 和 dictionary, 結果 Node.js 小勝 PyPy, 然後大勝 CPython。整體來說執行速度夠用了, 到是記憶體有 1.7G 的限制 (64bit OS 預設 1G), 要多留意一下。 使用 Express 作 web…

server push by long polling

程式碼沒興趣讀落落長心得的人, 這裡有用 Tornado 實作的程式測試碼。 心得server push 是指從 server 主動送訊息給 client, 這裡有圖解一些達成 server push 的方式。其中我個人偏好 long polling 的作法,運作方式就和字面一樣: client 先發出一個連線, server 不要立即回應。等 server 需要主動通知 client 時, 再回傳資料。這個作法的好處是: 各種 client 都適用, 只要能用 http 連線即可, 不是瀏覽器也OK, 現在各個平台都有好用的 http 函式庫。 不用擔心 client 網路環境問題。client 能主動建立往 server 的連線, 反過來就很難說了。 另一方面, long polling 的缺點是 server 會有許多閒置的連線占資源。像 apache 這類每個 client 用獨立的 thread 處理連線的作法, 就不適合處理 long polling。假設一個 thread 占據 10MB 空間, 1k 個不作事的連線, 就占掉 10G 記憶體了。另外大量 thread 之間的 context switch 也是可觀的時間負擔。 但是改用 epoll 之類的 API 寫成 event-driven 的架構, 可用 single process single thread 的方式同時處理大量連線, 就沒有浪費記憶體和 context switch 的時間負擔。現在有不少現成的工具使用 epoll 包成 green thread, 使用上和 multi-thread 一樣容易上手 (而且還不用擔心 race condition, 因為實際上只有一個 native thread),降低實作門檻。其中 Tornado 是 Python 寫成的 web framework 並內建可上線用的 web server。我作了簡單的 benchmark, 的確可以快速反應一秒內同時擁入的一千個連線。用 Tornado 省去不少工夫 (若不想用 web server 而是自己從頭作 server, 也可用 gevent)。 實作 long polling 的另一個問題是: 如何在察覺資料更新時, 能立即通知 client? 想像 client 透過連線 S 連往…

apache ab 使用 post 傳資料

用法: $ cat post.txt key=value&key2=value2 $ ab -n 1000 -c 1000 -p post.txt -v4 -T 'application/x-www-form-urlencoded' http://.../ 注意使用 -p 指定 post data 時,同時必須用 -T 指定傳送 content type 為'application/x-www-form-urlencoded。反應不如預期時可用 -v 輸出收到的資料,協助除錯。

Chrome NaCL 開發心得小記

目前開發到一半, 先加減記一下。之後有多什麼心得再來補充。 為什麼要用 NaCL自然是方便重用既有的 C/C++ 程式啦。 雜項 NaCL 無法在本機檔案中執行 (file://...)。web pages、Chrome Web App、 Chrome Extension 才能用 NaCL。若要在本機試 web pages 的話, 需要跑 local web server。NaCL SDK 內有附一個 local web server, Getting Started 的範例用 make serve 執行 local web server。建議先玩 Getting Started 裡面的兩個範例, 了解 NaCL 的架構。 有支援 POSIX 和 ptherad, 還算堪用, 不過 port Linux 的程式時會遇到很多 Linux 才有但 POSIX 沒有的程式碼 (網路、時間、pthread 各式各樣都有)。 分成 PNaCL (編成 bitcode 執行檔, 使用前再轉成執行檔) 和 NaCL (native binary)。若需要放到 Chrome Web Store, 後者比較不方便, 得編多份不同平台的 binary 得用 NaCL SDK 附的工具, 我試過用 nm 和 ar 都無效, 改用 NaCL SDK 附的 llvm-nm 和 llvm-ar 才有正常結果。 若想使用 stdio 的函式 (如 FILE 相關函式), 要另外使用 nacl_io library。需要在 Makefile 補上 -I$(NACL_SDK_ROOT)/include -I$(NACL_SDK_ROOT)/include/pnacl 和 -lnacl_io除錯參考資料: 官方文件 1. 基本的除錯方式是透過 stderr 導到執行 Chrome 的 terminal (預設行為), 或寫到 DevTools 的 console (透過 /dev/console1 ~ 3)。 但是導到 DevTools console 的輸出會被限制行寬, 超出的字會被截掉。還有由於 stderr 是 unbuffered, 輸出會亂掉, 若想將 stderr 導到 /dev/console1, C/C++ 程式內記得改設 stderr 為 line buffer ( setl…

在 Ubuntu 14.04 上編 stable chromium 43

參考資料Get the Code: Checkout, Build, Run & Submit - The Chromium Projectsdepot_tools_tutorial(7)Chromium Development Calendar and Release Info - The Chromium Projects 步驟 1. 從這裡找到最近的 stable version VERSION 2. 取得程式和安裝相依套件 $ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git $ export PATH=$PATH:/path/to/depot_tools $ fetch --nohooks chromium $ fetch --nohooks blink $ cd src $ ./build/install-build-deps.sh $ git checkout VERSION # 可和 git tag 對照一下 $ git show VERSION # 取得 commit 編號 COMMIT $ (edit ../.gclient) # 設 "safesync_url" 為 COMMIT $ gclient sync --with_branch_heads # 沒有 --with_branch_heads 會出錯 3. 產生編譯所需的檔案和編譯 $ cd /path/to/chromium/src $ gclient runhooks $ ./build/gyp_chromium $ ninja -C out/Debug chrome