12/31/2006

Happy New Year

在 2006 年的最後兩天,我收到一個最大的禮物。


Agile Web Development with Rails—Second Edition。早在 23號我在網路上看到天瓏書局開賣,我就覺得可能會賣的很好,立刻用電話訂下來一本。結果昨天晚上去拿的時候,書局的人還跟我說,昨天20本已經賣完了,只剩下我訂的那本。聽到的時候還蠻驚訝的,原來 Ruby on Rails 市場還是很大的。

今年的最後一天,為大家說聲新年快樂。我們明年繼續 Happy Railing。



2006年度本Blog 資料分析

既然大家都來十大,我也來個本 Blog 年度十大熱門文章好了,順便分析一下本站的使用者都用哪些關鍵字,使用系統都是哪些。雖然本 Blog 今年8月中才開始撰寫,不過四個多月以來累積了點人氣,實在很心虛。明年如果沒意外,還是會努力繼續筆耕。

第十名:IBM 使用 Ruby on Rails 來開發 Koala Project
Koala Project 是一個紀錄,分享商業流程的 Project 。他有提供 Wiki 跟 Firefox 的 slider bar。其實這些都不太重要,重點是那是 Ruby on Rails 寫的!!!
評語:該不會是查詢 IBM 或是查無尾熊的人進來看這篇文章的吧XD 純粹新聞的文章。

第九名:JRuby 0.9.1 發佈,可怕的進步
JRuby 作者怎麼可能剛加入SUN,程式功力就好像打開任督二脈一樣猛。60% 的速度改進耶,可不是簡單就做的出來,我想大概是 New interpreter design 這裡所造成的關鍵性差異吧。
評語:JRuby 自從這個新聞之後,瞬間受到 Ruby 社群廣大的注目跟鼓勵。也讓 JRuby 擠進本 Blog 十大文章。

第八名:Pagination :讓分頁不再繁瑣
Ruby on Rails 其中一個特色,就是把 Web Programming 裡面繁瑣的細節,用優美簡單的語法來修飾。所以,通常你不需要花太多時間在細節上面,而是可以直接往 business logic 進攻。什麼是繁瑣的細節呢?分頁就是典型的例子。
評語:討論分頁的好處,並且探討效率的問題。可能是真正解決了一些人的問題,所以進入第八名。

第七名:媽,我上 iThome 了~~
台灣 Ruby 社群接受 iThome 記者採訪,並且在 269期(2006/11/18~11/24)獲選為封面故事『搜索Ruby on Rails的高速魔法』。看完全部的章節之後,發現我講的話有點多 XD
評語:
媽,該不會是你灌的票吧................
iThome編輯:非也,是編輯部搞的

第六名:Windows 上面安裝 Ruby on Rails
原因是因為我都有機器可以測試,不過我就是沒有 Windows。但是因為太多人問我了,連我同事都問我@@!,我還是寫一篇解救一下我的 Gmail 收件夾吧。
評語:Windows 安裝的文章果然還是票房保證。

第五名:敝公司出了大事,萬事都得延宕下來
基本上,我肯待一家公司,代表我對他有忠誠,我喜歡或是認同這間公司的作風 。這次我們公司處於生死存亡之際,我恐怕沒太多時間寫 Blog ,本 Blog 在最近更新可能非常緩慢,請原諒,我想跟我的公司一同度過這個難關。
評語:感謝大家對我們公司的支持。

第四名:Comet For Ruby on Rails and Mongrel
Comet 這個詞出自於 Dojo 作者 Alex Russell 在 2006/3/3 發表的 Comet: Low Latency Data for the Browser 。簡單來說就是讓 Browser 跟 Server 作一個長時間不斷線的連線,然後我們要在 Web 撰寫 Rich Client 的程式就相當的容易。有人推測這可能是一個超越 AJAX 的技術。
評語:我覺得大部分的流量來自於 vgod 的站吧,果然人家的站還是大站,我是小喀。

第三名:Agile Web Development with Rails
如果你正在找一本 Ruby on Rails 的書,你想要學習 Ruby on Rails ,或是你想看看 Ruby on Rails 是個啥東東。這本書是一定要買的書籍。 Ruby on Rails 三年就發展到這種程度,這本書真的功不可沒。
評語:聖經本果然魅力無法擋,堂堂登入第三名。

第二名:從 Django 看 Ruby on Rails 成功的原因
這裡有一份對岸 cookoo 寫的对Django的遗憾,真是一篇好文章,裡面描寫到 Django 如何錯失大鳴大放的機會。我看完之後,突然發現 cookoo 這篇文章藉由 Django 的缺點,他也順便偷偷分析了 Ruby on Rails 成功的原因。大家可以來看看
評語:cookoo先生的好文章,小弟只是沾光而已。查詢 Django 的人可能會被誤導進入本站 XD

第一名:Ubuntu 6.10 安裝 Ruby on Rails + lighttpd
這裡有Ubuntu 上面安裝 Ruby on Rails (精簡版),如果想要一步一步來安裝。請參照這裡。
評語:居然是 Ubuntu 這篇晉升全年度熱門文章第一名。證明 Ubuntu 使用者都很喜歡 Rails,還是Rails 使用者都很喜歡 Ubuntu?真是令人難解的議題呀。By the way,我個人是很喜歡 Ubuntu 啦,使用方便並且架站快速,創辦人的精神更是令我敬佩。

再來介紹一下本站年度十大關鍵字,看看大家都是用哪些關鍵字進來查詢的。
  1. ruby on rail
  2. rubyonrails
  3. freebsd ruby install
  4. ROR
  5. ror
  6. SQLITE
  7. ror has_and_belongs_to_many pagination
  8. ruby on rails .net
  9. lighttpd 1.5.0
  10. rails 中文 亂碼

當然本站查詢 Ruby on Rails 進來的使用者最多,不過 SQLite 第六名我也很訝異,原來我之後很少寫 SQLite,居然還有人賞光。查詢 FreeBSD 安裝 Rails 說明的人還不少,看來 FreeBSD 用戶不少。Rails 中文亂碼是怎麼一回事?我從沒遇到這種情況說。

本站使用者瀏覽器比較
  1. Firefox 52.74%
  2. IE 39.76 %
  3. Safari 3.33%
居然是 Firefox 獲勝,證明 Firefox 用戶比較喜歡本站吧。

本站使用者系統比較
  1. Windows 84.9%
  2. Linux 7.96%
  3. MAC OS 6.94 %
Linux 跟 MAC 還是有人在用的呀。

本站使用者語言比較
  1. 繁體中文:61.03%
  2. 英文:19.67%
  3. 簡體中文:15.96%
本站的英文使用者應該都是外地的華人吧。對岸造訪者這一兩個月增加很多是真的。

本站最大來源
  1. Google :36.49%
  2. 直接連本站 :22.64%
  3. Ruby 台灣使用者社群 :6.65%
這一兩個月從 Google 進來的比率已經高於 50%。Google大神惠本站良多呀。

12/30/2006

Ruby on Rails 伺服器架設原理

一般來說,Ruby on Rails 架設原理很簡單,分成三個部份。
  1. Frontend Server
  2. Application Server
  3. Database Server
每個部份都有自己的功用。


Frontend Server 負責將所有 HTTP Request forward 給後端的 Application Server,也就是他是作類似 Reverse proxy 的工作。一般來說,Apache 2.2 跑 mod_reverse_proxy 是最常出現的選擇,nginx 也是不錯的選擇。Lighty 1.5 之後跑 mod_proxy_core 也很方便,等到 1.5 release 之後我會作詳細的評估。
Application Server 負責跑 Ruby on Rails 程式,你寫好的程式就在上面跑。一般來說可以用 Webricks,Fastcgi,scgi,Mongrel 等等 Ruby on Rails Runner來跑。Webricks 太慢,Fastcgi 有穩定性,以及不好設定的疑慮。SCGI 太年輕。目前最穩,最好用,而且已經被驗證過的 Application Server 就是 Mongrel。

Database Server 就是處理資料處理的工作。可以跑 SQLite,MySQL 之類的 RDBMS 。甚至使用 File 來當資料處理,或是使用 NFS 也未嘗不可。不過這裡通常大家都是使用一般大廠的 RDBMS資料庫。

組合方式

Apache 2.2 + Mongrel:穩定,高彈性的組合

Apache 2.2 遇到 user request 用 HTTP 分配給 Mongrel ,然後 Mongrel 去跑。這個組合的好處是每個 Application Server node 都可以很輕易的拆成不同台機器,並且很好管理。Apache 的穩定又是出名的。雖然不見得最快,但是方便 scale 以及穩定是他最好的優點。目前所有組合當中最穩定的方式,很多流量最大的 Ruby on Rails 站台也都是使用這個方式。適合在已經有一定規模的網站。設定方式在此我有介紹

Lighttpd + Fastcgi:單機最佳選擇
Lighttpd 1.4 跑 PHP 或是跑 Ruby on Rails 都是這樣跑。Lighttpd 為 Frontend Server ,他接到 request ,經由 unix socket 送給身為 Application Server 的 Fastcgi ,Fastcgi 再執行 Ruby on Rails 程式。通常這個方式是 Frontend Server 跟 Application Server 跑在同一個機器上面的,當然每個 Fastcgi 也可以跑在 TCP Mode ,然後 Fastcgi 放在不同機器上面,不過設定不易不常使用這個方式。這個組合的好處是執行效率非常快速,如果 Frontend 跟 Application 放在同一台機器上,Lighty 這個組合遠比 Apache 的組合來得輕快許多。但是缺點是多台機器設定複雜,不易擴展到多台機器上,Fastcgi 又有在高負載下罷工的負面報導。相反的,單台機器上面 Fastcgi 設定管理簡單,速度又飛快,非常適合小網站剛剛起步時,機器不足,流量不大的需求。設定方式在此我有介紹

Nginx or Lighttpd 1.5 + Mongrel:未來的新選擇

類似Apache 的組合,但是 nginx 或是 Lighttpd 1.5 都有一個優點,不像 Apache 2.2 那麼肥。反正這個 Frontend 只要作 reverse proxy 的工作,其實不需要 Apache 那麼大的 Server 來作。好處是 Frontend Server 比較快速。壞處是 nginx 這個俄國來的 Server 大家不熟悉,doc 又很少(俄文是很多啦)。Lighttpd 1.5 又只在 pre-release 階段,穩定程度還是得花點時間。不過如果扣掉 Frontend 的 X factor,這個組合兼具輕快跟方便 Scale ,可說是最好的組合。lighty 1.5設定方式在此我有介紹。nginx 的設定檔這裡有範例,可以參考。




12/29/2006

跑 Lighttpd 的5 大網站

取材自Lighttpd 作者 Blog,在 Alexa 上面的 Top 250 網站已經有 5個是跑 Lighttpd,我們來看看這幾個網站怎麼使用 Lighttpd。以下排行都是 Alexa 排行。

  1. 第6名: youtube使用 Lighttpd 來serve static content,像是 images,video。不過他們的流量太大了,所以使用 patch version 的 lighttpd 來加強。
  2. 第12名:wikipedia 使用 lighttpd 處理所有的 image work,像是縮圖之類的。
  3. 第80名:SourceForge 是完全使用 Lighttpd ,包含 PHP,以及 static content
  4. 第132名:sendspace.com 是一個巨量的 file sharing 網站,他們是使用 Lighttpd。
  5. 第221名:mininova 是一個 Torrent Download 網站。

根據 Netcraft 的 2006/12 報告,一共有
178619 個網站使用 Lighttpd,佔 12位。我們發現到 Lighttpd 其實已經不少巨量網站採用,實在是個好消息。




LightyPHP:Windows 上面的 lighttpd 懶人包

