>

危言聳聽就是這樣

剛看完「被新聞出賣的世界」更有感… 反正這些媒體寫文章也不用付什麼責任,搭個 Google Reader 被關閉的熱潮隨便寫寫舊好

Startup Metrics For Pirates.

Legends!

iDoneThis 架構剖析

之前為大家介紹了 iDoneThis 這個 service,今天讓我們來看看iDoneThis 的架構還有他們從剛開始到目前的開發心得吧。

一些數據

  • 每天收到 10,000 封 e-mail
  • 每天寄出 40,000 封 e-mail,大多數都是在美國時間的下午六點寄出
  • 每秒鐘數個 web-request
  • 1GB 的使用者資料,5GB 的資料庫
  • 文件有做即時索引和搜尋
  • 所有的 service 只用了一台 xlarge EC2 instance

架構

  • 幾乎所有事情都用 Python 搞定
  • Django 當做 web interface
  • apache + mod_wsgi 來處理 web server
  • postgresql 作為資料庫
  • 收到的 email 經由 sendgrid parse API 跑過後再用自己寫的 email processor 處理
  • 前端: CoffeeScript, backbone.js, jQuery, sass
  • lucene + solr 作為搜尋之用

Email - 從 Gmail 到 Sendgrid

由於直接用 EC2 instance 送信很容易被判定為 spam,所以剛開始 iDoneThis 是用 gmail 的 BCC 來送信的,之後就換成了 SendGrid

iDoneThis 寫了一個 script “sendmail” 來跟 SendGrid API 互動,直到今天這個 script 還是被使用著,不過可靠度方面也大大改善了。剛開始的 sendmail 只是一個簡單的迴圈來處理資料庫當中的東西,現在已經變成了會追蹤寄送 e-mail 當中的不同狀態並且做些相對應的處理。

為了處理收到的 e-mail,剛開始 iDoneThis 寫了一個大概兩百行的 “getmail” script 來透過 IMAP 存取 gmail,起初這個 script 很不穩定,而且當 script 出錯的時候會讓資料庫爛掉,所以在跑 getmail 必須有人在旁邊看著。不只這樣,還必須來處理一些不必要的文字(簽名檔、回文等等)以及 encoding 等等的問題,為了要搞定這件事情,getmail 長到了大約 800 行左右。

持續了一段時間之後,iDonThis 捨棄了 getmail,轉為使用 SendGrid 的 incoming parse API。主要的原因是因為 gmail 對 IMAP 存取有 rate limit,所以沒辦法快速的把 email 處理完。

規模化

起初,iDoneThis 主要面對到的瓶頸不是在技術上面,而是在開發時間上面,就算到今天還是如此,對 iDoneThis 來說,這代表著效能以及規模化的議題主要是圍繞在簡化程式設計上面。

想要做到這件事情,第一步就是盡可能的限制要開發的功能,或是把一些部分外包出去。只有在確定開發出來的功能有人用之後才會做優化。

再來,儘管可能會犧牲效能,還是要盡可能讓程式碼精簡。舉例來說,使用 Django ORM 不一定會產生有效率的 SQL 查詢,但是只有在實際上線而且發現會產生效能問題之後才會做這部份的優化。這麼做除了可以避免過度的優化外,也讓程式碼看起來乾淨許多。

隨著收到和寄出的信件越來越多,iDonThis 考慮到轉換到多台 server 的架構。不過這會讓架構上面複雜不少,也會帶來些許的麻煩。為了可以節省開發者的時間和簡化成是架構,儘管可以用好幾台 small EC2 instance 搞定一樣的事情,iDonThis 還是用一台 xlarge EC2 instance 搞定。

最重要的部份是 iDonThis 有做到 continuous deployment,每個開發者都可以在幾秒之內把程式碼 deploy 到 production server,這代表著開發環境跟 production 會是一致的,這也代表在某個功能上線之後可以很快的做出相對應的反應。

重新架構

