Tuesday, February 28, 2006

Rails, Apache, CGI/FastCGI on Windows

安裝 typo 時, 在 apache 2 + windows 上碰到不少問題, 其實 Rails 1.0 產生出來的應該很好設定, typo 可能是比較早開發加上有調整過困擾了我, 把一些細節記錄下來以免忘記!
  1. 安裝 Apache 2, MySQL
  2. 安裝 Ruby, Rails
  3. 開始新的 web app, 打開 Dos Command Prompt
    > rails my_app
    > cd my_app
    > ruby script/server
  4. 請用 http://localhost:3000 看是否運作
  5. 詳細請參考 Rolling with Ruby on Rails
接下來我們進入正題, 當你有了 web app 後, 如何和 Apache 一起工作.

1. CGI 法
  • 打開 rewrite 功能, 移除 "#", 重要!
    LoadModule rewrite_module modules/mod_rewrite.so
  • virtual host 設定
    <VirtualHost *:80>
    ServerName mywww
    DocumentRoot d:/my_app/public/
    ErrorLog d:/my_app/log/server.log

    <Directory d:/my_app/public/>
    SetEnv RAILS_ENV production
    Options +FollowSymLinks +ExecCGI
    AllowOverride all
    Allow from all
    Order allow,deny
    </Directory>
    </VirtualHost>
  • 要設定, my_app/public 下的檔案, 基本上 Rails 1.0 產生出來是不用動.
    • .htaccess
      a) RewriteBase 要關閉
      #RewriteBase /myrailapp
      b) RewriteRule 要用 dispatch.cgi
      RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
    • 確定 dispatch.cgi 及 dispatch.fcgi 第一行, 要指到 ruby
      #!d:/usr/ruby/bin/ruby
  • 打開 c:/WINDOWS/system32/driver/etc/hosts 檔案, 加上
    127.0.0.1 mywww
  • 重新起動 Apache, http://mywww/ 或 http://localhost/

  • Alias 設定, 記得上面都要成功再來試 oh!
    • 加入這一段, 成功後可以移除上面 virtual host 設定
      Alias /myapp "d:/my_app/public"
      <Directory d:/my_app/public/>
      SetEnv RAILS_ENV production
      Options +FollowSymLinks +ExecCGI
      AllowOverride all
      Allow from all
      Order allow,deny
      </Directory>
  • 記得要改 my_app/public 下的檔案
    • .htaccess, 記得要打開 RewriteBase
      RewriteBase /myapp
  • 重新起動 Apache, http://localhost/myapp
2. FastCGI 法
  • 記得請先作完上面方法確定成功後再用 FastCGI 加快, 也比較好找問題
  • 安裝 FastCGI for Apache, 請下載 RubyForApache
    PS. 記得安裝時只要選擇 mod_fastcgi 就好了!!!
  • 設定你的 Apache
    • 加上 FastCGI module 功能
      #FastCGI
      LoadModule fastcgi_module modules/mod_fastcgi.so
      FastCgiConfig -restart-delay 120 -idle-timeout 150 -appConnTimeout 100 -init-start-delay 100 -startDelay 100 -maxProcesses 1 -minProcesses 1 -processSlack 1 -initial-env RAILS_ENV=production
  • 設定你的 my_app/public
    • .htaccess 要改成
      #RewriteRule ^(.*)$ dispatch.cgi [QSA,L]
      RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
  • 重新啟動 Apache, http://localhost/myapp 應該會快一點

Wednesday, February 22, 2006

聊聊 Ruby on Rails