今天看到 LightyPHP 這個套件,裡面寫到
LightyPHP是一個包含PHP和lighttpd的軟體包裝,讓你輕鬆的在Windows 2000/XP上建立PHP伺服器
也就是一個類似 Appserv 的套件包,不過他跑的是 Lighty + PHP + SQLite。他的目的也在 FAQ 寫了
特別聲明, LightyPHP並不適合用作為伺服器軟體, Windows作業系統也不是伺服器的好選擇。 LightyPHP的設定是以容易使用為主,並不是為了要當作網站伺服器。
恩,作者的觀念也是正確的。除了 Windows 下面沒辦法跑 Fastcgi ,所以得用 CGI 去跑 PHP 以外,沒啥好挑剔的工具。


12/28/2006

css_dryer: DRY Up Your CSS

css_dryer 是一個將 CSS Dry UP的技術。想法很簡單,他將 CSS 視為 HTML,然後用 Rails 來產生 CSS 相關的內容。


其實他的開宗明義就是
Cascading style sheets (CSS) are wonderful but repetitive. Rails strongly discourages repetition, the don't repeat yourself (DRY) principle, so writing CSS feels ungainly in Rails.
因為 CSS 重複很多,所以不符合 DRY 原則,所以我們需要 DRY 一下 XD 雖然很符合 Rails 邏輯,但是這個東西到底有沒有用呢?老實說,我是持反對的態度的。因為 CSS 其實是 ART 去專職負責的,當初設計的原因也是因為 CSS 如果設計的好,是可以做到完全將程式跟美工分開的程度。如果 ART 能夠完全使用 CSS 去做到所有排版需要,那麼程式設計師沒必要,也最好不要去干涉 ART 負責的事情。這個 Plugin 雖然有點用途,但是你難道要強迫美工去學習 Ruby 的語法嗎?所以大家看看就算了:p

安裝方式是
$ script/plugin install http://opensource.airbladesoftware.com/trunk/plugins/css_dryer
使用方式是產生相關 Controller
$ script/generate controller dry_css
然後寫相對應的 controller
class DryCssController < ApplicationController
layout nil
session :off

before_filter :set_headers

private
def set_headers
headers['Content-Type'] = 'text/css'
end
end

這樣 http://www.example.com/dry_css/ 就會回傳 CSS 內容了。最後記得在 header 寫上
<link href='/dry_css/site' rel='Stylesheet' type='text/css'>
即可。




How To Think Like a Computer Scientist :Ruby 版

How To Think Like a Computer Scientist 是 Open Book Project 一系列的電子書, 這系列的書不只是 Free Available ,還是 GNU License 的。這代表你不只可以免費看,散佈,你還可以修改,並且作其他用途。

這是這個 Open Book Project 的宗旨
The Open Book Project is aimed at the educational community and seeks to encourage and coordinate collaboration among students and teachers for the development of high quality, freely distributable textbooks and educational materials on a wide range of topics.
這一系列的書有 Java, C++,Python,logo 版,現在 Ruby 版也推出了。撰寫者是 Elizabeth Wiethoff 。不過這本書 FAQ 第一個問題就是『Why does this book about Ruby smell like Java?』XD。原因就是這本書大部分的 code 都是直接從 Java版轉過去的,可見 Ruby 跟 Java 的相似性。

該選擇那個 OS 作為 Ruby on Rails 伺服器的環境?

小弟雖然不才,但是有一點我很自傲。我的使用 OS 相當的廣,MAC OS X,Gentoo Linux,Ubuntu Linux 都是我在日常生活中使用的 OS。並且 FreeBSD,Windows,Debian Linux,Fedora Core Linux 都有機器管理的經驗。由於有很多機會可以自由轉換各種 OS,所以我不執著於任何一個 OS,並且深信
OS 只是 Tools ,真正決定一切的關鍵是管理者
那麼要我推薦 Ruby on Rails 的 OS 呢?我會怎麼選擇?

適合研發 Ruby on Rails 用的 OS

所有的 OS 都可以,只要你喜歡,你習慣這個 OS 的操作,可以灌 Ruby on Rails 還有 Mongrel ,都沒任何問題。當然 IDE 也是很重要的因素,所以我比較推薦可以安裝 TextMate 跟 RadRails 的 MAC OS X。但是 RadRails 因為是跨平台的,所以 OS 之間差距沒那麼大。

適合 Ruby on Rails 伺服器環境的 OS

我首先不推薦 Windows ,因為許多報告都顯示
這些都告訴我們 Ruby on Rails 對於 Windows 的支援度很弱。

FreeBSD 是一個很適合架站的環境,但是我曾經看過 Mongrel 作者 Zed Shaw 說過 Mongrel 在 FreeBSD 跟 MacOSX 的效能不佳,只是現在那篇文章似乎已經 Zed 被拿掉了,或許是他已經改進了效能。這篇講解 Scale 的文章底下的 Comment ,也有人出來問類似的問題
Justin said about 18 hours later:
I believe Zed mentions on the Mongrel site that there are performance issues when running Mongrel on Mac OS X and FreeBSD. Given that you're running on FreeBSD, have you experienced any of the (relative) slower performance running Mongrel on FreeBSD?
但是作者也僅僅回答他沒有作過類似的效能測試。所以這就是證明 Zed 的確有說過『Mongrel 在 FreeBSD 跟 MAC OS X 上面比較慢』類似的話,但是他有沒有改進 Mongrel 讓他更合乎 FreeBSD ,似乎不得而知。

Linux 方面,目前似乎沒有效能上的負面消息傳出來。

結論

安全性跟穩定度方面,各個 OS 上面的表現應該是要看管理者功力。至於效能方面跟相容性的考量,Windows 最不推薦當作 Ruby on Rails 伺服器環境。MAC OS X 跟 FreeBSD 等 BSD 系列有 Mongrel 作者的對於效能上面的負面報導。相對的,Linux 目前還沒有效能上面的負面報導,可說是這方面的贏家。但是一個好的管理者也可以將系統調整到相當快速的境界,所以我認為 BSD 跟 Linux 並沒有誰適合當 Ruby on Rails 環境的贏家。還是那句話
OS 只是 Tools ,真正決定一切的關鍵是管理者


12/27/2006

Hemidemi 的首頁書籤討論的 HTML 碼

如果仔細觀看 Hemidemi 的首頁,你會發現他有時候書籤最新討論會出現下面的狀態

會出現類似圖中糯米團寫的
其實這是抄襲自"獵人"的<a href=& quot
如此 HTML 碼的原因很簡單。在顯示書籤討論的內容, Hemidemi 是允許一些 HTML Tags,來充實討論區的版面。但是在首頁上,站長應該是怕 HTML Tags 破壞版面,所以用類似 h() 或是自己寫一個 filter 的方式,把所有的< >都改成了 & gt; & lt;," 改成 & quot,用來保護版面的乾淨跟安全性。這些議題其實都在本 Blog 的 HTML Filter 系列討論過了。但是Hemidemi 首頁的 HTML 碼實在是太難看了,有沒有方式可以只顯示 HTML Tag 的內文即可。

當然有,在 Ruby on Rails 就是 strip_tags() 這個 function,他會將所有
<a href='http://www.example.com'>lala</a>
轉成只有內文
lala

就上面的實際範例,糯米團寫的
其實這是抄襲自"獵人"的<a href="http://zh.wikipedia.org/wiki/%E5%BF%B5%E8%83%BD%E5%8A%9B">念能力</a>! XD

就會被 strip_tags 改成只顯示
其實這是抄襲自"獵人"的念能力! XD
這樣在首頁顯示就好多了。

眾所皆知,Hemidemi 是用 Ruby on Rails 寫的,如果站長看到的話,順手改一下吧:)

UPDATE: 葛力好快的動作呀。

Yullio 試用感

Mollio 是一個我很喜歡的 CSS template,就連我自己架的中文 Ruby 星球也是用 Mollio。今天早上看到 HappyDesigner 發表了 Yullio: YUI CSS Grids 與 Mollio 的結合,看到裡面講
hlb根據YUI Grids與Mollio CSS/HTML Templates,製作了一套名為 “Yullio” 的模版(Yullio = YUI + Mollio)。
並且發現到,他們還有 Rails 的 Plugin,還可以Gem 安裝!!!所以二話不說就先裝了要緊。

安裝方式就是
gem i -y layout_yullio_generator
使用方式就是
ruby script/generate layout_yullio layout_name sidebar_name
假設如原網頁講的打 ruby script/generate layout_yullio Expense sidebar ,他會生成一個 layout 叫做 expense,然後在 app/view 裡面有一個 _sidebar 的 partial ,記載了 sidebar 應該放的東西。並且他會將所有需要的 CSS、JavaScript 及 plug-in 放一份到 public/ 及 vendor/plugins/ 目錄下。其他詳細文件請跟原作者聯絡

最上面那張圖是我使用這個 plugin 自動產生的頁面,還不錯吧,以後這個 plugin 對我來說應該會很常使用到吧,感謝 hlb 和 lukhnos。

版權宣告

Yullio Layout Generator 是使用 BSD 授權公開發表的軟體套件,由 hlb 和 lukhnos 製作。YUI Grids 及 Mollio 的授權,請參考其各自的網頁。


延伸閱讀


12/26/2006

Ubuntu 上面安裝 Lighttpd + phpmyadmin

這是今天安裝 Ubuntu 6.10 時的紀錄,畢竟 phpmyadmin 是一個誰都得使用的套件,還是得記錄一下。想看 Ruby on Rails 的文章的人可以自動略過去,另外這裡有 Ubuntu 安裝 lighty + RoR 詳細版以及精簡版的。

  1. 安裝 lighttpd (註1)
    apt-get install lighttpd
  2. 安裝 php5-fastcgi mode (註2)
    apt-get install php5-cgi php5-mysql libfcgi-dev
  3. 修改 Lighttpd config 成 Enable mod_fastcgi
    /usr/sbin/lighty-enable-mod fastcgi
    /etc/init.d/lighttpd force-reload
  4. 安裝 phpmyadmin
    apt-get install phpmyadmin
註.
  1. lighttpd 1.4.13 是放在官方套件沒錯,但是是屬於 universe 的,得先將 source.list 裡面 universe 打開
  2. PHP4 Fastcgi 似乎有問題,只好灌較肥的 PHP5

Update: 本文章同步發表至 ubuntu@tw 論壇

延伸閱讀


Ubuntu 上面安裝 Ruby on Rails (精簡版)

我發現之前的太落落長了,其實大家會被嚇到,所以我決定寫一個極度精簡版的安裝方式,方便大家開始上手。本文章測試環境 Ubuntu 6.10。




安裝 Ruby on Rails
apt-get install rails
安裝 Ruby on Rails 如此即可,不用再更多了。

但是要玩 Ruby on Rails ,沒有 Mongrel ,gem,DB 根本就跟不用玩一樣,所以下面的步驟是安裝的方式。

安裝 gem
這裡下載 gems 最新版,解壓縮後,安裝,順便更新gem
ruby setup.rb
gem install rubygems-update

安裝 Mongrel cluster

先安裝相關 make 套件,這樣安裝 Mongrel 才不會有相關問題
apt-get install build-essential ruby1.8-dev
再來我們用 gem 安裝 Mongrel Cluster
gem i mongrel mongrel_cluster -y
安裝資料庫
  • MySQL :apt-get install mysql-server-5.0 libmysql-ruby1.8
  • SQLite:apt-get install sqlite3 libdbd-sqlite3-ruby1.8
  • POstgreSQL:apt-get install postgresql-8.1 libpgsql-ruby1.8
UPDATE: 本文章同步發表至 Ubuntu@TW 論壇


Mongrel 1.0 快要來了


Mongrel 1.0 RC1 Windows 版本已經在 Mongrel 首頁上面發佈了,很明顯的,Mongrel 1.0 的腳步也近了。

其實我早就發現 Mongrel 的品質根本就是 1.0 的水準,並且許多站台早就在已經將 Mongrel 用在商業用途上面(Apache 2.2 + Mongrel)。只是Mongrel 0.3 的版本號碼實在很難看,也會嚇跑許多初學者吧,所以在 1.0 的推出應該對很多有人大大的振奮吧。