剛開始的 iDoneThis 只是一個很簡單的 Django 專案,只有幾個 models、views 和 templates。儘管產品一直在進步,不過 iDoneThis 依舊是在比較舊的 web 應用架構上面 - 所有在上面發生的事情都伴隨著頁面讀取和送出表單。有一段時間這樣運作的還不賴,不過過了一段時間之後使用者希望可以有更好的使用者介面來存取他們的資料。

起初 iDoneThis 用了一堆 jQuery 來完成需要做的工作,雖然可以動,但是 code 變得很混亂而且很難除錯。為了希望盡可能的簡化前端的程式碼,原本的 jQuery code 被 CoffeeScript 和 Backbone.js 取代。隨著時間的演進,iDoneThis 的 backend 變成了 API-based 的架構。Django web service 分為兩個部分,一部分是負責提供 json API,另外一部分是負責吐出前端的程式碼以及 html 的部份。

目前為止,這種模式的程式碼比舊方法簡單許多而且更容易除錯,儘管還是花了不少時間才變成如今的樣子,不過由於程式碼簡潔許多,所以之後也可以更容易的增加新功能以及除錯。

這當中 iDoneThis 學到了什麼

  • 把麻煩的事情外包,而且是盡可能的外包。iDoneThis 來說,把所有 email 相關的事情都交給 SendGrid 處理。當然可能在某些時間點或許把這些事情自己刻些 tool 來處理是有意義的,不過對於新創公司來說,這個時間點可能會是在遙遠的未來。
  • 簡化比效能重要。儘管或許可以用 nginx 跑在一個比較小的 EC2 instance 上面,不過用 apache + mod_wsgi 一切都處理的很好。對 iDoneThis 來說,都是盡可能的用最簡單的方法來完成工作,關於效能的問題之後再考慮。
  • 有一小段時間 iDoneThis 打算把資料庫和 web server 分開跑在不同的機器上面,不過後來發現帶來的問題大過於好處,所以現在都是跑在同一台 EC2 instance 上面。

參考文章: IDoneThis - Scaling An Email-Based App From Scratch

昨天 iTunes Metallica 的專輯只要 20 元,不過我已經有實體 CD 了 …

使用 iDoneThis 來增加你的生產力

身為一個 Programmer,我們總是有滿滿的工作在身上,要怎麼樣增進自己的生產力呢?有關於幫助增進生產力的討論很多,像是 GTD 就是其中之一,不過除了 TODO List 之外還有沒有其他的方法可以幫助我們呢?

過去幾個禮拜我使用了 iDoneThis 這個服務,iDoneThis 的概念很簡單,每天這個 service 會在你指定的時間寄信給你,你只要回覆一封 e-mail 就可以記錄自己一整天做了些什麼事情。每天記錄的結果,就會列在如下圖所列的行事曆:

iDoneThis

iDoneThis 的概念看似很簡單,不過對我來說真的有增進生產力的效果,到底是為什麼呢?

  1. 它讓我可以很自然的紀錄每天做的事情。收發 e-mail 是我每天都一定要做的事情,所以把記錄這件事情融入在原本的 workflow 當中是在順暢也不過了。我不用另外開什麼軟體,也不用打開我的筆記本,我只要像平常每天要做的事情一樣:打開收件夾、回信。這樣就完成了記錄的工作。
  2. 它讓我思考更多關於事情的先後次序。透過每天的紀錄,我可以再檢視一次今天做了什麼,想想明天可以做什麼,再調整一下自己的 TODO List。
  3. 它會讓我更有動力完成每天應該做的事情。人性是很奇妙的,雖然這只是一封信,不過這封信會讓我再回信之前想想是不是還有什麼事情其實自己可以今天做完而沒做的,常常因此我每天的 TODO List 可以減少了一項到兩項。

你是不是也希望增進自己的生產力呢?個人版的 iDoneThis 是免費的,如果想要跟你的團隊一起使用,那麼每個月一個人只需要美金三塊。就從今天開始試試看吧,或許你也會跟我一樣喜歡上這個簡單但是相當有用的服務!

不知道為啥今天晚上腦子裡面都是 Highway Star…