跳到主要內容

API 使用 http 做為底層 protocol 的好處

以前對 http-based 的 API 一直有疑問 (免責聲明: 我沒有弄懂 RESTful 和這點的具體差別), 為什麼要綁在 http 這個不太相關的協定上? 尤其是在試用 Solr 後, 發覺因為使用 http 提供 api 的緣故, 即使是 localhost 連線做很簡單的查詢, 也有一定的 latency 成本。

不週在多了一些 network programming 經驗後, 對此有了不同想法。

首先, network programming 很痛苦, 一開始要處理兩個問題: 第一點是在 streaming-based 的資料上, 提供 datagram 的概念, 這樣才有辦法傳遞和接受參數。streaming 不同已有完整資料的檔案一般, 資料回傳時間不一定, 每次讀回的 byte 不一定, 提供 datagram-like 的介面, 要費點心思。

第二個問題是, 要將資料 serialization, 這件事本身也很苦, 若要求效率, 要用 binary 格式, 實作苦除錯更苦; 若用 text 表示 (如 JSON), 也許有一天會有效能問題, 若需要傳 binary file, overhead 太大。

第一和第二問題在面對多種語言的 client 時 (比方 PC 上有人想用 Python 或 C++, mobile 上有 Objective C 和 Java), 實作成本更高。

解決這些基本問題後, 若幸運地服務順暢, 用戶成長個 10 倍, 有什麼方法可以擋住 10 倍的使用量? 也就是 scalability 的問題, 這又是一串的麻煩開始。10 倍擋住後, 變 100 倍怎麼辦?

反之, 使用 http-based solution, 以上統統不是問題。有成熟的 web server 包含 scalability 都解決了, http client lib 也是遍地開花, 沒有找不到套件的問題, 只有太多種版本不知選那個好的困擾 (看看 python 那票 urllib, urllib2, httplib, httplib2 以及其它各家 3rd party 實作)。更可以直接用 browser 試用 API, 連寫程式都不用。

照這樣來看, 因為綁定 http, 而「稍微」多些 latency, 似乎不是什麼不得了的負擔。

ps.

  • kcwu 補充說明使用 http 還有減少被阻擋的機率, 有許多地方會擋 port 80、443 以外的 port。此外, http 有許多現成工具提供 encryption, compression, cache, proxy, load balance, authentication 等功能。
  • Socket Programming HOWTO 值得一讀, 簡要地描述 network programming 的基本知識以及實作會遇到的問題。

留言

這個網誌中的熱門文章

(C/C++ ) 如何在 Linux 上使用自行編譯的第三方函式庫

以使用 LevelDB 為例。 抓好並編好相關檔案,編譯方式見第三方函式庫附的說明:$ ls include/ # header files leveldb/ $ ls out-shared/libleveldb.so* # shared library out-shared/libleveldb.so@ out-shared/libleveldb.so.1@ out-shared/libleveldb.so.1.20* 下面的例子用 clang++ 編譯,這裡用到的參數和 g++ 一樣。 問題一:找不到 header$ clang++ sample.cpp sample.cpp:5:10: fatal error: 'leveldb/db.h' file not found #include "leveldb/db.h" ^ 1 error generated. 解法:用 -I 指定 header 位置 問題二:找不到 shared library$ clang++ sample.cpp -I include/ /tmp/sample-2e7dd8.o: In function `main': sample.cpp:(.text+0x1e): undefined reference to `leveldb::Options::Options()' sample.cpp:(.text+0x6f): undefined reference to `leveldb::DB::Open(leveldb::Options const&, std::string const&, leveldb::DB**)' sample.cpp:(.text+0x10c): undefined reference to `leveldb::Status::ToString() const' sample.cpp:(.text+0x7d0): undefined reference to `leveldb::Status::ToString() const' clang: error: linker command failed with exit code 1 (u…

熟悉系統工具好處多多

記一下以前很困擾, 現在秒殺的小事。 更新這篇的時候, 忘了函式庫用的 man page 裝在那個 package。以前就會想辦法 google, 運氣好一下會找到, 運氣不好會多找一會兒。 這回我想到新作法:$ strace -e open man 3 printf > /dev/null # 發現是讀 /usr/share/man/man3/printf.3.gz $ dpkg --search /usr/share/man/man3/printf.3.gz # 找到套件名稱 manpages-dev $ aptitude show manpages-dev # 確認描述符合, 收工

virtualbox 使用 USB 裝置

2012-12-16 更新 現在 (4.x 版) 似乎無需做任何設定, 只要有裝 Oracle VM VirtualBox Extension Pack, 在 VirtualBox 視窗右下角按 USB 的圖示, 再點目標裝置, 即可加入或移除該裝置 同一時間只有 host 或 guest 可擁有該裝置, 所以從 guest OS 移除, 相當於接回 host OS 目前 VirtualBox 只支援 USB 2.0 的插槽, 若偵測不到時, 注意一下是否為這個問題 有時拔拔插插, VirtualBox 會進入奇怪的狀態, 接上去 guest OS 無法連接且跳出 device is busy 的錯誤訊息。試看看拔除該裝置, 重開 guest OS (續上則) 若重開 guest OS 無效, 並且 host OS 已移除該裝置, VirtualBox 的 USB 清單卻仍顯示 "captured", 試看看拔除該裝置, 重開 host OS原文網路上搜一下, 比較多是 Ubuntu 當 host 的解法, 我的情況是 Win7 當 host, Ubuntu 當 guest。 這兩篇說明很詳細《Learn How to Set Up USB and Networking Options in VirtualBox》《幻影千瞳的部落格: VirtualBox 使用筆記(二):使用 USB 裝置》 現在的版本圖形介面很好用了, 不用像第二篇說的那樣用指令操作。這裡記下我的操作步驟: 關掉 guest OS 在 VirtualBox 選單, 選擇 guest OS -> Settings -> USB -> Enable USB 2.0 會出現訊息框, 說明要安裝 Oracle VM VirtualBox Extension Pack。下載後安裝它 host OS 插入 USB 隨身碟 在 VirtualBox 選單, 選擇 guest OS -> Settings -> USB, 點右邊有綠色 "+" 的 USB 頭的圖示, 選擇該 USB 隨身碟, 加入它的 filter 從 host OS 移除 USB 隨身碟 開啟 guest OS 插入 USB 隨身碟, 於是 guest OS 會自動偵測…