在我研發期當中,我沒有安裝任何 Server 端的程式,只安裝 Mongrel 在 iBook G4 上面。從頭到尾,一個 Mongrel 就可以 handle 所有的研發任務。以後 Project 要上線,其實也只是多開幾個 Mongrel 去跑,前端交給 Reverse Proxy 去搞 load balancing即可。對一個 RD 來說,研發機器環境跟 Production 環境幾乎一模一樣,可說省了許多麻煩事。所以 Mongrel 可說是居家旅遊的必備法寶呀。

新手學習 Ruby on Rails 必看的幾件事

寫這個Blog,我的 Email 信箱會遇到很多讀者的鼓勵,也會有很多新手的發問。但是我想說的是,我也是上班族,我很多時刻是在工作的,不回答你只是因為我在忙,不是我在生氣之類的。最重要的是,我覺得我要跟大家理清一下,學 Ruby on Rails 應該有的態度。

  1. 學習 Rails 很簡單,但是你不肯花功夫下去去學就一點都不簡單。
    我遇到很多人連花點時間都不肯,就想直接問我找答案。用這種態度根本就學不到任何東西,不管是那一方面的學問都一樣。
  2. 遇到問題時,先看看 Error log,嘗試去解決他,不行再去找答案。
    我在學 Linux 的時候,一個月上手,第二個月用 Debian 架出一個 Linux 桌面,第三個月開始管站。不是我行,是我遇到問題會嘗試去看 Error log,嘗試解決問題,就算解決不了問題,光是在解決的過程中,我就學到了更多東西。
  3. Ruby on Rails 是用 Ruby 寫的 Framework,這代表你要花點時間去看 Ruby。
    有時候有些人問的問題,或是寫的 code 不對,就開始怪 Ruby on Rails。可是我後來發現大多數的問題,都是對於 Ruby 不熟悉所造成。我想問的是,你在學 Java時,會連語法都不去看就開始寫嗎?你在寫 C++ 時,會連要怎麼寫 C++ 都不知道,就去寫程式嗎?那為什麼遇到 Ruby on Rails ,你會連 Ruby 都沒花時間去看,就開始寫 Ruby on Rails 程式呢?
  4. 不要好高騖遠,先用 Webricks 來當伺服器。
    有些人一定要一開始就架設好 Apache + Fcgi ,lighttpd+fastcgi,一定要一開始就將整個架設伺服器的架構都搞定,然後才開始學習 Ruby on Rails。但是這根本就本末倒置,一開始要學習的是熟悉 Ruby on Rails ,而非如何架設一個可以上線的系統。
    一個可以上線的系統需要的是 MIS 極為專業的技巧,但是 Ruby on Rails 專長是如何快速的開發程式,兩者不太一樣,都是需要時間去專精的東西,你在研發期應該作的是學習 Ruby on Rails,而非架設系統。我所認識一位矽谷公司老闆,他們就是先寫 Ruby on Rails 程式,然後程式直接放 Web Host 就好,等到流量夠大,有了足夠的資金,目前才在開始考慮請 MIS 來架站。其實到這個程度了,你也不用花時間學習架站,就多請幾個專業的MIS 來解決即可。
  5. 想做就做吧,想寫就寫吧。等到問題出現再來解決吧。
    有些時候,我會問自己這樣作有沒有考慮到其他衍生的問題,然後一再反覆的討論,結果到最後時間不夠了,還沒開始寫程式。這是我以前寫 PHP 的習慣,因為程式進行重構本身是非常困難的問題,一重構可能要花個一天到一周不等的時間,所以與其花那麼多時間如此不如一開始考慮清楚。
    雖然這個立意是好的,但是目前現實就是『計畫永遠趕不上變化,變化永遠趕不上老闆的一句話』,有太多太多巨細靡遺的 spec 因為客觀環境情況改變了而胎死腹中。與其去考慮全盤的狀況,花了太多時間,結果最後連一點東西都生不出來。不如一開始有了想法就先作出一點東西,遇到問題在進行修改即可。
    當然有人會問,那麼重構的問題怎麼辦。PHP 或是 JAVA 我不知道,但是 Ruby on Rails可以把重構的時間極小化。我開發 Ruby on Rails 程式至今,曾經寫了一個 Project 裡面重大的重構了 10次以上,每次重構的時間是一個小時到三個小時不等。

    為什麼?

    因為 Ruby on Rails 本身 code 量就比其他語言來得少,大概是一般語言的 1/5 到 1/10。程式碼行數的多少會跟重構時間呈現絕對正相關。也就是說,Ruby on Rails 極為精簡的程式碼會大幅度的減少重構所需時間。加上 Ruby on Rails 開發速度快,所以重構的速度也超快。在加上 Convention over Configuration 的概念讓重構可以維繫一個統一的標準,DRY原則會讓重構的 cost 減少。這些東西都會讓人感覺到,DHH在設計 Ruby on Rails 時,他其實不是想設計一個開發快速的架構,他的目標是設計一個重構快速的架構。

    所以,寫 Ruby on Rails 程式不要想太多,寫了就是,有問題就改吧,沒啥大不了。

