網頁

搜尋此網誌

2014年5月21日 星期三

Node.js 伺服端事件驅動非阻斷式平台

Node.js 是一個建於 V8 JavaScript 引擎上的一套伺服端平台,採用 JavaScript 程式語言,Node.js 使用事件驅動 (event-driven)、非阻斷式 (non-blocking) 的輸入/輸出模型,因此具有輕量級、高效率的特性,特別適合用於資料密集 (data-intensive)、即時 (real-time) 的應用領域。

為什麼創造Node.js

Node.js 的創造者瑞安‧達爾 (Ryan Dahl) 在 Node: Up and Running 一書的前言說明 Node.js 的緣起。Ryan 在2008年尋找用於建置網站的程式語言平台,他注意到推送 (server push) 這項技術,伺服器將資料推送給用戶,而不是讓使用者以輪巡 (polling) 的方式取得。當時的方式是,伺服器接收請求後,依序發送資料給用戶端,伺服器本身必須處理一堆開啟且閒置的連線,這顯然不是個好方法。

Ryan 知道 C 語言如何解決這個問題,使用 Non-Blocking Sockets 的方式可以有效降低閒置連線的成本 (overhead),因此一台伺服器將能處理上千個閒置連線並且有很高的吞吐量 (throughput)。不過這種方法有兩個問題:
  1. Ryan 不想使用 C 語言開發,他想使用動態語言。雖然任何程式語言可以用系統呼叫的方式做,但那會讓程式碼變醜,也僅是另一種Socket程式設計罷了。
  2. 他認為使用 Non-Blocking Sockets根本上是困難的,只要是 Non-Blocking 的方法就會讓開發變得困難。
在 2008 年 9 月 Google 發表 Chrome 瀏覽器和高效能 JavaScript 引擎 V8 ,執行較快的 JavaScript 引擎可以讓網頁速度更快,而 V8 確實讓網頁執行速度快了很多,突然間Google, Apple, Mozilla, 和 Microsoft 開始在 JavaScript 引擎上展開競賽。與此同時,Douglas Crockford的「JavaScript:優良部分」這本書的出版,讓鄙視的 JavaScript 變成一種重要的程式語言。

Ryan 有個偉大的想法:JavaScript 的 Non-Blocking Sockets,由於 JavaScript 沒有現成的 Socket 程式庫,所以 Ryan 可以是第一個引進這種 Socket ,並希望提供更好的介面。他所要做的事是:將高效能 JavaScript 引擎 V8 結合 C 語言開發的 Non-Blocking Sockets,Ryan 辭掉他的工作,全心全意實現這個想法。

JavaScript 與 Non-Blocking Sockets 結合得非常好,這個特點不是一開始就很明顯清楚的。閉包 (closure) 讓一切都有可能,人們可以用幾行 JavaScript 程式碼完成非常複雜的非阻斷式伺服器。 他原本擔心 Node.js 會變成不能用的平台,但隨著世界各地的社群高手開發程式庫,Ryan 舒緩他的憂慮,由於單一的 Event Loop 和完全的非阻斷式介面,程式庫將可以越加越複雜而不需要採用昂貴的執行緒。

在 Node.js 中,使用者發現預設情況下就能容易擴展 (scale)。在於系統核心不允許使用者做出很可怕的事情,例如阻斷運行中的執行緒,所以效能不會顯著地下降,比起傳統阻斷式的方式好上一個數量級 (10倍以上),可以處理更多的流量。

從上述內容我們可以知道 Non-Blocking 是一件重要的事情,為何需要 Non-Blocking 呢?傳統上,伺服器會開啟一定數量的程序(或執行緒)處理連線,當這些程序因為處理 I/O而被 block 時,這個程序將只能等待回應而不能服務其他用戶,由於伺服器開啟的程序數量有上限,阻斷的程序將嚴重影響服務的吞吐量,特別是一堆開啟且閒置的連線。如果有 Non-Blocking 的處理方式,則整體效率將可以提升。

為何要使用Node.js

