2013/07/30

[three.js] PerspectiveCameraの属性をイジる。

Three.jsには、Cameraがあります。
そこから派生した2つのカメラオブジェクト、
それぞれ、「正射影カメラ」、「透視投影カメラ」と呼ばれているようです。
今回は、後者のPerspectiveCamera、すなわち、「透視投影カメラ」のパラメータを弄ってみました。

Perspective Camera

人間の目で見えるように描画する。
つまり、同じ大きさの物体であれば、カメラから近いものほど大きく、遠いものほど小さく見える。

Perspective Cameraのパラメータには、

fov
field of view. y軸(縦)方向の画角(視野角)。
コレが大きいと、いわゆる広角になり、小さいと望遠になる。
aspect ratio
描画空間(xy面)のアスペクト比、つまり横/縦。
near
描画空間(手前側の面)の視点からの距離
far
描画空間(奥側側の面)の視点からの距離

があります。
これらの組み合わせが、描画する空間にどう作用するのかを確認するため、右のようなパラメータをイジる画面を表示するコードを書いてみました。

結果は、 let's play with cameras!にあります。
WebGLに対応したブラウザで見ていただければ、と思います。

2013/07/19

[three.js] Three.jsを使った最初のサンプル

一度は断念した Three.js を再び触り始めました。
上記サイトの documentation にある

というページにある超簡単なコードを書いてみました。結果は、 で確認できます。
WebGLに対応したブラウザで見ていただければ、と思います。

2013/07/16

[emacs] LESSのためのless-modeを導入!

など、CSSメタ言語(というのか)を利用する機会が増えています。
twitter-bootstrapは、LESSで書かれているし、 ExpressではLESSやStylusが使えます。
ということで、僕のemacsにもLESSを扱いやすくするlispを追加してみました。
ちなみに、SassとStylusに関しては、
[emacs] scss-mode
[emacs] jade-mode, stylus-mode
を見ていただければ、と思います。

LESSのlispは、

があります。 前者は、css-modeに依存しており、僕のemacsでは適切なcss-modeがインストールできず使えなかったため、 (次のような警告が出ました。 Wrong css-mode.el: please use the version by Stefan Monnier, bundled with Emacs >= 23.) 後者をインストールしました。

less-modeをダウンロードして、~/.emacsに、