以下是讀者們常問我的新手問題,我希望大家如果在遇到問題時先看看這篇,相信可以避開 90% 的問題。
  1. 我一開始就出現 Application Error,那是什麼問題?
    Ans :這是一個所有人都會遇到的問題,簡單的回答就是某些目錄(tmp,log)使用權限設定錯誤,你可以請參照這篇的回答
  2. 要是出現下面的 Error,那是什麼問題?
    WARN TCPServer Error: Address already in use - bind(2)
    /opt/local/lib/ruby/1.8/webrick/utils.rb:73:in `initialize': Address already in use - bind(2) (Errno::EADDRINUSE)
    Ans:這是另外一個幾乎每個人都會問的問題,但是這個問題總是會讓我很不爽,因為這代表你不看 Error Message,還有基本觀念不足。Address already in use 就是你今天要啟動一個 port,但是之前已經有其他程式將這個 port 註冊走了,所以你的作法就是關掉之前聽這個port的程式 ,或是換個 port 即可。
  3. 為什麼我的Rails無法連結 MySQL?
    Ans:通常 80% 的原因是你的 config 沒寫,或是沒寫正確。50% 的原因是你沒安裝 Ruby 的 MySQL Client,請用 gem i mysql 來安裝。
  4. 為什麼我的 Rails 連結到 SQL Server 有問題?
    Ans:我聽說 Rails 或是 PHP 對 SQL Server 支援不好。不過因為我沒有花錢買 SQL Server,我手邊沒有 Windows的機器,我寫程式暫時也不會去使用 SQL Server,所以我無法測試他的相容度好還是不好。
  5. 為什麼我的 Rails 出現 application error?
    Ans:如果第一個問題已經解決了,但是有時候寫的一半還是出現 Application Error。那代表你寫了一些 code 讓 Rails 不爽,請先看過 error log ,去 google 一下,去討論區問問,等到都沒解答,你可以嘗試來問我。


12/22/2006

Rails Cache 再探:Page Cache 使用心得

以前介紹過 Rails Cache 第一步 : Page Cache。自從摸透了 Page Cache 之後,本人實在愛不釋手,至今已經用 Page Cache 寫過 3 ~ 4 個敝公司的行銷專案。我發現到 Page Cache 最大的特色就是可以產生一個完全靜態的頁面,而且完全不經過 cgi 就直接給 Web Server讀取。所以當你使用 page cache ,這意味著
  1. 最快的速度(靜態頁面絕對最快)
  2. 最高的安全性(不跑 cgi 絕對最安全)
  3. 前端 Web Server 完全不需要安裝 Ruby on Rails
等絕對優勢。

當然你會開始發問啦,這個東西只有幾個靜態頁面,但是遇到需要動態更新的資料的頁面要怎麼辦?我的回答是『不怎麼辦呀!!!』,本來 Page Cache 就不是用在這方面的,他是用在特殊的用途的,而且這些特殊用途其實還蠻常見的。

適用範圍

有時候某些流量超級巨大的頁面,像是一個網站的首頁,通常流量都超大的。這個時候網站的首頁還要動態產生那就實在太苦了機器,還是讓 Page Cache 產生出來靜態頁面,然後一個小時更新一次就好。

或是我們寫到某些計算量太大的頁面,像是一些資料庫資料的分析,不管怎麼算都需要計算個 10分20分鐘的時候,既然無法每個 request 都動態產生頁面,還是用 cache 一天產生一次這樣的大量計算的頁面吧,而且通常這種計算量大的頁面都不會要求即時的。

另外一個使用範圍,就是一些小型行銷專案。有些案子是一些小活動的頁面,通常他們只需要一個到兩個小頁面即可,這個時候也可以使用 Page Cache。不過這個時候我用 Page Cache 的原因在於通常負責行銷活動的機器有時候也會派上其他用途,一家公司通常不會特別撥一個機器去做活動頁面,這樣太浪費機器的資源。為了擔心行銷活動跟其他任務的機器綁在一起,如果我的 cgi 哪裡出了問題,影響到公司其他 team 的任務就不好意思了。另外一個原因是其他 team 的機器如果跑的是其他的任務,通常 frontend web server 是經過某些用途特製化過了,網管不會希望這樣特製化的 frontend web server灌太多其他 cgi 程式影響原本的用途。這時候我也會使用 Page Cache 來寫 Ruby on Rails,這個方面是取其安全性跟
frontend web server 不需要安裝 cgi的特色。

使用技巧

至於要怎麼使用呢?我把我目前寫行銷專案的技巧講出來好了。

首先你需要安裝一個 Mongrel ,然後跑在你的 Ruby on Rails程式在 80 以外的 port,這裡用 4000 來說明好了。再來用 Firewall 去擋住 4000 port,只允許 localhost 可以 access 4000 port,這樣就相當安全了。

再來請在每一個 cache page 的 action 以外,另外寫一個 action 專門 expire 這個 page cache。這裡假設 action 名字叫做 expire。

最後用 crontab 在本機端上定期 trigger一下剛剛寫好的那個 expire action,記得要去 trigger Mongrel 開的 port 4000,而非 80 port。這裡就可以做到定期rotate refresh cache 的功能,並且剛剛不是有說到 firewall 僅僅允許 localhost 去 access ,就是為了讓本機端去做到定期 rotate 的功能。

結論

到目前為止,雖然這個方式算是 special case 專用,但是這個方式,我覺得相當的好用而且簡單易懂,兼顧 Ruby on Rails 的方便性,並且擁有優異的速度跟安全性,程式碼僅僅多加個四五行 add / expire cache 的程式碼。如果有人想將 Ruby on Rails 導入公司,但是 CTO 因為延展性,速度,安全性等等理由去打發你的話,可以先考慮使用這個方式來導入。通常一不導入則已,只要一導入 Ruby on Rails ,你的同事嘗了 Ruby on Rails 的甜頭,就很難回頭去寫原本的 PHP 或是 Java 了 XD


延伸閱讀


find_or_create_by :神兵利器

我應該是 lag 很久吧,居然今天才發現 find_or_create_by 這個神兵利器,早點發現我應該可以少打幾百行 code 吧。簡單來說,find_or_create_by 就是先去找說資料庫裡面有沒有這個資料,如果沒有他就順手幫你建立一個。很簡單的概念,但是卻又非常頻繁用到。

使用方式如下

今天有一個 User Model 有兩個 attribute ,其中一個是 name ,另外一個是 email。 如果我們想要找出一個名叫做 'abc' 的使用者,如果沒這個人,就創造一個,然後將他指定到 a 這個 Object 。使用方是就是
a = User.find_or_create_by_name('abc')

仔細去翻 SQL Code,我們可以發現
SELECT * FROM users WHERE (userss.`name` = `abc` ) LIMIT 1
BEGIN
INSERT INTO users (`name`, `email`) VALUES('abc', '')
COMMIT

如果想要更進一步,我們想找出名叫做 'abc' ,並且 email 是 abc@example.com 的使用者,並且將他指定到 Object a。使用方是就是
a = User.find_or_create_by_name_and_email('abc' , 'abc@example.com')

SQL code 就是
SELECT * FROM users WHERE (users.`name` = `abc` and users.`name` = `abc@example.com`) LIMIT 1
BEGIN
INSERT INTO users (`name`, `email`) VALUES('abc', 'abc@example.com')
COMMIT


我果然應該多花點時間再重新閱讀 Ruby on Rails 的書好了,那麼方便的東西居然都不知道。

Rubinius :又是另一個 Ruby VM

Ruby VM 已經夠多了,但是沒一個夠力的。本來 YARV 看起來還蠻有希望的,但是現在似乎 Ruby 1.9/2.0 不會支援 YARVjRuby 可能是最有機會成功的,但是受到 SUN 力量的牽制,還是會令某些人感到不好(我是不會啦)。

這時候出現 Rubinius 了。為什麼需要 Rubinius呢?

Why?: I believe that the future of the ruby core is in a simple core and a simple architecture that is easy to modify. Rubinius goes to vast lengths to keep the core parts as simple as possible. Because in the end, it shouldn’t just be me and a few core developers who can dive into the core and change things. I want it to grow and flourish in the hands of everyone, and I believe the only way to do that is to build in that virtue from the beginning.
並且他將目標放在兩個重要的地方上面,bytecode and native threads。他可以將 .rb 的檔案編譯成 .rbc 的 bytecode 檔案,所以有了 code 加密的過程,或許可以增加不少商業公司開發 Ruby 程式碼的意願。

但是話說回來,我還是比較看好 jRuby ,但是越多 VM 選擇應該是越好。

延伸閱讀


華文 REST 討論文章網摘

說到這就要講到我在 滿紙荒唐言,一把心酸淚,裡面所講到的
Rails 1.2 + REST : 討論 Rails 的核心價值 這篇更是可笑,我連REST 的好處都不甚了解,就大張旗鼓的吹 REST 的好?

我當然不是作學問態度那麼隨便的人,所以我開始花時間去整理大家對 Rails 1.2 裡面 REST 的用法以及玩法,先看看大家怎麼講,再慢慢自己學習 REST 的概念也是很好的。

以下就是華文 REST 討論文章網摘大集合。


  • 引述 :『Rails 1.2的主要亮点是REST。可以这样说,经过这次升级,Rails成为第一个把REST作为核心思想的主流Web框架,从而把其他的竞争性的敏捷Web开发框架又一次抛在了身后。』
    孟岩說明 Rails 1.2 對於 REST 的東西
  • 著名的Web技术专家、HTTP等诸多Web协议的主要起草人Roy Fielding从加州大学Irvine分校获得博士学位,其博士学位论文中描述了一种分布式软件的体系结构风格,被称为REST。
  • 引 述 :『今年7月份举行的RailsConf 2006上,David Heinemeier Hasson作了一个主题演讲,很清楚地讲了Rails 1.2中对于REST的设计,以及REST风格给Web应用设计思想所带来的革新。我第一次看到这个视频,就认为这可能是对Web服务端开发具有历史意义 的一次演讲。』
    孟岩對於 DHH 的翻譯
  • 引述 :『REST的意义不在于做一个网站,而在于网站间的互相调用变得异常直接。网站间的调用,也可以理解成不同系统间的调用。

    比如一个公司的CRM、workflow、财务系统、website...可以是一套大系统,那样太繁杂,也可以是分别几个独立的系统(decoupled systems),但是互相调用metadata就会非常不方便。一般有这么几种方式实现(从差到好排序):
    1、A系统直接调B系统的数据库
    2、用程序访问B系统的网页,取出A系统需要的东西
    3、各系统把经常要访问的功能写成web service
    4、各系统做一套api
    5、REST

    上面的例子说的是公司系统,大众网站也是如此,如果大家都用REST,mashup也会更容易,好的应用会更多。』
  • 引 述 :『Constraints is FreedomCRUD 形成了一种约束,把我们从权衡Controller和action风格这种无聊的事情中解脱出来,按照统一的风格来编写程序以及构造URL。使我们有精力 关注更重要的事。REST还避免我们编写大的Controller。可曾有人后悔曾经写过的包含十几个action的,并且action之间毫无联系的 Controller呢?其实大部分情况下,一个Controller有7个action就够了,并且这些action关注于同一Model,大大提高了 正交性.』
  • 引 述 :『Rails REST特性可以让Web服务技术用平台独立或编程语言独立的方式相互通信,各个不同应用程序之间的远程过程调用从来都是相当麻烦,今天试用了一下 REST,相比SOAP 和 WSDL 的确非常简洁好用。现在能够领会DHH在Rails的演讲中说的:“我不认为Rails应该向外部世界屈服,恰恰相反,Rails正在有力地让外部世界向 我们屈服。”这是狂,不过DHH也有资格狂!』
  • 引 述 :『我总觉得REST应该用于提供数据而不是页面,还是用用户和圈子作例子吧,感觉顺畅一些。比如某个用户的页面,他选一个圈子,点击“加入”就加入了这 个圈子;而圈子的管理员也可以选择用户,并点击“添加”把用户加入圈子。这里2个页面完成的是同一个操作,都是创建一个用户-圈子的关系,但操作完以后的 页面转向会不同。如果用REST来提供页面,如何来处理这些转向?另加参数?那不是搞复杂了嘛。所以我觉得应该是浏览器上通过AJAX请求这个 action,返回数据,浏览器脚本把数据处理成显示,这也是AJAX最适合的方式。如果只提供数据,实际上不需要7种action,4种就可以了』
  • 引述 :『ESTful核心就是资源,把关系也看作是资源,所以用户加入和退出组可以改成用户与组的关系这个资源的创建和删除。基于这一点我觉得RESTful应该翻译为REST风格,不给它个合适的中文词汇来代替,总是理解起来有些偏差。』
  • 引述 :『设想REST流行起来,新网站都缺省地提供符合REST标准的API,整个internet就是一个巨大的类库,这才是真正的webOS。这才是REST的魅力所在,是激动人心的地方,不是仅仅为了某单个项目的优化。』
  • 引述 :『ails生成XML轻而易举,Rails 1.2的REST也是一项另人心动的功能,而Spry也是以资源作为操作对象,这2者结合会发生什么?我试着学习Spry的内涵,并结合Rails做点测试性应用,以确定是否值得迁移稍大点的项目到它上面。』

  • 引 述 :『在許多地方看到了Rails 1.2將支援REST的消息,但是好像沒有在中文網頁說明rails是怎樣去實作REST的,那麼就來自己try try看囉...目前看到最重大的改變有兩項:1. scaffold_resource generator2. route map.resource』


iHower REST 系列
  • 引 述 :『重點是了解 resources 觀念: 為每個 resource 用單一 URI 定位,忘記用不同URL syntax來觸發不同動作的傳統思維吧(別用 ?action=somepage 之類的東西),URL應該是名詞而不是動詞。設計這個 resource 使用哪種 (HTTP) verb,設計有哪些 content types。』
  • 引述 :『本來這篇想寫的仔細點,不過後來我發現AWDwR第二版講 Resource-Based Routing 的頁數還不少(十幾頁吧,還蠻詳細的),要用 Rails 的人應該都去買一本,我想我這裡就不巨細靡遺了… :p』
  • 引述 :『什麼是REST?

    REST 是一種分散式超媒體系統(如WWW)的軟體架構風格,你可以想像它是一個良好設計的Web應用程式規則: 一組網路Web頁面(虛擬的狀態機器),其中 Client 透過點選超連結(狀態變換),結果是下個Web頁面(表示應用程式的下一個狀態)。』
  • 引述 :『Rails RESTful 系 列 彈 第四篇,我在這裡做些 Rails RESTful 工具介紹,相關文章有 REST tools for Rails 1.2。』
  • 引 述 :『我們花了好幾篇學習為何 RESTful 跟如何用 map.resources 來架出 server-side provider,而具體的重大好處則會在 ARes 中體現出來,我們可以像對 ActiveRecord 的物件操作一樣來處理 ARes,只是它的內部運作對象變成 Resource 而不是 Database (你感覺不到你在用Web APIs :p)。』
  • 引述 :『DHH的投影片提到一個概念:

    Constraints are liberating (a straight jacket for your mind)

    這裡指的 Constraints (制約) 是什麼? 我想指的是 Controller 不出以下七種 action』




12/21/2006

Rails + Memcached

這篇介紹如何將 Memcached 跟 Rails 做一個結合,先介紹一下 Memcached 這個著名的套件。Memcached 是一個分散式的 Memory Object 架構,最早是 Life Journal Team 為了加快速度而開發的套件。 他可以啟動許多 Deamon 來將所有其他 Client 的 Object 都集合起來,並且做到多機器同步化的工作。他最大的優點是在於不需要考慮資料 ACID,所以速度方面相當的快。

當然,我們可以使用 Database 去做到一模一樣的事情,但是其實 Database 在 ACID 上面已經付出太多 Overhaed。如果今天需要操作的東西,是一些像是 Cache ,Session 之類真的不見就算了的東西的話,你可以考慮使用效率比 Database 快的 Memcached。目前已經有相當多的網站使用 Memcached 的技術,可說是相當成熟。並且在 Web Server 使用考量上,Web Server 通常使用資源是高 CPU 低 Memory ,而 Memcached 是低 CPU 高 Memory 的使用方式,兩者可以結合彼此優缺點,讓 Web Server 跟 Memcached 跑在同一台機器上面來避免浪費資源使用率。

以 Ruby on Rails 來看,Memcached 可以用在
這三個用途。

我目前使用他都是在 Session Store 這個部分,他可以將 Multi Backend Application Server 的 Session 存放放在同一處,當然可以提高Rails Scaling 的部分。而在實做上面,Memcache 沒有設定檔。要在 Master 啟動一個 2G Memory,listen 在 1.2.3.4 ,port 11211 的 Memcache Deamon 是這樣啟動的
# ./memcached -d -m 2048 -l 1.2.3.4 -p 11211
Ruby 要使用 Memcached 是非常的簡單,只要用 Gem 安裝 Ruby 的 Memcached Client 即可。

這裡有兩個選擇,一個是出現在很多書上面的 ruby memcache ,也是比較老牌的選擇。
gem i ruby-memcache
但是現在還有更新的選擇, Robotcoop 所開發的 Ruby Memcached Client AP

# gem install memcache-client

要選擇其實是很容易的,因為兩者的 API 實做都一模一樣,應該說 memcached-client 遵照 ruby-memcached 的 API,但是 memcached-client 效能比 ruby-memcached 來得好,所以請用 memcached-client 吧。

要在 Rails 上面使用 Memcached 來當作 Session Handler 也相當的簡單,將 session store 設為 memcached 即可。你可以在 enviroment.rb 加入
require 'memcache'

memcache_options = {
:compression => false,
:debug => false,
:namespace => "app-#{RAILS_ENV}",
:readonly => false,
:urlencode => false
}
memcache_servers = [ '192.168.1.150:2222', '192.168.1.150:2223' ]

Rails::Initializer.run do |config|
....
config.action_controller.session_store = :mem_cache_store
...
config.action_controller.fragment_cache_store = :mem_cache_store, memcache_servers, memcache_options
...
end

...
cache_params = *([memcache_servers, memcache_options].flatten)
CACHE = MemCache.new *cache_params
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS.merge!({ 'cache' => CACHE })

其實 Rails 對於 Scale 的準備還算是相當的完整,很多地方都有相當簡單方便的實做。



延伸閱讀



12/20/2006

[公告] 增加『繼續閱讀』的欄位

為了方便大家閱讀習慣,我參考 Blogger Beta 中 Read More 與 Archive 只顯示標題 作法 這篇實做出繼續閱讀的連結,並且將 Comment 跟 Tags 放在同一行。有意見可以請大家留個言 :)

Ruby Email 驗證 Regular Expression

Email 驗證的 Regular Expression已經是所有寫網頁程式的人都會背的。我都是直接使用這段 regular expression
/^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/
但是今天看到 RFC 822 的 Email 驗證程式也有 Ruby 版了,順便紀錄一下好了。

#
# RFC822 Email Address Regex
# --------------------------
#
# Originally written by Cal Henderson
# c.f. http://iamcal.com/publish/articles/php/parsing_email/
#
# Translated to Ruby by Tim Fletcher, with changes suggested by Dan Kubb.
#
# Licensed under a Creative Commons Attribution-ShareAlike 2.5 License
# http://creativecommons.org/licenses/by-sa/2.5/
#
module RFC822
EmailAddress = begin
qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-' +
'\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
quoted_pair = '\\x5c[\\x00-\\x7f]'
domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
domain_ref = atom
sub_domain = "(?:#{domain_ref}|#{domain_literal})"
word = "(?:#{atom}|#{quoted_string})"
domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
local_part = "#{word}(?:\\x2e#{word})*"
addr_spec = "#{local_part}\\x40#{domain}"
pattern = /\A#{addr_spec}\z/
end
end


如何在 Rails 底下設定 Subdomain

現在網路流行 Subdomain ,也就是固定網址。像是這個 blog 的網址 http://lightyror.blogspot.com/ ,裡面的 lightyror 就是我在 Blogger 裡面設定的。基本上,如何設定固定網址是需要 DNS Record 儲存到 DB 的技術,像是 MyDNS 之類的技術,這裡 Ruby on Rails 搭不上邊。但是如果設定好固定網址的 DNS Mapping, request 到了 Ruby on Rails 的 Application,Ruby on Rails 要怎麼判斷 request 的 subdomain呢?

最簡單的方式直接使用 request.subdomain 變數來判斷。 今天一個 request http://abc.def.example.com/ ,request.subdomain[0] 就是 abc ,request.subdomain[1] 就是 def。

如果要比較有結構的方式,可以將 site 的 mapping 放在 DB 裡面。RailsTip 有一篇 Building A Multi-Site Application,裡面介紹可以使用 DHH 寫的 Subdmain 的 plugin AccountLocation 來做到這件事情。安裝方式是
script/plugin install http://dev.rubyonrails.org/svn/rails/plugins/account_location/
然後在程式裡面使用
include AccountLocation
即可。

延伸閱讀


12/19/2006

JavaEye 掛掉了


還蠻驚訝的,剛剛發現到 JavaEye出現這個畫面。

情況如下
当你访问JavaEye网站的时候,位于JavaEye服务器和你的浏览器中间的某个路由器在返回页面中植入如下代码
也就是說某個 router 會幫你把 response page 植入一個 XSS 的 script,簡直防不慎防。儘管我們可以寫很好的 HTML Filter ,但是掌控權不在你手上就沒輒了。唉,身為 Ruby on Rails 愛好者,我不希望這個優質的 Ruby on Rails 討論區垮掉呀。祝 JavaEye 及早解決問題。

解決方式除了原本網頁所說的
或者您也可以临时采取以下手段避免被感染: 编辑C:\Windows\system32\drivers\etc\hosts,加入一行:127.0.0.1 cool.47555.com
如果網站管理者希望網站早點起來,還有一個狠一點的作法。既然這個 XSS 只對於 IE 發作,可以在 controller/application.rb 加入
if request.env['HTTP_USER_AGENT'] == ' 瀏覽器的判斷'
加以 filter 掉 IE 的 request。相信 JavaEye 的客群應該都有自備 Firefox 可以使用,在這關鍵時刻先撐過再說。

PS.
User Agent 列表





Safari Mozilla/5.0 (Macintosh; U; PPC Mac OS X; zh-tw) AppleWebKit/418.9.1 (KHTML, like Gecko) Safari/419.3
Firefox MACMozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv 1.8.1) Gecko/20061027 Firefox/2.0 (lzyc)
Firefox Windows Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv 1.8.1) Gecko/20061010 Firefox/2.0
Opera 9 Opera/9.02 (Windows NT 5.1; U; zh-tw)
IE 7 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
IE 6 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)


12/15/2006

Models 需要分目錄放置嗎?

我以前一直在想的問題 『我現在的 Project 程式碼 Model File 會不會太多?需不需要分目錄來放置?』很快的就發現到,大家想的問題實在很相近。 Caiwangqin’s blog有一篇 将Rails的Models分目录存放 的文章,裡面提到如何將 Model 分目錄放置的方式 ,但是也提到他認為不需要分目錄放置
Rails使用固定的规范省掉了复杂的config, 一个Web app如果只有20张以下的Table,是不需要分目录存放Models的,如果超过这个数量,我认为也是应该将一个大的Web app分割成多个小的App来做,更有利于以后的分布和维护。
如果仔細想想,我還蠻同意這樣的看法。

雖然手邊最大 Project Models 程式碼高達 45 個,但是目前還沒有任何困擾,因為 Convention over Configuration 強制 Model 跟 Table 同名的因素,會讓你完全不會找不到你要的 model file 。

另外一個因素是,我受到這篇的啟發
REST的意义不在于做一个网站,而在于网站间的互相调用变得异常直接。网站间的调用,也可以理解成不同系统间的调用。
現在已經跟 Partner 討論如何將部分功能以 REST 方式拆出去這個系統。原因當然是為了不讓系統太過龐大,改了這部分的 code ,又得擔心會不會影響整體的穩定。目前已經想到要將整個系統拆成一個主系統,三到四個小系統,如果順利拆出來的話,最大系統的 Model file 數量應該也不會高於 30 個。

也就是說,純粹以我這個 Project 來考量的話,目前沒有將 Model 分目錄的必要性。


PS. 這篇文章講到如何Models File 分目錄放置 ,並且也有範例。
时间: 2006-12-08 14:10 评级: (0位会员评分) 引用 推荐 收藏

在control里面加上include Location就可以了

延伸閱讀



12/14/2006

Apache 2.2 + Mongrel 設定方式

本來沒有打算寫的,不過看到 RailsCN 似乎有人有問題,所以還是順便寫一下好了。架設一些觀念在此我有作介紹,可以參考一下。


設定 Mongrel Cluster

請將你的 Mongrel Cluster 設定好,這裡預設 port 從 4000 ~ 4009 ,一共十個,跑在 production 環境下
mongrel_rails cluster::configure -e production -p 4000 -N 10
mongrel_rails cluster::start
修改 Apache 2.2 設定檔

Apache 的設定檔放在 httpd.conf ,以下修改內容皆在 httpd.conf 裡面設定。

首先確定你的 Apach 2.2 有 enable apache 的其中一個 Module mod_proxy
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so
再來我們開始設定 Mongrel Cluster 的 reverse proxy 設定,首先我們給這組 cluster 取名叫做 examplecluster,他是10組 Mongrel ,跑在 port 4000 ~ 4009 之中
<proxy balancer://examplecluster>
# cluster member 1
BalancerMember http://127.0.0.1:4000
BalancerMember http://127.0.0.1:4001
....
BalancerMember http://127.0.0.1:4009
</proxy>
再來假設你的 hostname 為 example.com,我們開始設定 virtual host
<virtualhost example.com:80>
ServerName example.com
ServerAdmin root@example.com
DocumentRoot "/var/www/example.com/htdocs"
ProxyPass /images !
ProxyPass /stylesheets !
ProxyPass /javascripts !
ProxyPass / balancer://examplecluster/
ProxyPassReverse / balancer://examplecluster/
</virtualhost>

重點是在於 ProxyPass,ProxyPass 代表 images,stylesheets,javascript 等 static file 交給 Apache 處理,不要給 Mongrel 處理。 還有 ProxyPassReverse 要指定正確的 cluster name ,我們要指定為 examplecluster。

最後重起 Apache 即可。本設定改自著名的文章 Scaling Rails with Apache 2.2, mod_proxy_balancer and Mongrel,還有 Robin 的 在Windows平台使用Apache2.2和Mongrel运行Ruby on Rails。設定是在 Gentoo Linux + Apache 2.2.3 + Mongrel 跑完全沒有任何問題。

12/13/2006

一次連接 Multi Database

今天看到 Rails可以有两个以上的数据库吗 以及 Multiple database handling with Rails。他們的作法有點詭異,而且有一個關鍵性的問題,每次 request 每個不相關的頁面也都得連接一次 external database。可是 Rails 要做這件事情應該沒那麼複雜呀?

1. 設定 config

extradb_production:
adapter: mysql
host: localhost
username: root
password: blabla
database: extradb_prod
2. 在相關 Model 利用 estabilish_connection 去做連接而外設定
class lala < ActiveRecord::Base
establish_connection :extradb_production
end

然後收工,連跨 DB 的關連性都沒問題。

滿紙荒唐言,一把心酸淚

滿紙荒唐言,一把心酸淚,都言作者癡,誰解其中味 ....曹雪芹
有時候覺得自己好像寫了個不可思議的 Blog,目前 Google 排行穩居 Ruby on Rails 類繁體中文第一名,你怎麼查 Ruby on Rails 第一頁幾乎都會看到我的文章。

那又如何!


Grouping Controller 這篇我連查詢『是不是 Grouping Controller 已經被建議不使用』都沒查詢。Rails 1.2 + REST : 討論 Rails 的核心價值 這篇更是可笑,我連REST 的好處都不甚了解,就大張旗鼓的吹 REST 的好?還在 JavaEye 上面被人提醒說
谈的太虚了,或者说什么都没谈
哎呀,您說對了,我真的都沒有談,一點技術含量都沒有,那篇我覺得我寫得很差,我在 murmur。很多時刻,我覺得我在將 JavaEye 的文章簡轉繁,就算一篇。有時候我覺得我把 Ruby Planet 的文章英翻中,也是一篇。與其說我在寫 Ruby on Rails 的文章,還不如說我在轉錄眾人的文章還比較好。甚至更慘的是,有些時候我還會偷懶看別人翻譯好的文章,而不去看原文,天呀,我居然如此的偷懶跟怠惰。

其實我不是不想寫流芳百世的文章,只是我寫不出來

其實事情就是這樣,很多時候對於一些高手來說,我其實寫一些沒有太多意義的東西,我甚至越寫越覺得我該停了,我在自取其辱。夠了,讓真正的高手來引導我們吧。奇怪的是,以前的我完全不這們覺得,總覺得自己還蠻有點料的,我覺得我學問深度跟廣度都夠,天呀,我真是個無知的人。反而是我研究 Ruby on Rails 的越深,越覺得自己的渺小。或許我是漸漸踏入了學問的山,爬的越高,越覺得山的偉大。走的越遠,越覺得自己的渺小跟無知。

更奇怪的是,以前罵 Java 跟 PHP 罵的最重的我,漸漸不批評 Java 跟 PHP 了。有時候覺得技術沒有絕對的高下,你有優點就有缺點,通常你的優點就是你最大的缺點。像是 Java 兼容並蓄,彈性十足,自然就會為了這些優點付出了入門困難,繁瑣難耐的缺點。PHP簡單好用,上手容易,自然帶來了難以維護,結構不佳的缺點。但是這也只是通論,看過一些高手的 code 之後我發現,沒有技術高下之分,只有作者有高下之分。

我似乎漸漸開始領悟一些東西,雖然無法掌握全貌,但是我真的漸漸開始掌握了什麼。奇怪的是,這都是在我學習 Ruby on Rails ,用這個 Blog 去紀錄他之後發生的。或許我寫了許多東西,或許我啥真正的好東西都沒寫。但是似乎有些人藉由這個 Blog 得到了點東西,我也藉由這個 Blog 獲得了許多東西。

舉個最深刻的例子,Rails 1.2 + REST : 討論 Rails 的核心價值 這篇文章裡面寫到我無法掌握 REST 真正的好處,被 JavaEye 某位版友抬愛,轉錄過去後,馬上就有一位 cvu 大大開示我
REST的意义不在于做一个网站,而在于网站间的互相调用变得异常直接。网站间的调用,也可以理解成不同系统间的调用。

比如一个公司的CRM、workflow、财务系统、website...可以是一套大系统,那样太繁杂,也可以是分别几个独立的系统(decoupled systems),但是互相调用metadata就会非常不方便。一般有这么几种方式实现(从差到好排序):
1、A系统直接调B系统的数据库
2、用程序访问B系统的网页,取出A系统需要的东西
3、各系统把经常要访问的功能写成web service
4、各系统做一套api
5、REST

上面的例子说的是公司系统,大众网站也是如此,如果大家都用REST,mashup也会更容易,好的应用会更多。
之前對於 REST 的好處不太了解,但是藉由他的文章我的確有收穫,也開始稍微掌握了點 REST 的神髓。

雖然我沒寫什麼真正了不起的東西,但是我的確從『撰寫Blog』這件事獲得許多收穫。以後這個 Blog 我會報持著『雖然我無法寫出什麼好文章,但是還是希望這個 Blog 能夠為讀者們帶來些什麼』這樣的心態繼續下去。感謝各位,感謝上蒼。

12/12/2006

Running Rails on jRuby

道喜技术日记發表了一篇Rails框架技术讲座:在JRuby上运行,Rails框架软件。。我看完後發現重點如下
  1. 下載 jRuby 廢話XD
  2. 下載 ActiveRecord-JDBC
    gems install ActiveRecord-JDBC -r -y --no-ri --no-rdoc
  3. 所有使用 ruby 的 command 要改成 jruby
  4. rake 改成 jake

裡面介紹怎麼在 jRuby 上面跑 Rails ,內容很詳細還有附圖,大家可以連過去看看。



Grouping Controller

昨天在看Agile Web Development with Rails 第二版時,發現到 0.14 -> 1.1 之間果然加入了許多東西,舉個例子,Grouping Controller 就是一個我一直沒發現到的好用小技巧。

當你在開發 Rails 程式的時候,你會發現 Controller 數量會漸漸變大,同一個 Controller 底下的 Action 數量也會漸漸大起來,而這個問題就很容易造成困擾。另外我們會發現到一些特質,就算很多功能是屬於同一個 Controller ,他們底下某些 function 卻是有自己的族群,這時候我們要切成兩個 Controller 也不是,放在同一個 Controller 也略嫌冗長。

這時候就要使用 Grouping Controller ,你可以使用階層式的 Controller 來分類這些 action。

舉個例子吧,我們要寫管理介面當中管理書籍的頁面
ruby script/generate controller Admin::Book
這個會產生
app/controllers/admin/ 這個資料夾
app/controllers/admin/book_controller.rb 這個 Controller
app/views/admin/ 這個資料夾
app/views/admin/book/ 這個資料夾
本身 admin 只是母分類,只是在 controller 跟 view 當中多一個目錄來作分類,真正可以 access 到的是 book_controller.rb 這個 controller 跟相對應的 action。而仔細看 book_controller.rb 裡面, Controller 宣告的寫法也改成
class Admin::BookController

這個樣子。而你要 access 到 Grouping Controller 的 action1 你必須使用
http://url.com/admin/book/action1
這樣的使用方式。除此之外使用方式就跟原來一模一樣。

我本身開發程式的時候,發現到我這方面的 Controller 數量成長不大,並沒有特別需要這個技巧的理由。不過如果你們程式的寫法造成大量的 Controller 數量,或是 action 數量爆多。你可以考慮導入 Grouping Controller 來加強你的結構化。

Update :根據這個連結 , 這個作法並不被鼓勵

Putting Controllers in Namespaces

This is really more trouble than it’s worth. You run into all sorts of crazy errors if you do this and you’ll be confused and frustrated. You’ll then ask other people about it and they’ll either blow you off for using namespaces with controllers or procede to get confused and frustrated as well. Then you’ll say, “I with I had listened to Kevin and Chris”. If you want /admin/some_controller as an URL that’s fine. Use the routing that’s built into rails.

如果你有類似的需求 , 可以在用 route 去解決 .

延伸閱讀
  1. Controller Inheritance in Rails
  2. HowtoSensiblyOrganizeControllers
  3. Guide: Things You Shouldn't Be Doing In Rails


12/11/2006

Rails 1.2 + REST : 討論 Rails 的核心價值

我還記得以前我跟另外一個人討論 ORM 的時候,還有人說到 『ORM毫無意義可言,他一點實用價值都沒有』。的確在那時的世界裡面,ORM是被視為拖累框架速度的兇手, ORM無法像 SQL 語法一樣完全處理各種不同的情況,ORM沒有任何實用的必要,他只是一個科學家的玩具而已。但是 Ruby on Rails 一推出,在如此漂亮方便好用的 ORM 之下,彷彿任何網頁開發架構沒有 ORM 好像就遜了一截。於是每個新出的 Framework 開始學習 Ruby on Rails,加入 Active Record 類似的機制,彷彿 ORM 是所有 Framework 必須也是必要的機制。

到底在 Ruby on Rails 之前,這個世界是沒有 ORM 的需求,還是只是我們這些凡夫俗子看不到這樣的需求?

當我提到 Rails 1.2 導入 REST 的時候,大家的問題又變成『為什麼要用 REST?』『REST 有其他的好處嗎?』,其實說實在話,我不知道 REST 到底會帶來什麼樣的革命。或許他也只是個行銷名詞。孟岩先生曾經對這個事情發表評論
Ajax的出现标志着RIA时代逐渐走来,客户端将不再是清一色的HTML页面,也可以是一个Ajax的程序,通过 XMLHttp向服务器发起PUT和DELETE请求。这样,就要求服务器端在四动词的背景下重新思考应用的构造。传统上,服务器端应用只是通过REST 风格将部分服务暴露出来。而Rails 1.2则直接将REST直接作为构建整个Web应用的中心,这才是Rails 1.2的独特之处,也是张显Rails社群离经叛道和卓尔不群的地方。为了要采纳REST风格,Rails 1.2革新了Web应用的构造思想,整个领域建模的思想都有所变化。现在整个Rails社群都应当准备向REST时代迁移。
說實在話,我還是無法很準確的抓住孟先生的點。
因為如果眾多網頁程式設計師對於 REST 的好處跟壞處都不甚明瞭,那要怎麼推行 REST 呢?當大家都不用 REST ,那麼使用 REST 有任何意義嗎?但是看到 DHH 在 2006 Rails Conf 講解了 Rails 1.2 對於 REST 的導入這篇演講
之所以今天我们会在这里聚会,之所以Rails是今天的Rails,恰恰因为我们对很多事情说了“不”,恰恰是因为我们将很多人 拒之门外。如今Rails被越来越多的人接受,但我并不认为因此我们就可以背离先前的原则。所以,尽管我毫无疑问地支持Thomas的很多实用的建议,但 对他的论调则不以为然。我不认为Rails应该向外部世界屈服,恰恰相反,Rails正在有力地让外部世界向我们屈服。
凡事迎合大眾到底是金科玉律,還是庸人的想法。我回想到當我接觸 Ruby on Rails 之前,我似乎也是座落在『ORM毫無意義可言,他一點實用價值都沒有』這一群人。現在的我呢?又到了哪裡去呢?回到 REST 這個話題,到現在為止我還是不知道 REST 能夠為我帶來什麼東西?但是我願意去嘗試看看,因為

到底在 Ruby on Rails 1.2之前,這個世界是沒有 REST 的需求,還是只是我們這些凡夫俗子看不到這樣的需求?


漸漸的我發現到, Ruby on Rails 的核心價值不在於他的方便好用,其實就是在於 DHH 那一句『我不認為Rails應該向外部世界屈服,恰恰相反,Rails正在有力地讓外界世界像我們屈服。』。既然 REST 是一個網頁開發正確的方向 , 大家就勇敢的走下去吧 。不要像個隨波逐流的人們 ,勇敢的向前面繼續邁進吧!

有些人迎合世界的需求,有些人用良好的產品去創造這個世界的需求。

在 iPod 剛推出的那年,所有評論一面倒的偏向『這個世界並沒有任何硬碟式的 MP3 Player 的需求』,現在那些人又到哪裡去了呢?而 iPod 最後成功的原因很多,但是最主要的原因在於他放大硬碟式隨身聽的好處(一次可以將所有的歌放進去),而且他的實做讓硬碟式隨身聽的缺點縮小,所以他成功了。(註1)

同樣的道理 , 真正讓 REST 可以起來的原因,是 Ruby on Rails 到底能不能實做出一個很方便,很好用的 REST 架構?而非去問現在市面上到底有沒有 REST 的需求。當 Rails Team 真的做出一個很棒的 REST 架構的 Framework ,可以放大 REST 架構簡潔的優勢,卻又可以縮小 REST 的缺點,那全世界都會因為 Rails 而轉動,就跟當初的 Active Record 一樣。但是如果有這個需求,但是實做無法吸引大家使用,也不會有人去使用的。加油吧,Rails Team。

延伸閱讀

註1 :

iPod 當初讓評論家否定的原因是因為
  1. 硬碟式隨身聽用電量多,電池恐怕撐不住
  2. 硬碟晃動時容易有挑針的現象
  3. 硬碟歌太多了,你很難用隨身聽這樣的小螢幕選擇幾千首歌。
而 iPod 最後出來的成品 , 我們可以發現到 Apple 用了不少心思讓這些缺點都極小化 , 最有名的例子在於圓形轉盤的設計 , 讓人們可以快速的從第一首選到第一千首 。

12/08/2006

RadRails 0.7.2 Release

RadRails 0.7.2 在此下載 。雖然我不用 RadRails ,我用 vim ,不過我還是很歡迎 RadRails 的進步,至於 0.7.2 加了什麼,根據官方 Blog 說法
Mostly enhancements to the RHTML editor. Improved content assist that proposes closing tags. An outline view. A source formatter. Tab-expansion for templates.
而這些新增的功能,大家有興趣的人自己看看吧。

我還記得昨天有人跟我講『我覺得 Ruby on Rails 的致命傷是 IDE』,雖然我不認同有沒有 IDE 會造成致命的差距,但是有個良好的 IDE 畢竟是好事。目前最好的 Ruby on Rails IDE 應該就是 RadRails ,SUN 看起來也想利用 NetBeans 反攻 Ruby on Rails 市場,大頭們要怎麼打架,大家拉拉板凳看好戲吧,畢竟 IDE 有競爭才有進步。那個 M$ ,你不是已經抓了 RubyCLR 作者了,怎麼不見 Visual Stdio 上面可以跑 Ruby。




不過只是 Tools ?

最近在找國防役,談了好幾家,但是我發現到一件重要的事情,似乎大家都對我的 Ruby on Rails 經驗抱持著聽聽就好的感覺。似乎真正的商業公司對於『 Ruby on Rails 』這個詞只是代表好用的工具而已。而他們所真正注重的,卻是我以前做過一些比較偏研究的東西。不管是論文,還是以前研究的作品,我這些東西的確可以寫 Paper ,但是他的價值大概跟一般研究生的 Paper 類似,沒啥好也沒啥不好。
為什麼外面的公司會在乎那些我不重視的東西,卻不去重視我覺得真正有價值的東西?
的確,對於公司來說,採用 JAVA 或是採用 .NET,只不過是 solution 的不同,只是 Tools 的不同,一個企業的核心價值還是在於他擁有的 research group的能力,他所擁有的人才的能力。換個 tools ,只要核心價值還在,這家公司依舊可以發揮相類似的能力。舉個例子,今天 Google 作業系統全部換成 FreeBSD ,他擁有的人才跟技術實力依舊可以成為一個網路強權。

但是如果這個 Tools 能力遠超過現在常見的 Tools 呢?

Ruby on Rails 生產力有多強,這我就不詳述了。假設他生產力可以達到一般 tools 的兩倍(其實我覺得兩倍是低估 Ruby on Rails 的能力),那就代表我可以在半天的時間做到你一天可以做到的事情,所以我的產品可以比你少一半的時間就上線,這在搶時機點,搶市佔率是多麼大的優勢。

如果你要用人力去彌補生產力的差別,那代表你最少需要兩個人,才能跟上我的進度。何況真正當過 PM 或是修過軟工的人都知道, 人數越多,生產力不會等比例上升,因為人需要溝通才能合作,溝通的成本意味著開會時間,同事交換資訊時間,版本控制工具,管理成本。人越多,溝通的成本越高,兩個人帶來的生產力,真正帶來的可能只有 1.3 ~ 1.5 倍的生產力(我從書上看來的) 。而你真正要達到兩倍生產力,你可能需要 3 ~ 4 個人才能達到類似的生產力。

從成本來看,一個生產力極高的程式設計師就算薪資 Double , 他的薪資也絕對比相類似生產力的 3 ~ 4 人薪資來的便宜,而且人越多溝通成本會等比例上升,這在成本上,Ruby on Rails 反而是絕對的優勢。

能讓生產力小幅度上升的東西叫做 Tools ,但是能讓生產力成倍數上昇的東西叫做什麼呢?

人類的歷史一開始,叫做石器時代,青銅器時代,鐵器時代。這些時代不是以重要人物為名,不是以國家為名,而是以 Tools 為名,因為這些 Tools 徹底改變了原始人類的生活方式。愛迪生發明電燈,電燈這個 tools 讓人們活動時間從 6am ~ 6pm 延長到 6am ~ 24 pm 。電話的出現,改變了人與人溝通的方式,讓溝通距離大幅度延伸。網路的出現,更讓許多人,許多企業經營方式有大幅度的改變。這些 Tools 的出現都大幅度改變人類的生活,他們也只是 Tools 而已,但是這些 Tools 為人類生活帶來革命。

話轉回來,Ruby on Rails 當然沒那麼偉大可以跟電燈電話,網路相比。但是他為網路公司的經營方式,網頁程式設計師帶來巨大的改變。網路公司可以大幅度提高工作效率,大幅度減少開發所需人力,卻又可以降低溝通的成本。Ruby on Rails 讓 37 Signal 7 個人就可以開發出一般上百人的大公司不一定做的到的產品。

Ruby on Rails 不過只是 Tools ? 還是他根本就是一場網頁開發的革命?

12/07/2006

Agile Web Development with Rails 再獲獎項

Agile Web Development with Rails 又得獎了,這次是 Amazon 2006 的 Best Book,他獲選為 Computers & Internet 類別的第三名!!!恭喜這本得獎無數的 Ruby on Rails 聖經在出版一年多後依舊好評不斷。 希望明年就交給第二版發揚光大啦!!!

另外,我們可以發現科技書類前五名好書有四本是在講網頁開發的,或許反映了現在程式設計界的趨勢。

Mongrel 真的夠穩

在跑 Ruby on Rails 服務中,Lighttpd + Fastcgi 是 performance 很好的選擇,但是他有一個缺點,他很難管理,有時候會出現怪怪的情況。根據這個網頁的說法
The net effect is that my FastCGI dispatchers become unresponsive after a while, potentially after a huge traffic spike. Those sit there doing nothing and lighttpd is unable to talk to them.
當他在 high traffic 的情況下,似乎有時候會出現不太穩定的情況。雖然其實 Fastcgi 也沒那麼不堪,JavaEye 就是 run Lighty + Fastcgi ,也沒聽他們在說這樣組合不穩,Hemidemi 根據側面瞭解似乎也是跑 lighty + fastcgi,也還不是很穩定。但是如果你真的跑一個流量大到嚇死人的網站,或是你天性就是要求99.99%的穩定上線時間,有沒有更好的選擇?

這時候我們來看看另外一個跑 Ruby on Rails 常見的組合,Apache 2.2 + Mongrel。Apache 雖然效率不及 Lighty ,但是穩定度可是他的強項。而 Mongrel 呢?他夠穩嗎?

長時間觀察

我已經使用 Mongrel 跑在我公司一些流量較小的服務上面,至今已經快三個月了。除了我修改程式必須重新啟動 Mongrel 以外,他依舊每天任勞任怨的穩定服務。


尖峰時刻的穩定度

上面說的流量小服務當中,我曾經遇到一個小小的 DOS 攻擊,有個人曾經在極短時間內用 bot 塞了一萬八千多筆資料到資料庫裡面(汗,是我寫的程式有一個地方沒檢查到),Mongrel 依舊沒有任何不穩的跡象。我使用 ab 來做壓力測試時(concurrency 100), Mongrel 也沒有鬧情緒。

小結論

Mongrel 在安裝方便,管理簡單,scability 方便,以及穩定度上面表現的都相當的優異。我認為這是 Ruby on Rails 裡面,Application Server 目前最佳的選擇。

12/06/2006

RSpec 已經可以在 jRuby 上面使用了

來自 infoQ 的消息
RSpec, the Behavior Driven Development(BDD) library for Ruby, has been solidifying on JRuby recently.
可以看出 RSpec 對於 jRuby 的重要性,Priority 排那麼高,看來又得去看看 BDD 的意義。不過 jRuby 加入 SUN 之後真是速度驚人。

ps. Behavior Driven Development 老實說我並不是很了解,但是根據這個網頁可以知道一點皮毛。
It pulls together strands from TestDrivenDevelopment and DomainDrivenDesign into an integrated whole, making the relationship between these two powerful approaches to software development more evident.
Behavior Driven Development 主要是把 Test Driven Development 跟 Domain Driven Design 結合在一起。

Ruby 1.8.5-p2 發佈

官方消息,因為 CGI library (cgi.rb) 的問題,可能使有心人士 DOS 攻擊,所有使用 cgi.rb 都會被影響。請 upgrade 到 Ruby 1.8.5-p2 ,下載點在此

12/04/2006

NetBeans 可以寫 Ruby 啦!!!



看來 SUN 是鐵了心要往 Ruby 衝 , 自從 Sun Hire JRuby 作者之後的效應漸漸出現了 , 現在 NetBeans 可以撰寫 Ruby 程式了 。根據前面這個網頁的說法 , NetBeans 上面編寫 Ruby 一共有 semantic highlighting , code completion, mark occurrences 這些功能。還記得上次 Tim Bary 說到 Rails 的 Dev Tool 偏弱 , 看來 SUN 要出手幫 Ruby 社群解決這個問題了 。

Update:JavaEye 已經有簡單的使用說明出來了。

UnSpun : Amazon 開始使用 Rails


Rails 界的大事 , Amazon 開始使用 Ruby on Rails 了。UnSpun 是 Amazon 製作的一個線上投票的網站 , 你可以選出最好最壞等東西。當這個東西一開始上線 , 馬上出現恐怖的 Application Error , 不過在設定調整好之後 , 現在運行已經很穩定了 。這個網站代表的意義代表像 Amazon 這樣的大公司已經開始使用 Ruby on Rails 進行測試 , 是否大規模使用還有待時間考驗 。

TIOBE 12月排行:勝利的一年

TIOBE 2006/12最新排行出爐了,這個月 Ruby 的上升幅度也跟上個月類似,有 0.617 % 的上升,堂堂挺進 2.334%。不過在Javascript 跟 Delphi 也上升 0.2% 的情況下,只幹掉 SAS 邁向第 11 名。去年到今年 Ruby 排行上升了 9位,佔有率上升了 1.9% ,幾乎 80% 的佔有率都是今年拿下來的,只能說這是一個 Ruby 勝利的一年。因為是年尾,所以不作下個月預測,直接作明年預測。

依照這個走勢,我覺得明年的 Ruby 應該會
  1. 輕鬆站上十大Language
  2. 有挑戰 Python 機會
究竟 Ruby 會走到那裡呢?我也無法預測。只知道以他的走勢,他的後勁還是相當驚人的。

Position
Dec 2006
PositionProgramming
Language
Ratings
Dec 2006
Status
1 Java 19.907% A
2 C 16.616% A
3 C++ 10.409% A
4 (Visual) Basic 8.912% A
5 PHP 8.537% A
6 Perl 6.396% A
7 Python 3.762% A
8 C# 3.171% A
9 Delphi 2.569% A
10 JavaScript 2.562% A
11 9 * Ruby 2.334% A

11/29/2006

Agile Web Development with Rails 第二版


Ruby on Rails 界的聖經 Agile Web Development with Rails 的第二版終於脫離 Beta ,開始送印了。所有購買 PDF Version 的人應該都會收到一封信
The final version of Agile Web Development with Rails went to the printer last Friday. This means that the paper book will start shipping sometime around December 15.
然後所有購買 PDF 版本的人都已經拿到最新的 PDF 了吧 XD 。我想距離 Amazon 上面買到應該不遠,大概是12月中就可以開始訂購了。這本書一定要敗的啦!!!

11/28/2006

敝公司出了大事,萬事都得延宕下來

基本上,我肯待一家公司,代表我對他有忠誠,我喜歡或是認同這間公司的作風 。這次我們公司處於生死存亡之際,我恐怕沒太多時間寫 Blog ,本 Blog 在最近更新可能非常緩慢,請原諒,我想跟我的公司一同度過這個難關。

BTW ,看到這一長串討論文章,以及Hemidemi聲援的網友,我看到了德不孤,必有鄰這句話。

Comet on Lighttpd

Comet 果然是開始慢慢發酵,Lighty 作者 Jan 也開始對 Comet 有興趣了
Can I use it ?
Not yet. This is a idea how to implement COMET in a nice, performing fashion. On the way to 1.5.0 it will be implemented. Meanwhile I’m looking for comments on the idea and if it matches your needs for COMET and AJAX.
他還沒決定怎麼作,不過可以確定的是事情是他會在 1.5 上面 implement ,implement 方式可能是採用 mod_multiplex 或是 mod_mailbox 方式來作。

至於 Comet 可以拿來作的東西,AJAX 也都做得到。但是有些程式的架構本身就比較適合 Server Push ,而不適合 Polling。像是聊天室,IM等程式都是廣泛的 Comet 應用,期待 Lighty on Comet 的到來。

11/27/2006

What's new in Rail 1.2's ActiveRecord

Rails 1.2 RC 出了,我們也該好好看看多了什麼有趣的東西。基於我認為 Active Record 是 Rails 的核心價值,所以我先從 Active Record 開始說起。就如我剛剛說的 Active Record 是 Rails 的核心價值,在企業中,核心價值是很難允許修改的,所以這次的改版對於 Active Record 修改非常少 XD 我發現幾個比較重要的改變。

  1. Condition find 變得更加 Rails
    原本還很 SQL Like 的 Condition find
    Person.find(:all, :conditions => [ "last_name = ? and status = ?", "Catlin", 1 ])
    變成
    Person.find(:all, :conditions => { :last_name => "Catlin", :status => 1 })
  2. Has_through 更加好用
    支援 :uniq => true , << , delete ,改天嘗試看看能不能取代 has_and_belongs_to_many
  3. Has_one support dependent
    一共有
    :destroy, :delete, and :nullify 幾個 option
基本上在 Active Record 端修改的不多,不過光是 condition find 跟 has_through 的進步就值得我們更新到 Rails 1.2。

11/23/2006

Rails 1.2 RC 1 出了

雖然手邊的工作正在趕上線,但是這個新聞太大了,還是得報一報,Rails 1.2 RC 1出了。 賣點如下
  • REST REST REST !!!
  • response_to : 別人給你一個request,你可以選擇回應的 format,像是 HTML ,XML,RSS之類的。
  • Auto-Loading Lib
  • MultiByte:你沒看錯,Unicode Support
  • Route 改版
  • ProtoType :Prototype’s Ajax-based forms no longer serialize disabled form elements
  • Action Mailer 加強:MIME 1.0 Default
詳細情況看這裡吧。要嘗鮮的人請按
gem install rails --source http://gems.rubyonrails.org --include-dependencies
這次 1.2 版最主要進步就是 REST,讓 Ruby on Rails 繼續往更加前瞻性的 Web Framework 邁進。恭喜 Rails Team!!!

update : 有關於 Restful 的介紹,請看

Something really close

最近一周 Blog 都沒時間寫,實在很汗顏。因為 Ruby on Rails 的專案即將上線,這周的每天都在 tune performance ,修改Bug,寫文件,還有找出頁面忘記加入那些連結。最近的感覺就跟馬拉松要最後衝刺的心情一樣
『快成功了,不過還差一點』
到目前為止,程式研發時間大概是 2.5 個月 * 2 人。但是扣掉Partner 是學生,一周大概只有 2 人天,我一周上班時間本來就大概 3~4 人天,9~11 月之間我還配合公司行銷專案,隨手開發了 2 ~ 3個小專案。(因為這些案子我都用用 Ruby on Rails ,我才能『隨手』開發 =.=)所以總開發時間大概是 2 ~ 2.5 人月比較正確。

身為 Ruby on Rails 推廣者,我總是會被問到『國內有那些公司用 Ruby on Rails?』。雖然我花很多時間寫文件 。不過到最後發現,比起寫一百篇文章,推廣的效果還不如自己寫一個網站所帶來的效益來得高,也比較有說服力。LAMP 獲得尊敬也是等到 Wikipedia,Flickr,Digg 等網站規模起來了,才獲得商業公司廣泛的肯定以及採用。這個案子如果真的可以起來,相信會給國內 Ruby on Rails 界一個大大的振奮。

這個案子結束後,我該思考兵役的問題了~~~

PS. 最近壓力測試發現 Mongrel 真的很穩。

11/22/2006

HTML Filter 3: XSS

講了那麼多 HTML Filter 的例子 例子2,回到一個問題?如果照著之前的程式,有沒有辦法防範 XSS ?我現在給的答案是
不容易
為什麼?難道 Rails 那麼爛?錯了,看看這個表吧,當你的站遇到 Extra dot for absolute DNS 這種攻擊。
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
我們發現,有太多玩法可以放 XSS,而濾掉特定 tag 方式幾乎行不通,因為我們還是希望開放某些有用的 tag 像是 a 或是 img。但是我們可以減少這種可能發生率
  1. 使用 white list filter ,盡量少用 black list,whitelist 就是僅僅開放某些 tag ,blacklist 就是僅僅關閉某些 tag。我之前的 html filter 就是 white list 的。
  2. href 跟 src 裡面要檢查 javascript 的欄位
  3. 如果沒必要開放 tag ,盡量使用 h 通殺
延伸閱讀
  1. XSS 筆記
  2. XSS 列表

11/18/2006

Linux Journal Editor's Choice of 2006


Linux Journal 12月份選出了 Editor Choice of 2006 。 如大家預料的,2005~2006保持無敵狀態的 Ruby on Rails 1.1.6 當選了 Web Framework of 2006。另外一個喜訊是Ruby 1.8.5 當選了 Programming Language of 2006,主要原因是 JRuby 受到 SUN 的青睞,打敗了入選者 Object-C 跟 Python。

另外一些跟本Blog有關的獎項,Apache 2.2 打敗了 Lighttpd ,成為 Web Server of 2006。Postgresql 8.2 打敗了 MySQl 跟 SQLite 成為了 Database Server of 2006。

媽,我上 iThome 了~~

台灣 Ruby 社群接受 iThome 記者採訪,並且在 269期(2006/11/18~11/24)獲選為封面故事『搜索Ruby on Rails的高速魔法』。看完全部的章節之後,發現我講的話有點多 XD
Update: 訪談線上版已經上線了

11/17/2006

為什麼 Debian 跟 Ubuntu 上面沒有 ruby-gems?

Ruby Gems 是一個相當重要的 Ruby 套件管理系統,有太多 Ruby and Rails 的 Plugin 在 Gems 上面可以方便的下載。但是,FreeBSD ,MAC OS X,Gentoo 都可以直接用預設的套件系統安裝 gems ,卻只有標榜安裝快速方便的 Debian 跟 Ubuntu 沒有提供 APT 安裝。這到底是為什麼呢?

我看了一些討論串這裡網頁解釋了許多 Debian 上面為何不加入 Ruby Gems 的原因。
  • Rubygems packages are not compatible with the FHS. Rubygems follows the “one directory per package and version” rule.
  • It is not possible to do “normal” (FHS-compatible) installations of rubygems, and some ruby software developers have started to distribute their software as gems only.
  • Rubygems is source-intrusive. The require instruction is replaced by a require_gem instruction to allow for versioned dependencies. Debian and most other systems think that dealing with versioned dependencies outside of the source is a better idea.
  • There are currently no plans to improve RubyGems to ease the work of Debian and RPM packagers.
當然啦,每個套件系統都有自己的 concern,不過我不太能接受這個理由,難道 Ruby Gems 必須為了特定系統開發一個新的方式嗎?

到底是系統應該配合開發者的習性,還是開發者得自己去適應系統的規則?

但是看到這個網頁,我覺得這個講的比較實在點
Pure ruby gems are converted fine. However, ones including C extensions are not.
大意是如果這個 GEMS 是純 Ruby 當然歡迎,但是有些 Ruby Gems 是有 C extenstions 的(一些 Ruby Lib 像是 ruby-mysql ),那就很容易出現安裝錯誤,所以相當不建議使用 Ruby Gems 摟。 為此,Debian-Ruby 的 Daigo Moriwaki 也寫了自動轉換 GEM 成為 DEB 的程式,希望能方便大家打包 Ruby Gems 的 DEB Package。但是話說回來, Ruby Gems 那麼多,你怎麼可能全部包成 DEB ?Ruby GEMS上有些東西有安全性顧慮時,要緊急下載 patch ,這時通常官方會建議使用 Gem 去更新,難道 DEB 也可以立刻做到即時更新?還是要使用者自己苦哈哈下載 source 自己裝?

到底是系統應該配合開發者的習性,還是開發者得自己去適應系統的規則?

如果答案是後者的話,Ruby GEMS 要怎麼做到跨平台?所以 Daigo Moriwaki 也深知這個道理,也提供了 Unofficial 的 deb source XD
deb http://www.sgtpepper.net/hyspro/deb unstable/
deb-src http://www.sgtpepper.net/hyspro/deb unstable/
Update 完 DEB index 之後,apt-get install rubygems 即可。

11/16/2006

Applet in Ruby

Tr Ruby 是我第一個發現 AJAX 可怕之處的 Demo site,你可以在 Web 上面打入任何 ruby command,他也會立刻顯示 irb 的結果。JRuby 作者在自己 Blog 提出了一篇Ruby for the Web? Check,裡面有一個嚇死人的 Demo ,形式跟 Tr Ruby 是一樣的,但是唯一不同的是,他不是用 AJAX,而是用 Applet 去跑的,要看demo 請到這裡觀賞

Yes, JRuby can run in an applet. No, it's not that hard. No, the archive doesn't have to be this big (the applet above is about a 1.6MB JAR file, but it includes stuff it doesn't need). Yes, this means you could start writing stuff for web pages in Ruby. No, I'm not kidding.

作者也興奮的莫名其妙,我也興奮的莫名其妙!!!JRuby 自從 SUN 接管後,實在突飛猛進呀。

HTML Fliter Part(2):yml 化的 sanitize

根據上一篇 HTML Filter ,我們發現到這個 sanitize 很好用。但是,但是,他的 okTags 太醜了,我不喜歡。
def sanitize( html, okTags='a href, b, br, i, p' )
我在想,能不能更加的 Ruby 化一點,所以我就花了點時間改寫一下程式,變成了新版的 sanitize。我們將 allow 的 tag 跟 attribute 寫在 yml 裡面,然後執行時 load 進去,這樣似乎比較結構化一點,並且可以在 Rails 使用。License 是 MIT。

首先,你先寫一個 allow_tags.yml 的 file ,原本 okTags = 'a href target, b, br, p, i' 變成了
a:
- href
- target
b:
br:
p:
i:
a: 代表你接受 a 這個 tag ,後面加上 -href 代表你接受 a tag 底下的 href attribute ,如果你還要加一個 target attribute 就是加一個 -target ,不難懂吧。

如果你在 Ruby on Rails 裡面,建議放在 config 下面。然後,將這段程式(nopaste 版本)放到任何可以 loading 的地方即可。

HTML Filter

一般來說,通常使用者 input 的 field 都會作一些 filter 的動作,避免你塞一些危險的 HTML code (script之類)進去。而這部份 Ruby on Rails 作法很簡單,就是在前面加上一個 h() 即可。h 在Ruby on Rails 作什麼事情呢?他是 html_escape 的 alias ,他會將所有的 < 還有 > 變成 & lt; ,& gt;,比如 <sctipt>alert('a'); </sctipt> 會變成
& lt;sctipt& gt;alert('a'); & lt;/sctipt& gt;
這樣你就完全作不了亂啦,因為所有 tag 都不見了。但是這樣通常嫌太過嚴格一點了,有時候我們會希望開放一些字型大小,顏色的tag 給你用,這時候 h() 通殺的特性會讓一切都變得很麻煩。所以這時候 Ruby on Rails 就出現 sanitize() 這個 function,根據 Ruby on Rails 的api 上面解釋
Sanitizes the given HTML by making form and script tags into regular text, and removing all "onxxx" attributes (so that arbitrary Javascript cannot be executed). Also removes href attributes that start with "javascript:".
他會砍掉 script 這個 tag ,以及 onClick onLoad 之類的 attribute ,你沒有機會執行 javascript ,那就會讓你 key-in 任何東西都如 sanitize 字面上一樣『完全無害』。但是,Ruby on Rails 預設的 sanitize 管制方式又有點大方,你還是可以塞一些 div 或是 iframe 之類的 tag 讓你的網站版面爛掉。

所以我們需要一個可以自訂的 HTML Filter ,可以自由指定我們放行那些 tag 。這時候我發現了這個網頁,這是 Brad Choate's 寫的 perl 函式 sanitize_html 的 Ruby porting,你可以到這裡下載 Ruby 的版本。這只有一個函式,請將這個函式放在任何可以 loading 的地方,然後使用
sanitize( HTML 程式碼 )
即可。我們來仔細研究一下怎麼使用,他的第一行
def sanitize( html, okTags='a href, b, br, i, p' )
okTags 代表的意思是就是他允許的 tag ,目前有 a ,b , br , i , p 之類的 tag 。如果你輸入 <iframe>aaa</iframe>之類的不允許的 code ,他會出現
aaa
這樣的結果,所有不被允許的 tag 一律被濾掉。如果你想加入 span,font 這個兩個 tag ,那就將他變成
def sanitize( html, okTags='a href, b, br, i, p, span, font' )
以此類推,很簡單吧。至於第一個的 a href 代表什麼意思呢?第一個 a 代表 sanitize 允許 a 這個 tag ,第二個 href 跟第一個 a 中間沒有逗號分開,代表 sanitize 允許 a 這個 tag 使用 href 這個 attribute。你要是不信的話,打入 <a href="http://lightyror.blogspot.com" target="_blank">Haha</a>之類的程式,他只會出現
<a href="http://lightyror.blogspot.com">Haha</a>
只有 href 這個 attribute 會被保留,其他的刪無赦 XD。如果你想讓 a 這個 tag 加入 target attribute ,那麼就這樣寫吧。
def sanitize( html, okTags='a href target, b, br, i, p' )
如此他就會保留 href 跟 target 這兩個 attribute。最後,當我們輸入這樣的 HTML <a href="http://lightyror.blogspot.com">Haha 有頭無尾的 html code ,神奇的是他居然會補齊 tag 成
<a href="http://lightyror.blogspot.com">Haha</a>
恩,這個東西實做相當完整,看起來十分有用。