Ruby Tuesday 2010 首場

Update(2010/2/10): 這場的投影片和 Distributed Ruby and Rails 那場一樣 :)

Ruby Tuesday 今年的第一場聚會,由 godfat 和我帶來 EventMachine 和 Distributed Ruby&Background-Processing in Rails 兩場演講。

EventMachine 是一套使用 Reactor pattern 的 event-driven I/O 函式庫,你可以在許多 Ruby networking 工具發現它的蹤跡,像是 Thinstarlingamqpcramp

我的部份則是將上次在中研院的題目 Distributed Ruby and Rails 中的 Distributed Ruby 和 Background-Processing in Rails 這兩個準備比較完整的部分拿出來分享。

時間: 2010/2/9(週二)晚上七點到九點。

地點: 台北市 果子咖啡

報名網頁: registrano.com/events/ruby-tuesday-201002

Distributed Ruby and Rails

中研院OSSF工作坊邀請,這次很有野心的挑戰這個題目,試圖涵蓋 Ruby 生態圈中,有關分散式 Ruby 程式設計和 Ruby on Rails 架構的相關內容:

  • Distributed Ruby
    • DRb
    • Rinda
    • Starfish
    • MapReduce
    • MagLev VM
  • Distributed Message Queues
    • Starling
    • AMQP/RabbitMQ
    • Stomp/ActiveMQ
    • beanstalkd
  • Background-processing in Rails
    • script/runner
    • rake
    • cron
    • daemon
    • run_later plugin
    • spawn plugin
  • Message Queues for Rails
    • ar_mailer
    • BackgroundDRb
    • workling
    • delayed_job
    • resque
  • SOA for Rails
    • What’s SOA
    • Why SOA
    • Considerations
    • The tool set
  • Distributed Filesystem
  • Distributed database

訂出這麼大的 Agenda 範圍,自己也嚇了一跳,簡直就是差點準備不完。像是 RabbitMQ、MagLev VM、XMPP、MapReduce、SOA 等我還希望可以準備些實際的程式範例。本來預定一個小時的演講,最後也膨脹到快兩個小時才講的完。

Anyway,這是最後的投影片了,相信你也可以獲得這個領域的大局觀。之後有機會我會繼續分享更多實作經驗。

使用 logrotate 定期整理 Rails Log 檔案

(2017/5) linux 日志定时轮询流程详解 這篇解釋的更清楚

不像 Apache 預設已經設定好了,會定期整理成 access.log.1, access.log.2.gz, access.log.3.gz 等,如果你沒特別處理,Rails 底下的 log 檔案可是越長越肥。

這個系統工具是 logrotate,它的設定檔在 /etc/logrotate.conf,設定的方式還真是簡單 (參考自 Rotating Rails Log Files):


