会社のインターンに@CheerDreams@hrysdが来てくれたのでPivotalのユーザー数が上限超え。

Account Plans - Pivotal Tracker

ん”ー、どうする?とりあえずPivotal cloneのFulcrumを試してみました。

% git clone git://github.com/malclocke/fulcrum.git
% cd fulcrum
% heroku create fulcrum-fjord-jp
% heroku add ons:add shared-database
% heroku add ons:add pgbackups:auto-month
% heroku config:add MAILER_SENDER=noreply@fjord.jp
% heroku add ons:add send grid:starter
% git push heroku master
% heroku run rake db:setup
% heroku domains:add fulcrum.fjord.jp
% heroku open

Fulcrum

ちょっと使ってみます。

コレをHerokuに移しました。

何よりも「僕が12時に起きてパソコンを立ち上げていないと動かない」という致命的な問題への対応です。

他の人も登録可能にすれば便利かな?誰か頼む・・・。

komagata/random_lunch - GitHub

怖話.jpをHerokuからさくらVPS 512に移行したのでパフォーマンスを測ってみました。(怖話.jpのアプリに大きく依存しています。また日本向けのサービスなので手元から計測したためネットワーク的にHerokuは不利です。)

  • Heroku
    • kowabana.jp
  • さくら
    • oulu.fjord.jp

さくらVPSではnginx + unicorn + mysqlを使っています。

Apache Bench

