はちゅにっき

こっちのブログはまったり更新

新年早々 nginx_tcp_proxy_module を組み込んだ deb パッケージを作ってみる

昨年は本当に細々と更新してきましたが、今年も細々と更新していきたいと思います。本年もよろしくお願いいたします。
ということで、さっそく本題。

新年早々 WebSocket で遊んでみたいなぁと思ったので、nginx で WebSocket を Proxy する場合に有名という、nginx_tcp_proxy_module を組み込んで Debian/Wheezy にインストールすることに。
nginx のソースコード持ってきてコンパイルすればいいんだけど、dpkg でパッケージ管理をしたいこともあり deb パッケージを作成することにしました。

nginx_tcp_proxy_module をダウンロード

以下の配布ページよりダウンロード

nginx_tcp_proxy_module
http://yaoweibin.github.com/nginx_tcp_proxy_module/

せずに、なんとなく上記ページにも記載のある github からもってきました。

yaoweibin / nginx_tcp_proxy_module
https://github.com/yaoweibin/nginx_tcp_proxy_module
# git clone https://github.com/yaoweibin/nginx_tcp_proxy_module.git
# rm -rf nginx_tcp_proxy_module/.git*

普通にダウンロードすればいい気がしますね。

nginx のソースコードをダウンロードする

aptitude で source を入手する方法が分からなかったので *1 昔ながらの apt-get を使ってソースコードを入手しました。

# apt-get source nginx

Build ルールを編集する

展開された nginx のソースコードディレクトリに、configure する際のルールが記載されたファイルがあるため、これを編集して nginx_tcp_proxy_module が組み込まれるようにします。

--- rules       2013-01-01 17:51:47.218259979 +0900
+++ nginx-1.2.1/debian/rules    2013-01-01 18:04:33.386259773 +0900
@@ -88,6 +88,7 @@
            --add-module=$(MODULESDIR)/nginx-echo \
            --add-module=$(MODULESDIR)/nginx-upstream-fair \
            --add-module=$(MODULESDIR)/nginx-dav-ext-module \
+           --add-module=$(MODULESDIR)/nginx_tcp_proxy_module \
             $(CONFIGURE_OPTS) >$@
        touch $@
 
@@ -119,6 +120,7 @@
            --without-http_userid_module \
            --without-http_uwsgi_module \
            --add-module=$(MODULESDIR)/nginx-echo \
+           --add-module=$(MODULESDIR)/nginx_tcp_proxy_module \
             $(CONFIGURE_OPTS) >$@
        touch $@
 
@@ -168,6 +170,7 @@
            --add-module=$(MODULESDIR)/nginx-upload-progress \
            --add-module=$(MODULESDIR)/nginx-upstream-fair \
            --add-module=$(MODULESDIR)/nginx-dav-ext-module \
+           --add-module=$(MODULESDIR)/nginx_tcp_proxy_module \
             $(CONFIGURE_OPTS) >$@
        touch $@
 
@@ -196,6 +199,7 @@
            --add-module=$(MODULESDIR)/nginx-upstream-fair \
            --add-module=$(MODULESDIR)/nginx-cache-purge \
            --add-module=$(MODULESDIR)/naxsi/naxsi_src \
+           --add-module=$(MODULESDIR)/nginx_tcp_proxy_module \
            $(CONFIGURE_OPTS) >$@
        touch $@
 

nginx_tcp_proxy_module のソースコードを deb パッケージに配置する

nginx のソースコードのディレクトリに、nginx_tcp_proxy_module をコピーします。

# cp -R nginx_tcp_proxy_module/ nginx-1.2.1/debian/modules/ 

patch を適用する

nginx_tcp_proxy_module を有効にするにはソースコードに patch をあてる必要があるため、Build 時に適用されるよう編集します。
patch 適用には quilt を利用しましたが、patch コマンドで適用するだけでいい気がします。

# cd nginx-1.2.1
# quilt new tcp.patch
# quilt add src/core/ngx_log.c
# quilt add src/core/ngx_log.h
# quilt add src/event/ngx_event_connect.h
# patch -p1 < debian/modules/nginx_tcp_proxy_module/tcp.patch
# quilt refresh

パッケージを再生成する

dpkg-builder でパッケージを再生成します。

# cd nginx-1.2.1
# dpkg-builder -b

完成