我們來談談一下 Ruby on Rails, 或許可以找到一些新開發 Web 的方法.
  • Rails 是用 Ruby 語言開發, Ruby 是純 OO/SmallTalk like script 語言, 不用管 build 環境, 可以很快上手, 它的相關程式庫發展也很齊全豐富. 例如:
    RubyGems => installer
    REXML => XML library
    Rake => make/ant
    WEBrick => web server like Tomcat
    Test::Unit => unit testing
    XML-RPC => XML-RPC
    SOAP => SOAP
    DRb => Jave RMI, contributed computing
  • Rails 是一套 MVC web framework, 它的設計理念(名言)
    • Convention over Configuration(CoC)
      依照 Rails 定義好的命名規則, Rails 會幫你處理相關運作, 從 url, html page, ORM, 資料庫都套用此一原則
    • Don’t Repeat Yourself(DRY)
      盡量讓大部份的事交給 Rails 處理, 但還要能讓開發者達成目的
  • Rails 和 J2EE
    • Java 陣營: Java + Tomcat + J2EE, Struts, Spring + Hibernate(ORM)
    • Rails 陣營: Ruby + WEBrick(Apache) + Rails
  • Rails 基本是由 Action Pack 及 Active Record 完成
    • Action Pack => Action Control + Action View
      • Action Controller => 處理 URL/HTML Request 的大腦
      • Action View => 產生 html/xml 結果
    • Active Record => 處理資料庫且能將資料庫內容轉成 Object 讓你使用. 也就是一般稱Object Relational Mapping(ORM), like Hibername.
  • Rails 團隊有開發過不少 web apps 經驗, see 37signals. 所以 Rails 很完整又很寫的很讚, 從 cookies, session, filter, error, validate, html page layout, AJAX, testing(unit & function), ORM... 都有考慮, 且都有讓你可以加入設定處理你想要做的事.
  • Rails 不喜歡用 xml 來做設定, 都直接寫在 Ruby 程式裡(這是 Ruby 語言的優勢, 其實那些都是 methods 而已)或用 yaml, 這樣也比較好懂一些.
  • 提供一些簡單的 script 讓你可以快速產生程式
    ex: generate scaffold Product Admin
  • Rails 現在的問題? 你的 web app 要用 Apache(deployment 時). 但用 CGI 慢, 所以要用 FastCGI, 但好像有些安裝問題? Rails 紅了這問題應該會被解決.
  • 多語系處理問題?
  • 雖然現在的不少 web app 用 PHP 開發, 但我覺的 PHP 老了, Ruby + Rails 應該讓不少人眼睛一亮. 自己不是很能習慣 PHP 的直率(自己是開發 J2EE web app)
  • 現在也有不少新的 web framework 冒出頭
  • Java => Trails, Groovy=> Grails
  • Python => Django
  • PHP: => Symfony, CakePHP, Zend Framework, Agavi, PHP on Trax
    Top 10 PHP MVC frameworks

Monday, February 20, 2006

DRb - distributed ruby

DRb, distributed ruby 就像 Java/RMI 角色一般.
  • 參考文件
  • Server
  • require 'drb'

    class HelloServer
    def sayhi
    "Hello to my world!"
    end
    end

    DRb.start_service('druby://localhost:9000', HelloServer.new)
    puts DRb.uri, "Ctrl-Break to stop server!"
    DRb.thread.join
  • Client
  • require 'drb'

    DRb.start_service()
    obj = DRbObject.new(nil, 'druby://localhost:9000')

    # Now use obj
    5.times do
    puts obj.sayhi
    sleep 2
    end

Benchmark - Ruby 測量程式花費時間

Ruby 有提供不錯讓我們得知程式所花費時間
  • 使用 "Benchmark"
  • require 'benchmark'
  • 得知程式執行花費時間
  • COUNT = 500_000
    puts Benchmark.realtime {
    1.upto(COUNT) do
    a = "1"
    end
    }
  • 得知花費時間
  • Benchmark.bm do |x|
    x.report {
    for i in 1..COUNT
    a = "1"
    end
    }
    end
  • 報表格式
  • Benchmark.bm do |x|
    x.report {
    for i in 1..COUNT
    a = "1"
    end
    }

    x.report {
    COUNT.times do
    a = "1"
    end
    }

    x.report {
    1.upto(COUNT) do
    a = "1"
    end
    }
    end

WEBrick - Ruby 下的 web server

