autotestのmapping
なぜかmodelファイルの変更をしても、autotestで再実行されない。
とりあえず、autotestのmappingを下のようにしたら実行されるようになった。
app以下のファイルとspecファイルのmapping。
.autotest
Autotest.add_hook(:initialize) {|at|
at.add_mapping(/app\/([\/\w_]+)\.rb$/) do |f, matched|
"spec/#{matched[1]}_spec.rb"
end
}
デフォのmappingどうなってんだろう・・。
MacはBSDベース
MacはLinuxベースじゃない。BSDベース。そのおかげではまった。
historyの出力から、行番号部分だけとりたかった。
これを、
こうしたかった。
121 ls -al
122 pwd
だけ。
ls -al
pwd
で、sedで-r(拡張表現オプション)つけて実行。
したら、
history | sed -r "s/^ +[0-9]+ //"
そんなオプションないっておこられた・・。
sed: illegal option -- r
原因は、MacはBSD UNixベース。
sedもBSDベースのもの。
man sedすると
BSDベースだと、拡張表現は-rじゃなくて。-Eみたい。
-E Interpret regular expressions as extended (modern) regular expressions rather than
grepは-Eなのになー。
Mac Lionにclispをインストール
「--use-gcc」つけろって怒られる。
brew install clisp
Warning: Building with LLVM, but this formula is reported to not work with
…
If it doesn't work you can: brew install --use-gcc
…
Error: Failed executing: ulimit -s 16384 && make
gccを使うっよって宣言するオプション?今まで指定したこと無いんだけど。
Macに入ってるgccがLLVMのものだから、そのあたりの絡みだろうか。
とりあえずつけて再実行。
無事はいった。
brew install --use-gcc clisp
==> Summary
/usr/local/Cellar/clisp/2.49: 62 files, 16M, built in 6.8 minutes
unicornのpreload_app
unicornの設定「preload_app」について。
ざっくりと、「workerのアプリケーションの先読み」の設定らしい。
このサイトに詳しい説明があったので訳してみた。英語は苦手なので怪しいがなんとなく雰囲気は合ってる気がする。
http://unicorn.bogomips.org/Unicorn/Configurator.html#method-i-preload_app
Enabling this preloads an application before forking worker processes.
workerをforkする前のアプリケーションの先読みを有効にします。
This allows memory savings when using a copy-on-write-friendly GC
これは、copy-on-write-friendlyに相性の良い環境では、メモリを節約できます。
but can cause bad things to happen when resources like sockets are opened at load time by the master process and shared by multiple children.
しかし、socketのようなリソースはmasterによってロード時に開いて複数のchildren(worker)で共有されているときに悪いことが起こる可能性があります。
People enabling this are highly encouraged to look at the before_fork/after_fork hooks to properly close/reopen sockets. Files opened for logging do not have to be reopened as (unbuffered-in-userspace) files opened with the File::APPEND flag are written to atomically on UNIX.
これを有効にするなら、before_forkもしくはafter_forkでsocketをの適切を開き直すことをおすすめします。
でもログファイルはUNIXによってアトミックに書き込まれるので問題なし。
In addition to reloading the unicorn-specific config settings, SIGHUP will reload application code in the working directory/symlink when workers are gracefully restarted when preload_app=false (the default).
preload_app=falseの時にHUPでunicornの再起動が正常に行われた場合、設定とアプリケーションをリロードし、リロードされたものへのシンボリックリンクが切り替わります。
■preload_appの設定によるSIGHUPでの再起動時の挙動の違い
preload_appの設定によって、SIGHUP(workerの処理の完了をもって再起動)を送ったときに挙動が違ってくる。
true
- unicornの設定:再読み込みされる
- アプリのリロード:されない。アプリはマスタでロード済みのものを使う。アプリをリロードしたければ、SIGUSR2を送って新マスタ&workerを立ち上げる方法をとる。
- ダウンタイム:発生しない(マスタのアプリをそのまま使うので、workerがあがった時から処理が可能)
false
- unicornの設定:再読み込みされる
- アプリのリロード:される
- ダウンタイム:発生する。(workerがそれぞれアプリをロードするので、ロード完了まで処理できない)
preload_appをfalseにする時って?
あえてpreload_appをfalseにする時ってなんだろう。
preload_appがtrueの時のデメリットは、
・SIGUSR2での再起動になり、手順的に多少複雑(古いmasterを後で落とすなど)
→でもcapistrano等で自動化可能な範囲。
・SIGUSRで新マスタ&workerを立ち上げる場合、一時的にマスタ&workerのセットが2セットできるからメモリ的に一瞬大きくなる事もある
→preload_appがfalseの場合はworker数分のアプリをメモリにロードするわけだし、そっちの方が大きくなるか。
何かの情報で、SIGUSR2が不安定という事を聞いたことはあるけど、そのへんの事情なのかな。
情報とつっこみ欲しい。
Mac Lionにnginx+php-fpmをいれ、Shindigを動かす
事前にいるもの
・Homebrew
・wget(Homebrewでbrew install wgetでいける)
nginx、php-fpmインストール
nginx
brew install nginx
php-fpm
php-fpmを有効にしたphpをインストールする必要がある。
brewで入るが、デフォではbrew対象外(/usr/local/Library/Formula/にスクリプトなし)なのでスクリプト作る。
インストール。fpm有効にするオプションを忘れずに。
cd /usr/local/Library/Formula/
curl -O https://raw.github.com/ampt/homebrew/php/Library/Formula/php.rb
mv php.rb `brew --prefix`/Library/Formula
このphp-fpm版のphpの前にphpが入ってたらパス通ってるのなら置き換える。
brew install php --with-fpm
sudo mv /usr/bin/php /usr/bin/php.old
sudo ln -s /usr/local/Cellar/php/5.3.10/bin/php /usr/bin/php
ls -al /usr/bin/php
> lrwxr-xr-x 1 root wheel 36 2 25 22:22 /usr/bin/php -> /usr/local/Cellar/php/5.3.10/bin/php
shindigを動かす
apache.orgからsindigを拾う
sudo mkdir -p /var/project/shindig
cd /var/project/shindig
wget http://www.apache.org/dist/shindig/2.0.0/shindig-2.0.0-php.tar.gz .
shindigは.htaccessを使っているが、nginxは.htaccessなんて読まないのでnginx.confで同じ挙動になるようにしてやる
shindingの.htaccess
# A
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php [L]
# B
php_flag always_populate_raw_post_data On
php_flag magic_quotes_gpc Off
A.リクエストされたものが、ファイルでもディレクトリでもない(該当なし)ならindex.phpに飛ばしているらしい。
B.phpのalways_populate_raw_post_dataをOn、magic_quotes_gpcをOffに。
という二つの設定がある。
nginx.confの設定
下記の内容を追記。
vi /usr/local/etc/nginx/nginx.conf
server {
server_name localhost;
listen 8080;
root /var/project/shindig;
access_log /var/project/shindig/logs/access.log;
index index.php;
if (!-e $request_filename){
rewrite ^ /index.php;
}
location / {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
include fastcgi_params;
}
}
php.iniの設定
always_populate_raw_post_dataをOnになっているか確認。
always_populate_raw_post_dataはONに、magic_quotes_gpcはOffになっている必要がある。
php-fpm -i| grep always_populate_raw_post_data
php-fpm -i| grep magic_quotes_gpc
そうでないと、shindigを動かしたときに
Your environment does not have always_populate_raw_post_data enabled which will interfere with Shindig. Please set 'always_populate_raw_post_data' to 'On' in php.ini
とか怒られる。
設定変更。ちゃんとphp-fpmを有効にしたphpの設定を変える(元からPHP入ってて、php.ini二つあるとか)
php-fpm -i | grep php.ini
vi /usr/local/Cellar/php/5.3.10/etc/php.ini
php_flag always_populate_raw_post_data On
php_flag magic_quotes_gpc Off
起動、確認
アクセスしてみる
http://localhost:8080/gadgets/ifr?url=http://www.labpixies.com/campaigns/todo/todo.xml
にアクセスして、ガジェットパーツが読み込まれたらOK(TODOリスト)
さくらVPSで、node0.5.3〜npmのinstallではまった
ローカルのnode.js環境をさくらVPSに移した。
いくつかはまる部分があったので備考録。
まずはnode.jsのソースをもってきてconfigure。
落ちた・・。pythonがエラーってるっぽい。
cd /usr/local/src/
wget http://nodejs.org/dist/v0.5.3/node-v0.5.3.tar.gz
tar xzvf node-v0.5.3.tar.gz
cd node-v0.5.3
./configure
ググってみると、英語のページでPythonが古いんだみたいな事を言われていた。
/usr/local/src/node-v0.5.3/wscript: error: Traceback (most recent call last):
File "/usr/local/src/node-v0.5.3/tools/wafadmin/Utils.py", line 274, in load_module
exec(compile(code, file_path, 'exec'), module.__dict__)
File "/usr/local/src/node-v0.5.3/wscript", line 222
"-pre" if node_is_release == "0" else ""
^
SyntaxError: invalid syntax
最新(2.7.2)をいれる。
Pythonはすんなり入った。
wget http://www.python.org/ftp/python/2.7.2/Python-2.7.2.tgz
tar xzvf Python-2.7.2.tgz
cd Python-2.7.2
./configure
make
make install
では、再度node.jsのインストール
configure通過。
./configure
次はmakeがこけた。
make
[ 5/36] libv8.a: deps/v8/SConstruct -> build/default/libv8.a
/usr/local/bin/python "/usr/local/src/node-v0.5.3/tools/scons/scons.py" -j 1 -C "/usr/local/src/node-v0.5.3/build/default/" -Y "/usr/local/src/node-v0.5.3/deps/v8" visibility=default mode=release arch=x64 toolchain=gcc library=static snapshot=on
scons: Reading SConscript files ...
ImportError: No module named bz2:
File "/usr/local/src/node-v0.5.3/deps/v8/SConstruct", line 37:
import js2c, utils
File "/usr/local/src/node-v0.5.3/deps/v8/tools/js2c.py", line 36:
import bz2
Waf: Leaving directory `/usr/local/src/node-v0.5.3/build'
Build failed: -> task failed (err #2):
{task: libv8.a SConstruct -> libv8.a}
make: *** [program] Error 1
bz2がない?またググってみるとbzip2-develが必要らしい。しかもそれはPythonインストール時に無いといけなかったららしい。。
しかもこれはPythonのインストール時に必要だったらしい。
yum install bzip2-devel
↑のPythonインストール(./configure〜make install)をもう一度。。
これで、nodeのmake、make installも通った。
'install' finished successfully (0.137s)
また、その後npmのinstallでもはまった。
下記のエラー出力。
npm install socket.io
これはtarが古いようだ。(ver 1.15)
npm ERR! tar "-mvxpf" "-" "-o" "-C" "/tmp/npm-1313209389660/1313209389660-0.5830379514954984/contents/___package.npm" tar: Ignoring unknown extended header keyword `LIBARCHIVE.creationtime'
npm ERR! tar "-mvxpf" "-" "-o" "-C" "/tmp/npm-1313209389660/1313209389660-0.5830379514954984/contents/___package.npm" tar: Ignoring unknown extended header keyword `SCHILY.dev'
npm ERR! tar "-mvxpf" "-" "-o" "-C" "/tmp/npm-1313209389660/1313209389660-0.5830379514954984/contents/___package.npm" tar: Ignoring unknown extended header keyword `SCHILY.ino'
tarをバージョンアップ。
この際、FORCE_UNSAFE_CONFIGURE(安全でないconfigureを強制。。)を1にしないとcofigureが通らなかった。
wget http://files1.directadmin.com/services/all/tar-1.26.tar.gz
tar xzvf tar-1.26.tar.gz
cd tar-1.26
./configure && make && make install
FORCE_UNSAFE_CONFIGURE=1
export FORCE_UNSAFE_CONFIGURE
./configure && make && make install
入った。
これでやっと、npm installも通る。
やっとうまくいった。長かった。。だいたいソースからのインストール系ってすんなりいった記憶が少ない
npm install socket.io
socket.io@0.7.9 ../node_modules/socket.io
├── policyfile@0.0.4
├── redis@0.6.6
└── socket.io-client@0.7.9
2011/07/22 Node.jsの勉強会 「『Node.js』とは何か。そして、その先へ。」 に行ってきました
「『Node.js』とは何か。そして、その先へ。」( http://www.jus.or.jp/benkyokai/11-07.html )
(日本Unixユーザ会の勉強会)のレポートです。
・日時
2011/07/22 18:30〜20:30
・講師
bad_at_mathさん、jackさん
資料が配布され、それに従った説明を聞く+サンプルを見る形でした。
下記は配布された資料に、説明内容+aを追記したものです内容です。
■Node.js
まずはNode.jsとは。
・サーバサイドJavaScriptプラットフォーム
・2009年、Ryan Dath作
■背景
そしてそのNode.jsはなぜ(何のために)誕生したか。
・C10K問題
-同時接続数が思い切り増えていくと、サーバがパンクしてしまう
-従来型の1スレッド1コネクションで同期I/Oというモデルにて表面化
■マルチスレッドの問題
マルチスレッドには下記の問題がある。また、腕の良い開発者でないと実装は難しい(資源の共有による、デッドロックの問題など)
○メモリ効率
・1スレッドあたり2MB以上であり、スレッドの処理内容によっては10MB以上の場合も
(2MBとか10MBとかの数字はどこから出たものなんだっけ。この時間、一瞬席周りがばたついて聞き逃したっぽい。。)
○ブロッキングI/O
・読み取り、書き込みが完了するまでひたすら待ち続ける処理
・ディスクやネットワークからの読み取り、書き込み性能はメモリにくらべてかなり遅いので問題になる
このあたりはLAMPな人がぶちあたりがちな問題ですね。
○I/Oコスト
CPUのL1キャッシュ : 3サイクル
CPUのL1キャッシュ : 14サイクル
RAM : 250サイクル
ディスク : 41,000,000サイクル
ネットワーク : 240,000,000サイクル
○解決策
・I/O多重化
-select()やpoll()など
・イベント駆動モデル
・ノンブロッキングI/O
ちなみに、ノンブロッキングI/Oと非同期I/Oって違うものなんですね。混同してた・・。ちゃんと勉強しよう。
- http://togetter.com/li/136290
- http://d.hatena.ne.jp/forest1040/20110407/1302150936
○select(),poll()
一度に多数のFD(ファイルディスクリプタ)の状態を確認可能
○epoll
select()やpoll()・・・FDをstateはプログラム側で検査する必要がある
epollの・・準備のできたFDの集合が返される
■性能比
liveventのベンチ比較。epoll優秀
■イベント駆動モデル
・シングルスレッド+ループ
・発生イベントの無いようにより処理分岐
・計量
・古くからGUIライブラリなどでも利用
・シグナルもその1つと言える(?)
■ノンブロッキングI/O
・読み取り、書き込み処理を行うとその成功、終了を待たずに呼び元に戻る
・ブロックしないので、他の処理を続けることが可能
■HTTPサーバ実装例
・enginex
・lighttpd
■ライブラリ実装例
・libevent
・libev
■libev
・Marc Lehman(GCCのPen最適化)
・livenentよりも高性能(ver1.x比)
■Ryan Dahl
・Edd(ruby製webサーバ)
・libebb(httpサーバライブラリ)
■オリジナル実装へ
・より高速へ
・よりスケーラブルに
■特徴
・シングルスレッド
・非同期
・ノンブロッキングI/O
■アーキテクチャ
Node.jsは、
v8、libev、libeioで構成されている。
■JavaScript
・スレッドライブラリなし
・非同期プログラミング
・近年目覚しく高速化
GoogleMapなどのAjaxやリッチなクライアント側実装に耐えうる各ブラウザベンダがしのぎをけずって高速化に取り組んだ
・開発者人口の多さ
■V8
・JavaScriptを大幅にスピードアップ
・プロパティ・メソッドアクセス高速化
・高速かつオーバーヘッドの少ないJIT
・効率の良いGC
■libeio
・ファイルI/Oを受け持つ
・内部ではスレッドプールを利用
■Node.jsの利点
・高効率
・賞メモリ
・HTTPがファーストクラス
・多数の接続に対応
・クライアントからサーバまで一貫(JS)
→どっちもJavaScriptで実装
・Webアプリ経験者の敷居の低さ
→これもJavaScriptで実装していることによる
・利用可能なライブラリはnon-blocking
・各コンポーネントの高速化の恩恵にあずかれる
・V8、libev
■コード例
省略
(よくある、HTTPサーバをたててHello World出力)
■Server-Side JS
Node.jsだけでなく、下記のようなサーバサイドJSライブラリもある
・Ringo.js
・Pinture
・Joyent Smart
・Jaxer
■既存のものとの違い
・目的やバックグラウンドが違う
・Node.jsは高速性、また多くの接続をハンドリングできることを目標に作られている
・JSを採用したのは上記の条件を満たす部品としてマッチしたため。
■Node.jsの得意分野
・同時接続数が多く、計量な処理のもの
・リアルタイムアプリケーション
■Node.jsの欠点
・シングルスレッドであること
・マルチコアを生かし切れない
(一応、現時点でNode Clusterやプロセスを複数たちあげる方法も無くは無い)
・CPUインテンシブな処理は構造上苦手(ループを高速にまわす必要がある)
・V7noヒープが現状、64bitで1.9GB(32bitで1GB)
・モジュールは非常に多く存在するが完成度があと一歩のものが多い
■Node.jsの流儀
Every I/O uses Non-Blocking I/O
・他の言語では同期I/Oを利用するライブラリを使ってしまい、処理速度が落ちる可能性があるがNodeではそれがない
■必要とされるスキル
・非同期プログラミングスキル
・サーバサイドではそれほど一般的ではない
■Node.jsの現状
・Windoesサポートに向けて、Microsoftが協力を表明(今ではバイナリ配布も)
・メジャープラットフォーム全てにおいて動作