# Rotate Rails application logs
/path/to/your/rails/current/log/*.log {
  daily
  dateext
  missingok
  rotate 65535
  compress
  delaycompress
  notifempty
  copytruncate
}

其中 daily 表示每天整理,也可以改成 weekly 或 monthly
dateext 表示檔案補上 rotate 的日期
missingok 表示如果找不到 log 檔也沒關係
rotate 7 表示保留65535份
compress 表示壓縮起來,預設用 gzip。不過如果硬碟空間多,不壓也沒關係。
delaycompress 表示延後壓縮直到下一次 rotate
notifempty 表示如果 log 檔是空的,就不 rotate
copytruncate 先複製 log 檔的內容後,在清空的作法,因為有些程式一定 log 在本來的檔名,例如 rails。另一種方法是 create。

設定好之後,可以等明天,或是執行 /usr/sbin/logrotate -f /etc/logrotate.conf 看看。

傳參數到 Rake 中

傳統作法是用 rake blah foo=1 這樣的指令,於是就可以透過環境變數拿到:


  task :blah do
    puts ENV['foo']
  end

但是,最近看到新的 API 使用中括號的用法 (也不新了,從 0.8.2 開始支援),覺得挺有趣的:


  desc "passing 1 parameter to rake task"
  task :blah1, [:a] do |t,args|
    puts args.inspect
  end
   

執行 rake blah1[9] 會輸出 {:a=>"9"},注意到傳進來的變數值是字串。



  desc "passing 2 parameters to rake task"
  task :blah2, [:a, :b] do |t,args|
    puts args.inspect
  end

 

執行 rake blah2[foo,bar] 會輸出 {:a=>"foo", :b=>"bar"}

如果要有預設值,可以這樣做:

 
  desc "passing parameters with default values to rake task"
  task :blah3, [:a, :b] do |t,args|
    args.with_defaults(:a => 'foobar', :b => 1)
    puts args.inspect
  end    
  

此時執行 rake blah3 則是輸出 {:a=>"foobar", :b=>1}

對了,好奇 t 是什麼? 那是 Rake::Task 物件。

如何正確發送(大量) Email 信件

Update(2011/5): 推薦 Amazon SES 服務

Update(2010/5): So You’d Like to Send Some Email (Through Code) 也可以一看

Update(2011/7): 推薦 Postmark,也有 Rails plugin。

在眾多客戶需求中,我最害怕的其中一條”順便”要做的功能就是,在後台可以寄信給”全部的”使用者。

寄 “email” 而已,不是非常簡單嗎?

寄給幾個人是很簡單,但是要寄給”一群”人,那就不是件簡單的事情了,在這 spam 肆虐的年頭, 信寄出去不一定就能順利到達使用者的收件夾。

Engine Yard 的這兩篇 How To Ensure Your Email Gets DeliveredMaking Sure Your Email Gets Delivered 點出了寄 Email 要注意的事項:

  1. 處理退信

    Bonuce mail 是你寄出去的信件,但是因為某些理由(地址不對、對方信箱滿了)而被對方 mail sever 退信,這些 email 你必須要處理。如果你忽略它還一直寄,你就長得蠻像發垃圾信的傢伙,而會被列出黑名單之中。

  2. 與主要的 Email 服務商設定意見反應機制(Feedback Loop)

    Feedback Loop 是一項協助處理當你的 email 被使用者按下 “垃圾信” 的服務。透過主動接觸主要的 Email 服務提供商,去建立用戶意見反應機制。例如 台灣Y!Yahoo! Complaint Feedback Loopmsn等,減少被寄件者檢舉成垃圾信的次數。

  3. 建立自已的 email 清單

    建立你自己的 mail 清單。如果你的清單是買來的,不但收件人沒有同意要收到你的信件,也會有很高的機會是 bonuce mail。寄出大量的非允許郵件,終究會讓你的 IP 被列出黑名單。

    標準的作法是,要在使用者註冊後,且他們也確認收到註冊的認證信(透過email上的認證連結),如此便可以確保這個 email 的正確性,而不會變成 bonuce mail。你也應該避免寄出跟你服務無關的email,減少被檢舉成垃圾信的機會。

  4. 不要使用 100% 以圖片為主的內容

    減少使用圖片,像 Gmail 預設就不會讀取圖片,重要的資訊使用圖片可能會讓使用者預設就看不到。充滿圖片的的 email 也容易判讀成垃圾信。

  5. 使用垃圾信判讀工作測試

    收信的 mail server 通常會使用如 Spam Assassin 的工具來判讀是否是垃圾信,而你也應該用這類的工作檢查你寄出去的信件。www.brandonchecketts.com/emailtest.php 是一個線上的檢查工作,如果你的分數太低,顯然很可能被判讀成 spam。至於為什麼分數低,可以參考這篇文章

  6. 驗證 HTML

    如果你寄的是 HTML 格式,你應該檢查 HTML 格式是否正確。一封畸形的信件也容易變成 spam。

  7. 模擬測試終端使用者環境

    使用不同 email clients 實際測試,例如 litmusapp.com 這個工具。不同的 client 可能會顯示不同的結果。

  8. 專屬 IP

    是否有專屬的 IP。如果你的 email sever 是跟人共用的,很可能別人被 spam 了,跟著害到你被列入黑名單。

  9. 設定 SPF Validation

    SPF (Sender Policy Framework) 是一項 e-mail 協定來確認 return-path address 的正確性,用以防止垃圾信件。設定 SPF 可以改進你的信件發送成功率,特別是 hotmail(MSN)。

  10. 設定 Domain Keys Verification

    Domain Keys 驗證是另一種防止垃圾信件的協定。

  11. 設定 Reverse DNS 反查

    設定反向查詢的 DNS 記錄,如果你寄信的 IP 無法反查,可能根本就寄不到。

  12. 驗證寄信者地址

    你的寄信人 email 位址也要是正確存在的。許多 email 服務商會先檢查寄件人的地址是正確的,才會收信。

接下來麻煩的是,如果你終究還是不小心被列成黑名單,該怎麼辦? 這篇文章也列出一些常見的原因。

Anyway,我的結論是,還是交給專業的來吧~ 自己架設/管理 email server 不但辛苦又會被 blocked。如果信件量一天低於 500 封,我會建議採用免錢 Gmail 來寄信;超過的話,則有一些第三方服務可以採用,例如 Amazon SESSendgridAuthsmtp。 如果需要比較多的行銷功能,則可以考慮 MadmimiCampaignmonitorMailchimp 等服務。

BTW,既然提到了 Campaign Monitor,如果你有心做 Email marketing,他們家有不少值得一讀的資源,例如 Guide to CSS support in email clients 就十分有用。