Node.js 用優雅的方法解決 Blocking 問題,提供 Non-Blocking 的 I/O 程式庫,採用非同步 (Asynchronous) 的呼叫方式,利用簡單的 Event Loop 實作 ,因而具有輕量級、高效率的特性。加上用 JavaScript 為程式語言,不需要使用多程序或多執行緒的程式架構,大幅降低學習門檻,提高開發成效。

了解這些開發背景,那些地方適合使用 Node.js 呢?我想大概有這些地方:
  1. 需要伺服端推送資料的應用程式。(長時間的閒置連線)
  2. 資料處理密集的應用程式。(I/O次數非常高)
  3. 具有擴展需求、大量並行處理、即時性的應用程式。
  4. 統一以 JavaScript 程式語言開發的應用程式。
這些應用特性符合 Node.js 的長處,也才能發揮 Node.js 的效益。如果是開發傳統的網頁應用程式(如留言板、部落格等),不妨以PHP、Python的框架平台進行開發,畢竟這些資源比  Node.js 還多,也比較純熟,使用上會更有幫助些。

參考書籍:
Tom Hughes-Croucher & Mike Wilson, Node: Up and Running, O'Reilly Media, 2012

如何安裝 Node.js

請先到下載頁面下載 Node.js ,如果你的系統是 Windows,那就用 Windows Installer (.msi) 吧!這是最簡單的安裝方式。如果你的系統是 Linux ,可以選擇下載 Source Code 自己編譯,或是下載 Binaries (注意你的系統是 32 或 64 位元)。以下指令是在 Ubuntu 上自己編譯 Node.js,提供大家參考。

apt-get -y install build-essential
tar xzvf node-v0.10.28.tar.gz
cd node-v0.10.28
./configure
make
sudo make install

node -v

npm

###

2014年5月19日 星期一

wxPython 跨平台視窗程式庫

wxPython 是一套 Python 的 GUI 工具 (toolkit),可以讓我們簡單快速地建立圖形化的使用者介面 (Graphical User Interface, GUI),wxPython 實際上是將另一套 wxWidgets 程式庫包成 Python 可以使用的套件。由於 wxWidgets 本身是一跨平台 (cross-platform) 的程式庫,因此利用 wxPython 開發的應用程式也是可以跨平台的,加上 wxWidgets 是呼叫系統原生的 API,其運行速度是相當快速。wx 的 w 指的是 Microsoft Windows,而 x 指的則是 X Window系統。

wxPython 在 Ubuntu 上的運作是這樣:wxPython → wxWidgets → GTK+ 。若是在 Windows 上則是:wxPython → wxWidgets → Windows API 。大部分的事情已經在 wxWidgets 做掉了,wxPython 是 Python 和 wxWidgets 之間的橋樑

了解 wxPython 的運作原理,我們可以試著裝起來用用看,在 Ubuntu 上安裝 wxPython 相當簡單,請執行下列指令:
sudo apt-get install python-wxgtk2.8
sudo apt-get install python-wxtools wx2.8-i18n

學習 wxPython 實際上就是學習 wxWidgets ,我們用 Python 去呼叫 wxWidgets 提供的功能。在 wxPython 之中的視窗稱之為「Frame」,而不是「Window」,這點需要特別留意,觀念上很容易混淆,所有的視窗都是繼承 Frame 類別。wxPython  提供相當多的工具項 (Widgets) 類別,學習時建議先認識有哪些控制項 (Controls) ,屬於 Control 的子類別,例如常用的按鈕 (button)、文字方塊 (text box)等。

至於新手入門的話,可以先看這篇 Getting started with wxPython ,若需要進一步的 API 說明,則可以閱下列連結的內容:
整體來說,利用 wxPython 開發應用程式具有跨平台的優點,加上以 Python 語言進行撰寫,使得我們可以簡單又快速地建立視窗應用程式。然而 wxPython 缺乏一個好用的 IDE 開發工具,像是 Visual Studio 可以用拖拉方式建立應用程式,稍微讓 wxPython 的開發顯得不甚完善。如果想用圖形化方式建立 wxPython 應用程式,則是可以參考 wxDesignerwxFormBuilder 這兩項快速開發工具。

