Hatena::Grouprubyist

takuma104のRuby/Rails日記

ツッコミ大歓迎!間違等ありましたらご指摘ください! / はてダはこちらで書いてます。

|

2008-04-07

Apache(SSL) Proxy + Mongrelのポイント

| 16:07 | Apache(SSL) Proxy + Mongrelのポイント - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク - Apache(SSL) Proxy + Mongrelのポイント - takuma104のRuby/Rails日記 Apache(SSL) Proxy + Mongrelのポイント - takuma104のRuby/Rails日記 のブックマークコメント

すでにApacheSSLで動いているサーバに、ちょっとRailsのアプリを追加したかったのですが、Fastcgiが若干めんどうそう&バグあり(?)みたいなので、あんまりお手軽に、みたいな感じでなさそうです。そこで、もうちょっとお手軽そうな方法で、ApacheはProxyにして、基本Mongrelで動作させようと思いました。で、ちょっとハマってすぐ解決したので、書いておきます。ハマりどころはSSL特有のところなので、普通はここではハマらないかも。

まずApacheの設定に

RequestHeader set X_FORWARDED_PROTO 'https'
ProxyPass /app http://127.0.0.1:3000/app
ProxyPassReverse /app http://127.0.0.1:3000/app

の3行追加(VirtualHostとか使っている場合は、その辺りとか、適宜で)で、Mongrelは、

$ mongrel_rails start -d -p 3000 -e production --prefix /app

とかで起動すると(ここでは--prefix /appがポイント)

https://example.com/app

とかからアクセスできます。apacheの設定の方の、X_FORWARDED_PROTOがポイントです。これが無いと、Railsアプリがリダイレクト返すときとかにhttpのままになってハマります。

以下参考にさせていただきました:

no title

404 Not Found

GildasGildas2012/10/16 07:12The genius store called, they're runnnig out of you.

xogkcwxogkcw2012/10/16 21:45BFXJC5 <a href="http://wevhpqolyryb.com/">wevhpqolyryb</a>