WEBrick 是一個完整的 Web 伺服器程式, 用 ruby 寫得蠻簡單易用的.
  • 參考文件
  • 範例
    • 啟動 WEBrick, port 為 2000

    require 'webrick'
    include WEBrick #

    #It's a function stub to start WEBrick
    def start_WEBrick(config = {})
    config.update(:Port => 2000)

    server = HTTPServer.new(config)
    yield server if block_given?

    ['INT', 'TERM'].each do signal
    trap(signal) { server.shutdown }
    end
    server.start
    end

    #To start WEBrick
    start_WEBrick do |server|
    #...see the following...
    end

    • 加入 html document root

    start_WEBrick do |server|
    #document root "/"
    doc_root = File.join(Dir.pwd, 'htdocs')
    server.mount("/", HTTPServlet::FileHandler, doc_root,
    {:FancyIndexing => true})
    end

    • 加入 servelet, 你的 XyzServlet 繼承自 HTTPServlet::AbstractServlet, 處理 do_GET/do_POST
    class HelloServlet < HTTPServlet::AbstractServlet
    def do_GET(req, res)
    res["content-type"] = "text/html; charset=UTF-8"
    res.body = %{
    <html>
    <body>
    Hello Servlet ...
    </body>
    </html>
    }
    end

    alias do_POST do_GET
    end

    class ENVServlet < HTTPServlet::AbstractServlet
    def do_GET(req, res)
    res["content-type"] = "text/html; charset=UTF-8"

    value = ENV[req.query['key']] if req.query['key']

    res.body = %{
    <html>
    <body>
    The server \"#{req.query['key']}\" is \"#{value}\" ...
    </body>
    </html>
    }
    end

    alias do_POST do_GET
    end

    #
    start_WEBrick do |server|
    #document root "/"
    doc_root = File.join(Dir.pwd, 'htdocs')
    server.mount("/", HTTPServlet::FileHandler, doc_root,
    {:FancyIndexing => true})

    #servlet "/hello"
    server.mount("/hello", HelloServlet)

    #servlet "/env"
    #ex. http://localhost:2000/env?key=OS
    server.mount("/env", ENVServlet)
    end
    • 使用
      • 請下載解壓 w.rar
      • 打開 DOS, 執行 ruby w.rb
      • 打開 Browser,
        • http://localhost:2000
        • http://localhost:2000/hello
        • http://localhost:2000/env?key=OS

Ruby 在 Eclipse 下的開發環境設定

Ruby 最近拜 Ruby on Rails(RoR) 紅透半邊天, 其實 Ruby 還真是不錯, 純 OO 又是 script 語言. 要上手並不難, 它基本程式庫也很豐富了, 除了 unicode 支援較不完整之外. 比起 PHP, 個人蠻推薦 Ruby.

開發程式習慣整合開發環境及專案管理, 近來在 Eclipse 下發展, 搭配 subversion/subclipse 做專案管理. 接下來簡單介紹大致開發流程

1. 安裝 java/J2SE50, 下載

2. 安裝 eclipse 下載 (解壓縮到 d:\eclipse 即可)

3. 安裝 ruby & ruby on rails, 這應該是你要玩 ruby 的原因, 參照

4. 開啟 eclipse, 安裝 Ruby Developement Tool(RDT) 參照
[Help]/[Software Updates]/[Find and Install...]/
"Search for new features to install"
"New remote site" 輸入
Name: "Ruby Developement Tool - RDT",
URL: "http://updatesite.rubypeople.org/release"

5. 設定 Ruby Developement Tool(RDT) 環境

  • [Window]/[Open Perspective]/[Other] 開啟 "Ruby" Perspective
  • [Window]/[Preference...]/[Ruby] 下設定 ruby interpreter & Ri/RDoc
    [Installed Interpreters]/[Add]
    Name: "ruby 1.8.2"
    Location: "d:\ruby\bin\rubyw.exe"
    [Ri/rdoc], Rdoc path: "d:\ruby\bin\rdoc", ri path: "d:\ruby\bin\ri"

6. Enjoy it

Subclipse 移除中文化

安裝 Subclipse 後出現中文用起來真是怪怪的...
下面方法可幫你回覆到英文環境

方法 1: eclipse 啟動時加上以下參數: -clean -nl en_US

方法 2: 或者拿掉那些 "zh*.properties" message 檔
到 plugins\org.tigris.subversion.subclipse.ui_0.9.105 目錄下
找到 SVNPluginUI.jar 移除 message_zh*.properties 檔案,
最後再移除 plugin_zh*.properties 即可
PS. 建議你用 WinRAR 蠻方便.