Build が完了すると、deb パッケージがたくさん生成されるので、あとは必要に応じて deb パッケージを dpkg を使ってインストールすれば OK ですね。
ということで、次は実際に作成した nginx のパッケージで WebSocket アプリを Proxy してみたいと思います。

ひとまず無事インストール完了ということで、わーい。

*1:知ってる方教えてください。

Net::SSLeay がインストールできないときは

OS って 1回セットアップすると、あまり触らなくなるから、すぐ忘れちゃうんだよね。。。

cpanm などで Net::SSLeay をインストールしようとして "openssl/err.h" がないよ!と怒られたとき*1

# aptitude install libssl-dev

*1:SSLeay.xs:153:25: fatal error: openssl/err.h: そのようなファイルやディレクトリはありません

GrowthForecast つかってみた

なんかすごくグラフを作成したい要件があったので、id:kazeburo さんが開発している GrowthForecast をつかってみました。

GrowthForecast
https://github.com/kazeburo/GrowthForecast

いつも通りメモだよん。

GrowthForecast を Clone する

App::gh *1 をインストールしてあるので、gh コマンドを使って

$ gh clone kazeburo/GrowthForecast

でおわり。便利ですね!

依存モジュールをインストール

cpanm さえ入っていればこれもいつものように

$ cpanm -l extlib --installdeps .

でおわり。これまた便利!

Alien::RRDtool をインストール

依存モジュールインストールしたし、もうカンペキ!と思ったけれど、実はグラフ描画ツールである RRDtool は一緒にインストールされない模様。
ということで、RRDtool も導入します。
今までは yum / aptitude などを経由してインストールしたり、自分でコンパイルしたりと大変でしたが、今は Alien::RRDtool があるので、こちらを cpanm を使っていれます。
依存するライブラリの問題でインストールできない場合もありますが、その場合は yum / aptitude などで依存ライブラリを別途インストールする必要があります。

$ cpanm -l extlib Alien::RRDtool

起動してみる

GrowthForecast には growthforecast.pl という起動スクリプトがついてくるので、これを実行してアプリケーションを起動します。

$ perl growthforecast.pl --host 0.0.0.0

これだけで準備完了。カンタン!

curl でグラフをかく

特定の URL を叩くだけでグラフを生成してくれるので、ためにし curl でグラフを書いてみます。

$ curl -F number=2.5 -F mode=gauge http://mydomain.com:5005/api/service/section/name

これだけでカンタンにグラフが。。。
あれ?なんか "number is not null" とか言うエラーが出ちゃったよ?
NULL 値なんて渡してないのにどうして!?
と思い、ソースコードを見てみると、どうやら number は整数値じゃないとダメみたい。

整数値以外のグラフも描画できるように

今回どうしても、整数値以外のグラフが書きたかったので、無理矢理整数値以外でも描画できるようにしてみました。
変更した差分は以下の通り。