ycjmliilyycjmliily2012/10/19 14:00UCs7nA , [url=http://euxflqelfmac.com/]euxflqelfmac[/url], [link=http://sbwbzdvcachg.com/]sbwbzdvcachg[/link], http://fkkujmoqgnsk.com/

kcseuikcseui2012/10/20 01:34zgpJdw <a href="http://ygzgibyrrrcs.com/">ygzgibyrrrcs</a>

epcygkepcygk2012/10/20 11:458Nlyr2 , [url=http://koklsldrfxlt.com/]koklsldrfxlt[/url], [link=http://rspwkzmbwljc.com/]rspwkzmbwljc[/link], http://tdrjremfuprg.com/

jj2013/11/11 14:44参考になりました。ありがとうございました。

トラックバック - http://rubyist.g.hatena.ne.jp/takuma104/20080407

2008-03-31

ほかのOSで動いてるのに、なぜかWindowsだけで動かないときのありがちなミス

| 02:16 | ほかのOSで動いてるのに、なぜかWindowsだけで動かないときのありがちなミス - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク - ほかのOSで動いてるのに、なぜかWindowsだけで動かないときのありがちなミス - takuma104のRuby/Rails日記 ほかのOSで動いてるのに、なぜかWindowsだけで動かないときのありがちなミス - takuma104のRuby/Rails日記 のブックマークコメント

つうかこんなの常識とか突っ込まれそうですが。

open('hoge') do |f|
  f.read
end

とかして、readした内容が化ける。これは、Windowsだと、fopen(3)がデフォルトで、テキストモードなため。ほかのOSは普通バイナリモード。

解決策は、

open('hoge','rb') do |f|
  f.read
end

とかすればOK。

あとは、

open('hoge') do |f|
  f.binmode
  f.read
end

とかでもOKみたい。こっちのが汎用的??

なかだなかだ2008/04/02 11:29openしたままでunlinkしようとしたりとか。

takuma104takuma1042008/04/02 12:24あー、あんまりお行儀良くなかったですね。
ブロック構文にしてみました。

moromoro2008/04/02 13:14Symbol#to_procがあると File.open('hoge','rb',&:read)と書けてカッコいいということを某所で教えてもらいました。

takuma104takuma1042008/04/02 13:49おお、これみたいな感じですね。確かにスマート。
http://wota.jp/ac/?date=20060309#p04

takuma104takuma1042008/04/02 13:52こっちのがええかな?
http://nov.tdiary.net/20060317.html

トラックバック - http://rubyist.g.hatena.ne.jp/takuma104/20080331

2008-03-17

Lighttpd + Rails2.0で、fcgiを独立起動(spawner使用)の場合のコツ

| 22:40 | Lighttpd + Rails2.0で、fcgiを独立起動(spawner使用)の場合のコツ - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク - Lighttpd + Rails2.0で、fcgiを独立起動(spawner使用)の場合のコツ - takuma104のRuby/Rails日記 Lighttpd + Rails2.0で、fcgiを独立起動(spawner使用)の場合のコツ - takuma104のRuby/Rails日記 のブックマークコメント

うちではだいたいこの設定で動かしています。

no title

フロントのhttpdlighttpdで、lighttpdが起動する際、一緒にfcgiを起動するのではなく、(すでにspawnerで)独立して起動しているfcgiプロセスにソケットでfcgiプロトコルで通信する、というタイプです。これだと、たとえばrailsのapp以下を更新したときに、lighttpdごと再起動する必要がなくて、

./script/process/repair -a restart 

とかすればOKなので、たとえばそのlighttpdが複数ドメインを運用している場合とかでも、そちらに一切影響を与えないで、railsだけ再起動というのが出来て凄く便利です。

ですが、この記述若干古いのと、なにかあってfcgiのプロセスが死んじゃったときに、死んだまま誰も起動してくれないので(そして誰もいなくなる)、lighttpdは生きているんだけどrails部分だけ機能停止、みたいな悲惨なことがよく起きてました。とりあえず、解決法が見つかりましたので書きます。

まず、inspectorという便利なコマンドがあります。

 ./script/process/inspector 

実行すると

  PID S USER      STARTED     TIME %CPU    VSZ MAJFLT COMMAND
24375 S hoge       Dec 26 00:23:10  0.0  53440      0 /usr/bin/ruby /hoge/dispatch.fcgi
20790 S hoge       Mar 16 00:00:37  0.0  49448      0 /usr/bin/ruby /hoge/dispatch.fcgi
 2701 S hoge       Mar 12 00:02:45  0.0  50292      0 /usr/bin/ruby /hoge/dispatch.fcgi
 2699 S hoge       Mar 12 00:00:00  0.0  18140      0 ruby ./script/process/spawner fcgi -p 9000 -r 10

とかでて、そのrailsで動いているfcgiの一覧がとれます。(上記は動いている場合の例)あとfcgiがいつ(再)起動したのかとかも出ます。

inspectorで何も起動していないことを確認したら、

 ./script/process/spawner fcgi -p 9000 -r 10

とかすると、port 9000からこの場合3つのfcgiプロセスが立ち上がります。fcgi というオプションは明示してあげないと、mongrelで動いてしまうようなので、明示してあげる必要があります。

あと-r 10というオプションもポイントで、これがあると、spawnerがデーモン化してくれて、10秒おきに、spawnerが立ち上げたプロセスを監視して、指定個数のfcgiプロセスが無いと、再起動してくれます。(むかしのspinnerの機能がspawnerにマージされたみたいです)これがあれば、fcgiプロセスが死んじゃっても勝手に生き返るので安心。

再起動は、repair -a restartでも良いかもしれないですが、なぜかうまくいかない(ちゃんとリロードされていない)場合があったりするみたいです。ちょっと乱暴ですが、

 ./script/process/repair -a kill

でも大丈夫です。上記のspawnerの設定が生きていれば、勝手にfcgiプロセスが起動され、結果としてちゃんとリロードされます。で、この最初のspawnerの正しい止め方が分からない...とりあえずinspectorで確認して、そのプロセスをkillで良いのかな?

redirect_toで301 Moved Permanently

| 21:50 |  redirect_toで301 Moved Permanently - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク -  redirect_toで301 Moved Permanently - takuma104のRuby/Rails日記  redirect_toで301 Moved Permanently - takuma104のRuby/Rails日記 のブックマークコメント

  headers["Status"] = "301 Moved Permanently"
  redirect_to "/"

とするサンプルが多くて困る。最近(2.0.x, 1.2.xも?)は、

  redirect_to "/", :status=>301

な方が正しいようです。(前者だと302のままになる)

トラックバック - http://rubyist.g.hatena.ne.jp/takuma104/20080317

2008-03-15

Hexな文字列を、バイナリに直す

| 06:01 | Hexな文字列を、バイナリに直す - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク - Hexな文字列を、バイナリに直す - takuma104のRuby/Rails日記 Hexな文字列を、バイナリに直す - takuma104のRuby/Rails日記 のブックマークコメント

たとえば、"0001AABB"とかいう任意の長さのhexな文字列を、packされたstring(この場合、0x00 0x01 0xaa 0xbbなバイナリ)にしたい場合。

def parse_hex_string_to_binstr(str)
  str.scan(/../).map {|e| e.hex}.pack('C*')
end

これ以上短くかけないかなあ?scan(/../)の..が反則臭い。

d:id:Hexaさんから、ご指摘いただきました。ありがとうございます。

Hexな文字列を、バイナリに直してみた - Hexaの日記

[ str ].pack("H*")

でOKですねorz. packの"H"というのは盲点でした。ほかにも知らないのあるかなあ。見てみようっと。

トラックバック - http://rubyist.g.hatena.ne.jp/takuma104/20080315

2008-03-12

MulticastなRTPを受信してRTPのヘッダ情報とか表示するサンプル

| 05:14 | MulticastなRTPを受信してRTPのヘッダ情報とか表示するサンプル - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク - MulticastなRTPを受信してRTPのヘッダ情報とか表示するサンプル - takuma104のRuby/Rails日記 MulticastなRTPを受信してRTPのヘッダ情報とか表示するサンプル - takuma104のRuby/Rails日記 のブックマークコメント

かなりニッチなサンプルですが貼っておきます。parse_rtpはちょっと適当すぎますが、だいたいこんなもんです...。

#!/usr/bin/env ruby -wKU
require 'socket'
require 'ipaddr'

def parse_rtp(pkt)
  {
    :sequence => pkt[2..3].unpack('n')[0],
    :timestamp => pkt[4..7].unpack('N')[0] / 90000.0,
    :payload_length => pkt.length - 16,
  }
end

def receive_rtp(mcacst_addr, mcast_port)
  sock = UDPSocket.new

  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1) #!!!
  sock.bind(Socket::INADDR_ANY, mcast_port.to_i)

  ip =  IPAddr.new(mcacst_addr).hton + IPAddr.new("0.0.0.0").hton
  sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, ip)

  loop do
    msg, info = sock.recvfrom(65536)
    rtpinfo = parse_rtp(msg)
    puts "time:%.3f seq:%d len:%d" % [rtpinfo[:timestamp],rtpinfo[:sequence],rtpinfo[:payload_length]]
  end
