はじめてのRuby(Rack)挑戦記録
5:07
おはようございます。
今日は今までやろうやろうと思って放置していたRubyに初挑戦します。
perl使いなので書き方や考え方がperlに偏っているかもしれませんがご了承下さい。
5:10
まずはRubyのインストール
sudo apt-get install librack-ruby
5:13
hello world
参考にしたのはこのページ
http://route477.net/d/?date=20080716
mkdir rack
cd rack
vi criticalspeed.rb
rbというのはperlでいうところのpmなのだろうか?
→plのようなものらしい(by IRC)
criticalspeed.rb
require 'rubygems' require 'rack' class CriticalSpeed def call(env) [200, {"Content-Type" => "text/plain"}, ["Hello, World"]] end end
vi criticalspeed.ru
criticalspeed.ru
require 'criticalspeed' run CriticalSpeed.new
rackup criticalspeed.ru
no such file to load rubygems
sudo apt-get install rubygems rackup criticalspeed.ru
無事wgetでhello world成功。9292番portが標準みたい。
9:36
もう30分経過。新しいことをやると時間が経つのがはやいなあ。
次はKyoto Cabinet入れる。
実はこれのrubyバインディングが触りたくて今日rubyをはじめたようなもの。
参考にしたのはこのページ
http://1978th.net/kyotocabinet/spex-en.html
http://1978th.net/kyotocabinet/rubydoc/
sudo apt-get install g++ cd /tmp wget http://1978th.net/kyotocabinet/kyotocabinet-0.9.8.tar.gz tar zxvf kyotocabinet-0.9.8.tar.gz cd kyotocabinet-0.9.8 ./configure make make check sudo make install cd .. wget http://1978th.net/kyotocabinet/rubypkg/kyotocabinet-ruby-1.0.tar.gz tar zxvf kyotocabinet-ruby-1.0.tar.gz cd kyotocabinet-ruby-1.0 ruby extconf.rb
no such file to load mkmf
extconf.rb は Makefile.pl相当?
ruby のバージョンは1.8.7みたい。1.9を入れるべきかもしれないけど、よくわからないので保留。
sudo apt-get install ruby1.8-dev ruby extconf.rb make sudo make install
インストールに成功した模様
6:02
開始から約1時間経過。
今度はKyotoCabinetに値を入れる練習。
cd ~/rack
vi make_kyotocabinet_benchmark_htmls.rb
make_kyotocabinet_benchmark_htmls.rb
require 'kyotocabinet' include KyotoCabinet DB::process('casket.kch', DB::OWRITER | DB::OCREATE) do |db| db['www.example.com/index.html'] = 'hello kyoto cabinet' end
何故DBを閉じなくていいのかわからない。do |db|ってなんだ?tie?
→IRCで教えてもらったけどまだ???状態
エラーが出ていないので値が入ったと仮定して先に進む。
→作者のブログで解説が出て理解できた
mixi Engineers’ Blog » 京都収納棚紅玉束縛: Rubyで簡単、DBプログラミング
6:27
KyotoCabinetから値を取り出してRack経由で表示してみる。
criticalspeed.rb
require 'rubygems' require 'rack' require 'kyotocabinet' include KyotoCabinet class CriticalSpeed def call(env) req = Rack::Request.new(env) fullpath = req.fullpath().sub(/^\//, '') output = nil DB::process('casket.kch', DB::OREADER) do |db| output = db[fullpath] end if output [200, {"Content-Type" => "text/html"}, [output]] else [404, {"Content-Type" => "text/plain"}, ['404 not found']] end end end
置換の違いにとまどったけど、なんとかできた。
perl版とちょっと違うけどrubyのほうが短く書けるなあ。
7:25
別のマシンからベンチマークを取ってみる
/usr/sbin/ab -n 100 -c 10 http://192.168.1.123:9292/www.example.com/index.html Request per second: 15.81 [#/sec] (mean)
Rack(WEBrick)が遅いなあと感じる。Rackで使えるウェブサーバーって何がオススメ?
いずれにしても私のrubyスキルでは最適化なんてとても無理っぽい。
7:35
@j_kinjou さんからThinやEventedMongrelがいいとの情報 thx。
twitter便利。
sudo apt-get install gem sudo gem install rack sudo gem install thin rackup --env production -s thin criticalspeed.ru /usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:9292/www.example.com/index.html Request per second: 1193.70 [#/sec] (mean)
Mongrelを入れて何これはやい。もしかしてperl版よりはやいんじゃないか?
と思ったらデータが帰って来ていない。
Thinも何故か動かない
本日初のハマリなので朝食を食べる
9:00
とりあえずこの記事を公開する。
あとRubyのIRCに入ってみた。日本語が使えるのが嬉しい。
はまった原因は --env productionだった模様。その遠因としてRackのバージョンが0.1だった。
というわけでRuby Enterprize EditionというのをIRCで教えてもらいインストールした。
その後流れで、Passengerをインストール
http://www.modrails.com/install.html
11:04
IRCで教わって環境を新しくした結果Thinが動いた
sudo apt-get install gem sudo gem install rack sudo gem install thin rackup --env production -s thin criticalspeed.ru /usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:9292/www.example.com/index.html Total transferred: 190000 bytes Request per second: 591.91 [#/sec] (mean)
16:00
お昼寝していたらこんな時間になった。
50000ページKyotoCabinetに突っ込む時間を計測することにする。
make_kyotocabinet_benchmark_htmls.rb
require 'kyotocabinet' require 'rubygems' require 'random_data' require 'net/http' include KyotoCabinet Net::HTTP.version_1_2 html_body = Net::HTTP.get('www.real-unreal.info', '/readmejp100.html') DB::process('casket.kch', DB::OWRITER | DB::OCREATE) do |db| domain = 'www.example.com' db[domain + '/index.html'] = html_body; 10000.times do rand_word = Random.alphanumeric(5) dir_name = domain + '/' + rand_word ["index", *"index2".."index5"].each{|base| db["#{dir_name}/#{base}.html"] = html_body} end end
time ruby make_kyotocabinet_benchmark_htmls.rb 1.34s user 1.76s system 12% cpu 24.262 total /usr/sbin/ab -n 10000 -c 100 http://192.168.1.123:9292/www.example.com/index.html Total transferred: 138440000 bytes Request per second: 182.61 [#/sec] (mean)
というわけではじめてのRubyプログラミングとしてやりたいことは一応できました。
IRCで助けてくれたRubyコミュニティの方々ありがとうございました。
ソースでRubyらしくない書き方とかあると思うので気がついたら教えてください。
WEBrickとThinでパフォーマンスが一桁以上違うんですね。
18:00
RubyのIRCでソースを見てもらう。
Net::HTTPが1行で書ける事をおしえてもらったので修正
18:13
10000.times.do end という書き方を教えてもらったので修正
もはや最後のは元々自分で書いたコードと別物に修正
追記:作者の方の解説(ちょっと難しいです)
mixi Engineers’ Blog » 京都収納棚紅玉束縛: Rubyで簡単、DBプログラミング