(add-to-list 'load-path "/path/to/less-mode.el")
(require 'less-mode)
とすることで、*.lessのメジャーモードがLessになりました。 インデントも問題無さそうです。

2013/07/13

[fluentd] nginxのアクセスログをfluentdからmongodbに!

前々から気になっていたfluentdをようやく試しました。 fluentdは、rubyで書かれたオープンソースのログ収集デーモンです。

今回試したのは、nginxのアクセスログ(ltsv)をfluentdを使ってmongodbに集める、ということです。 (ここでは、mongodbのインストール方法などは書きません。)

fluentdのインストール

fluentdにはyumパッケージ、debianパッケージ、ruby gemなどいくつかあって、 僕はgemをインストールしました。

 $ ruby --version
 ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
 $ gem --version
 2.0.3
 $ sudo gem install fluentd

fluentdの設定

ディレクトリ /etc/fluent を作って、初期化コマンドを実行します。

 $ sudo mkdir /etc/fluent
 $ sudo fluentd --setup /etc/fluent

ltsv用プラグイン(input)

nginxのアクセスログは、ltsv形式で出力しています。
(nginxのアクセスログをltsv形式にする方法は、[nginx]アクセスログフォーマットにLTSVを適用する。にあります。)
stanaka/fluent-plugin-tail-labeled-tsvを使用させて頂いて、簡単にltsvなアクセスログをfluentdのinputとして扱うことができました。
in_tail_labeled_tsv.rbというRubyファイルを/etc/fluent/pluginsに配置します。

mongodb用プラグイン(output)

fluentdの出力を、mongodbへ格納するためのプラグインをインストールします。
fluent/fluent-plugin-mongoです。

 $ fluent-gem install fluent-plugin-mongo

fluent.conf

inputとoutputの定義をfluent.conf(/etc/fluent/fluent.conf)に書きます。
今回は、nginxとfluentd、mongodbを同じホスト上で動かしています。
そのため、↓のようなファイルになりました。

/etc/fluent/fluent.conf


  <source>
    type tail_labeled_tsv
    path /usr/local/nginx/logs/access.log
    tag nginx.access
    pos_file /var/log/fluent/access.log.pos
  </source>

  <match nginx.access>
    type       mongo
    database   fluent
    collection nginx
  </match>

fluentdの起動

fluentdのupstart用スクリプトを書いて起動します。

/etc/fluentd.conf


description "fluentd upstart script"

start on (local-filesystem and net-device-up)
stop  on shutdown

respawn
respawn limit 5 60

script
  exec sudo -u somebody /usr/local/rbenv/shims/fluentd -c /etc/fluent/fluent.conf
end script

 $ sudo start fluentd

これでmongodbにアクセスログがmongodbに蓄積されました。

参考にさせて頂いたサイト。

2013/07/10

[nginx]アクセスログフォーマットにLTSVを適用する。

以前、nginxのアクセスログフォーマットについて書きました。 ログ収集のためのツールであるfluentdが広まっており、サーバーログなどの扱い方も変わってきているように思います。

そういった中で、LTSVという形式でログを出力させることで、ログをアプリケーションで扱いやすくするという方法が広まっているようです。
LTSVに関する説明として、LTSV FAQ - LTSV って何? どういうところが良いの?がとても参考になります。

LTSV形式でnginxのログを出力させる場合、nginxの設定ファイル(一般的には、nginx.conf)に次のように記述します。
(http ディレクティブに書きました。)


    log_format ltsv "time:$time_local"
                    "\thost:$remote_addr"
                    "\tforwardedfor:$http_x_forwarded_for"
                    "\tuser:$remote_user"
                    "\treq:$request"
                    "\tmethod:$request_method"
                    "\turi:$request_uri"
                    "\tstatus:$status"
                    "\tsize:$body_bytes_sent"
                    "\treferer:$http_referer"
                    "\tua:$http_user_agent"
                    "\treqtime:$request_time"
                    "\tcache:$upstream_http_x_cache"
                    "\truntime:$upstream_http_x_runtime"
                    "\tapptime:$upstream_response_time"
                    "\tvhost:$host";



各項目のラベルは、上述のLTSVのサイトで推奨されているラベルを使っています。
そして、このログフォーマットを適用したいserverディレクティブ内で、
  server {
    listen 80;
    # 略
    access_log logs/access.log ltsv;
    # 略
  }
のように指定し、nginxを再起動することで、LTSV形式のログが出力されます。

2013/07/03

[nginx] worker_processesとworker_cpu_affinityについて

nginxにはworker_processesというパラメータがあります。 NginxのWikiCoreモジュールのページには、次のような説明があります。


A worker process is a single-threaded process.
If Nginx is doing CPU-intensive work such as SSL or gzipping and you have 2 or more CPUs/cores, then you may set worker_processes to be equal to the number of CPUs or cores.
If you are serving a lot of static files and the total size of the files is bigger than the available memory, then you may increase worker_processes to fully utilize disk bandwidth.
Your OS may schedule all workers on single CPU/core this can be avoided using worker_cpu_affinity.
Nginx has the ability to use more than one worker process for several reasons:

  1. to use SMP
  2. to decrease latency when workers blockend on disk I/O
  3. to limit number of connections per process when select()/poll() is used
The worker_processes and worker_connections from the event sections allows you to calculate maxclients value:
max_clients = worker_processes * worker_connections


何が書いてあるかといえば、

worker prcessは、シングルスレッドなプロセスだよ。
nginxがSSLやgzip圧縮みたいにCPUを専有するような処理をするって場合に、2つ以上のCPUコアがあるなら、worker_processesにはCPUコア数と同じを設定したらいいよ。
大量の静的ファイルをホスティングしていて、ファイルサイズが空きメモリサイズよりも大きくなっちゃうような場合も、worker_processesの値を増やして、ディスク帯域を十分に使えるようにしたらいいよ。
君のOSだと全部のworker_processを1つのCPUコアに割りつけてしまうかもしれないけど、そんな時はworker_cpu_affinityを設定すれば回避できるよ。
nginxは、

  1. SMPを使うため。
  2. ディスクI/Oによる応答遅延を減らすため。
  3. select()/poll()環境下でプロセスごとの接続数を制限するため。
といったいくつかの理由から複数のworker processが使えるようになっているよ。

worker_processesとeventセクションに設定するworker_connectionsから、最大クライアント数を計算できるよ。つまり、
最大クライアント数 = worker_processes * worker_connections
になるよ。

といった内容でしょうか。
つまり、worker_processes を CPUコア数にして、worker_cpu_affinityをきちんと設定しなさいよ、ということで、
僕のサーバは2コアなので、

  worker_processes 2;
  worker_cpu_affinity 0101 1010;
を設定しました。

2013/07/01

[node] nvmをシステムワイドに適用する。

rbenvをシステムワイドに適用する方法について、 rbenv + ruby-build を system-wide にインストールするを参考にさせていただき、無事に適用することができました。

まったく同じ要領で、nvmをシステムワイドに適用させてみました。

nvmのインストール
$ cd /usr/local
$ sudo git clone git://github.com/creationix/nvm.git nvm
$ sudo chown -R root:[グループ名] nvm
$ sudo chmod -R g+rwxX nvm
グループ名は、nvmを使用させるグループ名を指定します。
/etc/profile.d/nvm.sh
source /usr/local/nvm/nvm.sh
ユーザがログインすると、自動的にnvmが利用可能になります。