###

2014年5月2日 星期五

NSIS 建置 Windows 安裝程式

NSIS (Nullsoft Scriptable Install System) 是一套建置 Windows 安裝程式 (installers) 的開源軟體,用來將程式或文件打包成一個執行檔給客戶安裝使用。NSIS 採用腳本 (Script) 的方式建置 Windows 安裝程式,有點像寫程式的方式,先撰寫一個副檔名為 .nsi 的 Script,再利用 MakeNSIS 編譯 .nsi 檔案,將可以得到安裝程式的執行檔。

NSIS 提供大量的範例可以參考,因此學習 NSIS 不會很困難,加上外掛 (plug-in) 程式,我們可以快速地建置相當專業的安裝程式。雖然 NSIS 的指令很多,但不用擔心,實際會用的指令不不超過 20 個,有需要再查找就行了,缺點大概就是只有英文的操作介面吧!除了 NSIS 這個開源軟體之外,還有 Inno Setup 和 WiX Toolset 這兩套免費軟體可以使用,大家有興趣不妨比較看看。

學習 NSIS 最重要的是了解 .nsi 檔案的內容,Script 中有幾個重要觀念如下:

  • 安裝程式屬性 (Installer Attributes)
    這是用來設定安裝程式的行為,例如安裝路徑、名稱、圖示、版本資訊等,屬於全域的設定。詳細參閱http://nsis.sourceforge.net/Docs/Chapter4.html#4.8
  • 頁面 (Pages)
    可以將安裝程式顯示的每個視窗當作一個頁面,NSIS 內建數個頁面類型,例如版權頁面用來顯示版權資訊,元件頁面讓用戶選擇安裝元件等。頁面之間是有先後順序的,在撰寫 Script 要特別注意,頁面主要是利用 Page 和 UninstPage 兩個指令進行設定。詳細參閱http://nsis.sourceforge.net/Docs/Chapter4.html#4.5
  • 章節 (Sections)
    可以把 NSIS 的章節當作程式元件來看,例如一個安裝程式需要安裝兩個軟體,這時候就需要兩個章節,在元件頁面的視窗就會看到兩個軟體元件。比較注意的是每個章節會有一個名稱作為元件名稱,如果是 Uninstall 或字首為un.的名稱則是用在移除的元件。詳細參閱http://nsis.sourceforge.net/Docs/Chapter4.html#4.6
  • 指令 (Instructions)
    指令占了 NSIS 說明的大部分,包含檔案操作、登錄檔 (Registry) 操作、程式或系統的呼叫執行等等,基本上都是安裝或移除會用到的操作指令。詳細參閱http://nsis.sourceforge.net/Docs/Chapter4.html#4.9
  • 函式 (Functions)
    將常用的操作定義成函式以避免重複,特別的是 NSIS 定義一些回呼函式,我們可以撰寫一些操作讓 NSIS 執行時呼叫,例如啟動或關閉 NSIS 時執行某些工作。詳細參閱http://nsis.sourceforge.net/Docs/Chapter4.html#4.7
  • 編譯時期命令 (Compile Time Commands)
    這是用來設定 NSIS 編譯的行為,常用的命令有引用外掛 (plug-in) 程式、定義常數等。詳細參閱http://nsis.sourceforge.net/Docs/Chapter5.html

最後,介紹 NSIS 的安裝,NSIS 有兩種版本,一種是 NSIS ( http://nsis.sourceforge.net/ 網站上面的版本) ,另一種是 Unicode NSIS。如果不需要多國語言,以英語為安裝程式的語言,那麼兩種版本的 NSIS 是沒有什麼差異,但若希望安裝程式顯示中文或其他多國語言,則建議採用 Unicode NSIS,比較不會出現亂碼的情形。必須注意的是,Unicode NSIS的 .nsi 檔案必須是 UTF-8 編碼的 Script ,這樣 Unicode 版本的 MakeNSIS 才能正常編譯。此外,這兩種版本是可以同時安裝在一個系統上的。

###

熱門文章