このエントリーをはてなブックマークに追加

PHP 5.4のトレイトで読み取り専用配列を実装してみる

traitを使って何か作ってみようと思い立ち、読み取り専用の配列を実装してみました。配列として扱いたい(例えばforeachで回したいとか)けど外側からの変更は受け付けたくないというシチュエーションで使えます。

使い方は以下の通り。

このエントリーをはてなブックマークに追加

Rails3にBackbone.jsを導入する

最近Backbone.jsを触っています。Backbone.jsをRailsで使うなら、パッケージで導入してしまうのが一番簡単だと思います。

Gemfileにrails-backboneを追加してbundle install

Backbone.jsを組み込みます。

app/assets/javascript/application.js は以下のように変更されます。

この下から2行目、ファイルでは app/assets/javascript/backbone/app.js.coffee が各モデル・ビュー・テンプレートなどを読み込むようになっています(ファイル名はRailsアプリと同じ名前になります)

ところで、rails-backboneのお作法は(scaffoldで生成されたコードをみる限り)モデル・ビュー・ルーターをディレクトリに分けて管理するようです。そしてその構造がそのまま名前空間になります。

例えばUserモデルなら app/assets/javascript/backbone/models/user.js.coffee にファイルを作り、下記のようなコードを書いていきます。

アプリ名が長いと若干タイプが面倒かなーって印象ですが、まぁ app/* と同じ感覚で作れるのでRails慣れしてる人は違和感なく使えそうです。

このエントリーをはてなブックマークに追加

OpenIndiana (Solaris) のDTraceでNode.jsをプロファイリングする

昨年辺りから開発を進めているNodeアプリが大変残念なパフォーマンス1 だったので、DTraceでプロファイリングしてボトルネックを探してみる作戦です。

DTraceはSolaris, FreeBSD, Mac OS X辺りに搭載されているのですが、Profiling Node.js を読むとMacでは動かない上に32bitじゃないと駄目、とだいぶ面倒な制約が付いています。ちなみにFreeBSDもNGです。

仕方が無いのでOpenSolarisの後継?にあたるOpenIndianaをVirtualBoxで動かす事にしました。

Node.jsを入れる

OpenIndiana自体のインストール方法は割愛します。普通にF2キーを連打していればインストール出来ると思います。。。、、、それにしてもSolaris触るの何年ぶりだろう

ひとまずインストール済みパッケージを最新版に上げて再起動しておきます。

GCCとmath.hをインストールします。

OpenSSLは入っているはずなんですが、configureした時に無いって怒られるので改めて入れておきます。

Nodeのソースを落としてきてインストールします。v0.8.2は謎のエラーを吐いてビルドに失敗するのでv0.6.20にしました。DTraceを有効にするためにconfigureに–with-dtraceオプションを付与してビルドします。

DTraceの結果をSVGに加工してくれるstackvisを入れておきます。

実際にプロファイリングしてみる

試しにフィボナッチ数列を計算する関数をひたすらぶん回すコードをトレースしてみます。良いコード無くてごめんなさい。

Nodeを実行します。これは一般ユーザーでも大丈夫です。

Nodeプロセスを動作させたまま、別ターミナルでDTraceをroot権限で実行します。60秒間 stacks.out に記録していきます。

stackvisを使ってstacks.outをSVG化します。

生成されたstacks.svgはこんな感じになりました。

しっかりとグラフになっています!縦がコールスタックの深さで横が処理時間の相対的な長さのはず?

ちなみにWebSocket-Nodeで実装したエコーサーバーをDTraceしてみた結果はこちら。

まとめ

処理に時間がかかっている関数がザックリと分かるのでボトルネック探しに重宝しそうです。

しかしMacで動かないのが惜しい。Solarisってだけでハードルが上がるような気がします。あと何故かNode v0.8.2がビルド出来ない2 のでそこら辺が今後の課題ですね。

(追記)

いま開発中のアプリをトレースしてみたらこんな感じになりました。

  1. C1Kが限界っていう。そのうちエントリーに起こしたい []
  2. GCCのバージョンかGYP周りもしれない []
このエントリーをはてなブックマークに追加

Rails3 + unicornからRabbitMQに接続するには

ruby-amqpはEventMachineに依存しているので、unicornからRabbitMQに接続する場合は少し手間がかかります。EventMachineで実装されているThinなどはそのまま動くようですが。。。

下記コードをconfig/unicorn.rbに追記します。

config/amqp.ymlを用意します。

開発環境(WebRickなど)からもRabbitMQに接続出来るようにします。

コントローラからパブリッシュする場合は下記のようにします。

このエントリーをはてなブックマークに追加

Ubuntu on EC2でRabbitMQクラスタを構築する手順

EC2 で動かしている Ubuntu Server 11.10 に RabbitMQ クラスタを構築したのでその時の手順をブログに残しておきます。ホスト名の設定で若干手こずりました…。

RabbitMQをインストール

オフィシャルで配布されているパッケージを使うのがお手軽です。

下記コマンドでエラーが出なければ、正常にRabbitMQが起動しています。

RabbitMQの初期設定

RabbitMQはデフォルトでノード名がインストールしたサーバのhostname -sになっています。このノード名を変更するには /etc/rabbitmq/rabbitmq-env.conf でNODENAMEを指定すれば良いのですが、何故かNODENAMEにはFQDNが使えません。

このままだと、別のRabbitMQサーバをクラスタに追加する時にノード名の不一致が起き、正常に追加出来ないという罠が待っています。まぁ、/etc/hosts に全サーバのホスト名を書いていけば問題無いのですが、EC2だとインスタンスの再起動でIPとホスト名が変わったりするので、あまり現実的ではありませんね。極力ドメイン名で処理したいところです。

そこで /etc/rabbitmq/rabbitmq-env.conf でFQDNが使えるようにRabbitMQ本体に若干手を加えます。といってもオプションを書き換えるだけです。

書き換える前にサーバを停止しておきます。

/usr/lib/rabbitmq/lib/rabbitmq_server-2.8.1/sbin/rabbitmq-server

/usr/lib/rabbitmq/lib/rabbitmq_server-2.8.1/sbin/rabbitmqctl

/etc/rabbitmq/rabbitmq-env.conf は下記のようにします。

これでRabbitMQを再度起動させてエラーが出なければ設定完了です。

クラスタ化する

rabbit1.foo.bar.internal と rabbit2.foobar.internal に対して、上記手順に則ってRabbitMQをインストールしたと仮定します。

rabbit1を初期化する

rabbit1上でrabbit2をクラスタに参加させる

クラスタに追加されているか確認する

追加されてますね。rabbit2からも確認してみます。

これでrabbit1, rabbit2どちらに接続してもキューをpublish, subscribeすることが出来ます。クラスタ化自体はそこまで難しくないと思います。

詳しくはオフィシャルドキュメントに全部書いてあるので、そちらを参照してください。