diff --git a/lib/GrowthForecast/Data.pm b/lib/GrowthForecast/Data.pm
index f334efa..c88c24a 100644
--- a/lib/GrowthForecast/Data.pm
+++ b/lib/GrowthForecast/Data.pm
@@ -27,7 +27,7 @@ CREATE TABLE IF NOT EXISTS graphs (
     service_name VARCHAR(255) NOT NULL,
     section_name VARCHAR(255) NOT NULL,
     graph_name   VARCHAR(255) NOT NULL,
-    number       INT NOT NULL DEFAULT 0,
+    number       REAL NOT NULL DEFAULT 0,
     mode         VARCHAR(255) NOT NULL DEFAULT 'gauge',
     description  VARCHAR(255) NOT NULL DEFAULT '',
     sort         UNSIGNED INT NOT NULL DEFAULT 0,
@@ -60,7 +60,7 @@ EOF
     $dbh->do(<<EOF);
 CREATE TABLE IF NOT EXISTS prev_graphs (
     graph_id     INT NOT NULL,
-    number       INT NOT NULL DEFAULT 0,
+    number       REAL NOT NULL DEFAULT 0,
     subtract     INT,
     updated_at   UNSIGNED INT NOT NULL,
     PRIMARY KEY  (graph_id)
@@ -70,7 +70,7 @@ EOF
     $dbh->do(<<EOF);
 CREATE TABLE IF NOT EXISTS prev_short_graphs (
     graph_id     INT NOT NULL,
-    number       INT NOT NULL DEFAULT 0,
+    number       REAL NOT NULL DEFAULT 0,
     subtract     INT,
     updated_at   UNSIGNED INT NOT NULL,
     PRIMARY KEY  (graph_id)
@@ -83,7 +83,7 @@ CREATE TABLE IF NOT EXISTS complex_graphs (
     service_name VARCHAR(255) NOT NULL,
     section_name VARCHAR(255) NOT NULL,
     graph_name   VARCHAR(255) NOT NULL,
-    number       INT NOT NULL DEFAULT 0,
+    number       REAL NOT NULL DEFAULT 0,
     description  VARCHAR(255) NOT NULL DEFAULT '',
     sort         UNSIGNED INT NOT NULL DEFAULT 0,
     meta         TEXT NOT NULL DEFAULT '',
diff --git a/lib/GrowthForecast/Web.pm b/lib/GrowthForecast/Web.pm
index 61539e9..6dd813f 100644
--- a/lib/GrowthForecast/Web.pm
+++ b/lib/GrowthForecast/Web.pm
@@ -748,7 +748,7 @@ post '/api/:service_name/:section_name/:graph_name' => sub {
         'number' => {
             rule => [
                 ['NOT_NULL','number is null'],
-                ['INT','number is not null']
+                # ['INT','number is not null']
             ],
         },
         'mode' => {

ValidateRule とか、HTML::Shakan を使ってそうな書き方なので、本当は数値だけが通るようにとかしたほうがいいとは思うんだけれど、とりあえずこれで整数値以外の値でもグラフがかけるようになりました。
いまのところ特に問題はないし、まぁいいかな?


というわけで当初の目的通り、グラフを生成することができました。

後日談

本当は GrowthForecast ではなく、HRForecast を導入しようとしていて、MySQL ではなく PostgreSQL にも対応できるように書き換えたりとか頑張ったけれど、最終的に HRForecast も整数値しかグラフにすることができなく、その部分を直すのがめんどくさそうだったので GrowthForecast に乗り換えました。時間があるときに HRForecast 整数値以外でグラフがかけるようにしたいな。

*1:cpanm App::gh でインストールしました。

gcc をソースからインストールする

RedHat Linux 4 を使っているんだけど、個人で gcc 4.6 をインストールしたい場合、どうすればいいの?*1
とかいう意味不明なことを聞かれたので、ためしに手元の環境 (Debian/wheezy) の $HOME 以下に gcc をインストールしてみることに。インストールといっても、結構カンタンで依存モジュールを入れつついつものようにコンパイルしていくだけでした。
需要はまったくなさそうだけど、メモとして。
上述のとおり、実際にインストールするのは RedHat だけれど、手元の環境は Debian なので、これを真似てもインストールできないかもしれません。

*1:RedHat4 にインストールされている gcc は 3.4.6 らしい

続きを読む

git svn で特定の commit を merge するなど

完全に個人的なメモ。
うーん。git むずかしい。

リモートのリリースブランチを更新する

$ git svn fetch

リモートのリリースブランチをローカルに Checkout する

$ git svn checkout -b local/RB-1.0.0 RB-1.0.0

trunk に入っているコミットをローカルのブランチにマージする

$ git cherry-pick -n <commit id>

"-n" をつけるとコミットしないため "git commit" でコメント書きつつコミットする。
ここで、git merge とかしてしまうと、特定のコミットではなく、 までのすべての更新を取り込んでしまう。

リモートのブランチにコミットする

$ git svn dcommit

Apache Killer をかいてみる

すっごい久しぶりに日記を書こうかと。
Apache Killer が騒がれてから、ずいぶん時間も経ったのでちょっと前のネタを投稿。

「うちのサーバも Apache Killer に対処しなきゃね。」

と騒いでいた頃に、検証用のために Apache Killer をダウンロードしてみたんだけれど、攻撃手段 *1 がスクリプト内にハードコードされていて、検証するたびにその部分を書き換えなきゃならなくて、ちょっとメンドクサイ。
ということで

Perl の勉強をしつつ、ちょっとモダンな Apache Killer を作ってみよう。」

という流れで作ってみました。不純な動機ですね。
工夫したところは。。。

  • Getopt::Long であらゆる項目を引数で受け渡せるように
  • HTTP リクエストを Furl を使う
  • FurlX::Coro で Coro 駆動にした
    • Parallel::ForkManager で Fork も可能

あんまりキレイには書けてないんだけど、とりあえず FW の機能などを検証するには充分な感じになりました。
あくようげんきんだよ!

*1:スレッド数や、リクエストのレンジ数