% ab -n 1000 -c 100 http://kowabana.jp/
Requests per second:    6.12 [#/sec] (mean)
Time per request:       163.526 [ms] (mean, across all concurrent requests)
% ab -n 1000 -c 100 http://oulu.fjord.jp/
Requests per second:    38.29 [#/sec] (mean)
Time per request:       26.114 [ms] (mean, across all concurrent requests)

Chrome Developer ToolsでのDOMContent event fired

トップページをスーパーリロードした場合。

  • Heroku
    • 1.69s
  • さくら
    • 540ms

結果

人気サイトじゃないのでabの結果はそれほど気にしてませんが、DOMContent event firedはパラパラと残りのパーツが表示されるのは別として、ユーザーにとって「ページが表示された」と感じる実際の時間に近いと思います。それが3倍違うというのは結構な違いだなと思います。確かに体感速度でも速くなったように思います。

怖話.jpをHerokuからさくらVPS 512に移行することにしました。理由は下記です。

  • DB容量が無料の範囲を大幅に超えている。(一応容量オーバーしていても使える)
  • slug(リポジトリ)のサイズが制限(100MB)を超えた。(これはオーバーしているとpushできない)
  • ファイルアップロードが必要になった。(S3を使えば対応は可能)
  • 回線が遅い。(us westとかなので仕方が無い)

Amazon EC2にしなかった理由はまだ人気が無いのでお金をかけられないからです。もし売上が月数十万になったら移行します。

DB移行

HerokuのDBはPostgreSQLです。さくらVPS 512ではMySQLを使うことにしました。

現在のDB容量は37.4MB。レコード数は約2万件ぐらいです。heroku db:pullをしたら1時間たっても終わる気配がなかったので次の方法を取ることにしました。

  • herokuからローカルにpg_dumpを持ってくる。
  • ローカルのpostgresにpg_restore。
  • ローカルのmysqlにtapsサーバーを立てる。
  • ローカルのpostgresからtapsサーバーへpush。
  • ローカルのmysqlからmysqldump。
  • さくらVPSのmysqlにrestore。

大したデータ量じゃないのに、要はネット経由でtapsするととてつもなく時間がかかるのです。

「これ絶対もっと楽な方法あるよなあ」

などと思いながら作業しました。

% heroku plugins:install git://github.com/ddollar/heroku-sql-console.git
% heroku sql
SQL> select * from unk;

It's not psql. It's only send sql and return results.

Heroku-ja Meetup #1 : ATND

Heroku-ja Meetup #1 - 写真 - Google+

昨日行われたHeroku-ja Meetup #1でPaaS向けCMS LokkaというLTをさせていただきました。

正にHeroku三昧の時間で楽しかったです。会場のリクルート メディアテクノロジーラボ MTL Cafeも設備が整っていて、発表するのにとてもやり易かったです。Herokuオフィスの雰囲気や皆さんがどうやってHerokuを使っているのかというお話がとても為になりました。

Lokkaについてもruby1.9.2対応してくださった@tyabeさん(Herokuのデフォルトが1.9.2に変わって焦ったけど@tyabeさんのお陰でLokkaが動いてて良かった)に会えたり、@yagi_さんと次何実装するか話したり、Herokuユーザーの方々に宣伝できたりで行って良かったです。

RubyKaigi2011終わったらまたLokkathonやりたいです。

主催の@junyaさん、キャンセル待ちから運営側に回ることで滑り込むという裏技を使いつつ、ピザでみんな手がベタベタになるのに気を効かせて速攻ティッシュを買ってくるなどの名運営っぷりを見せた@rono23さんなどなど、皆さんありがとうございました。

HerokuのCedar StackはClojureに対応してる。要はLeiningenに対応してる。(RubyのBundlerに対応してるのと同じようなもん)

project.cljを見て必要なもんをpush時にインストールしてくれる。

;; lib/unk/core.clj
(ns unk.core
  (:use compojure.core
        ring.adapter.jetty))

(defroutes app
  (GET "/" _ "unk"))

(defn -main []
  (let [port (Integer/parseInt (get (System/getenv) "PORT" "8080"))]
    (run-jetty app {:port port})))
;; project.clj
(defproject unk "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :dependencies [[org.clojure/clojure "1.2.1"]
                 [compojure "0.6.3"]            
                 [ring/ring-jetty-adapter "0.3.8"]])
# Procfile:
web: lein run -m unk.core
$ heroku apps:create --stack cedar
$ git push heroku master
$ heroku apps:open

http://sharp-wind-970.herokuapp.com/

OMG!

環境変数$PORTを使う必要がある部分でちょっと躓きました。

Herokuの新しいCedar Stackを使う。

今までと大きく違うのはforemanを使ったprocess modelが導入されたこと。要はwebアプリもcronジョブもバックグラウンドタスクもみんな宇宙船UNIX号の仲間たち、foremanで平等に扱おうよということ。具体的にはProcfileにprocessの設定を書いてforeman経由で動かす。

# Gemfile:
source :rubygems
gem 'rack'
# config.ru:
require 'rubygems'
require 'rack'

class App
  def call(env)
    [200, {'Content-Type' => 'text/plain'}, ['hello']]
  end
end

run App.new
# Procfile:
web: bundle exec rackup -p $PORT

こんな感じ。

$ gem install foreman
$ foreman start

ローカルでもforemanで試せる。

$ heroku apps:create --stack cedar
$ git push heroku master
$ heroku apps:open

http://floating-dawn-850.herokuapp.com/

いいね!

process typeを自分で定義する

unixのprocessなら何でもありなので適当に定義できる。

# Procfile:
web: bundle exec rackup -p $PORT
unk: echo unk; sleep 1000
% foreman start
02:23:42 web.1     | started with pid 77070
02:23:42 unk.1     | started with pid 77071
02:23:42 unk.1     | unk
02:23:43 web.1     | [2011-06-23 02:23:43] INFO  WEBrick 1.3.1
02:23:43 web.1     | [2011-06-23 02:23:43] INFO  ruby 1.8.7 (2011-02-18) [i686-darwin10.7.0]
02:23:43 web.1     | [2011-06-23 02:23:43] INFO  WEBrick::HTTPServer#start: pid=77072 port=5000

こいつは自由だぜ。

# Gemfile:
gem 'barista'
gem 'therubyracer-heroku'
$ rails g barista:install

coffeeをrailsに提供するからバリスタってか?heroku上ではコンパイルするためのjs実装が無いのでエラーが出る(ローカルではnodejsを使ってます)。therubyracerはv8のrubyバインディング。therubyracer-herokuはそれをherokuで動かすためのもの(何やってるのかはわからない。見てない)。

ttfのwebfontをWebFont Loaderで読み込む時に"fontがapplication/octet-streamになってるぞ"みたいなnoticeが出る。

ローカル(WEBrick)では出てなかったので気付かなかったがHeroku(nginx + thin)では出てる。

キモイので自前のnginxがあるサーバーにfontを移して/etc/nginx/mime.typesに下記を追加。

application/x-font-ttf    ttf;

ブラウザのDeveloper ToolsのNetworkでcontent-typeが楽に確認できて便利。

怖話