end

addr = ARGV.shift || "239.192.1.1" 
port = ARGV.shift || "5434"

receive_rtp(addr, port)

SO_REUSEADDRとSO_REUSEPORT

| 05:12 | SO_REUSEADDRとSO_REUSEPORT - takuma104のRuby/Rails日記 を含むブックマーク はてなブックマーク - SO_REUSEADDRとSO_REUSEPORT - takuma104のRuby/Rails日記 SO_REUSEADDRとSO_REUSEPORT - takuma104のRuby/Rails日記 のブックマークコメント

OSXで、QuickTime Broadcasterで配信したMulticastなストリームを、ローカルでRubyで受信しようとしたところ、bindでのErrno::EADDRINUSEで小一時間はまる。QT Broadcasterは、どうもマルチキャスト先のポート番号と同じものをbindしてしまうため、SO_REUSEADDRを指定してもだめっぽい。VLCとかでは、ローカルでちゃんと受信/再生できるので、どうやっているのかなあ、、とVLCのソースを読んでたら、SO_REUSEADDRなんか使っていなくて、SO_REUSEPORTを使っていた。Rubyで書くと

  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, 1) #!!!

な感じ。これにしたら解決した。

トラックバック - http://rubyist.g.hatena.ne.jp/takuma104/20080312
|