t.marcusの外部記憶装置

忘備録とかちょっとした考えとかをつらつらと...

NginxをL7 LBとして使う

名だたるメーカーのLBは数百万してしまうので、個人で使うには高過ぎる。
個人用途だと十分すぎる?のでnginxをアクティブスタンバイ構成のLBとして使う方法

やりたいことをまとめると

  1. /path1もしくは/path2以下のでアクセスが来た場合はweb2にproxyする
  2. 上記以外のリクエストはweb1にproxyする
  3. web1とweb2はそれぞれアクティブスタンバイ(active/passive)構成として、基本的にはactiveが受けるが、activeが応答しなかった場合はpassiveで処理を行う
  4. activeが復旧した場合はactiveが処理を行う

【テスト環境】

# サーバ環境
$ cat /etc/redhat-release
CentOS release 6.4 (Final)
$ nginx -v
nginx version: nginx/1.0.15

# ネットワーク環境
+ lb (192.168.56.20)
|
+- web1-active (192.168.56.30)
+- web1-passive (192.168.56.31)
|
+- web2-active (192.168.56.40)
+- web2-passive (192.168.56.41)

# LB以外のnginxのドキュメントルート配下の構成
# それぞれのファイルにはどのサーバのホスト名を書く
./
+ path1/
|   + index.html
+ path2/
|   + index.html
+ index.html
+ hoge.html
+ piyo.html

まずnginxにweb1とweb2のグループを登録してactive/passiveの設定を行う

$ cat /etc/nginx/nginx.conf
user              nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log;

pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    keepalive_timeout  1;

    # web1の設定
    upstream web1 {
        server 192.168.56.30:80    fail_timeout=1s max_fails=1;
        server 192.168.56.31:80    backup;
    }

    # web2の設定
    upstream web2 {
        server 192.168.56.40:80    fail_timeout=1s max_fails=1;
        server 192.168.56.41:80    backup;
    }

    include /etc/nginx/conf.d/*.conf;
}

そして、rewriteの設定を行う

$ cat /etc/nginx/conf.d/default.conf
server {

    listen       80;

    location / {
        proxy_pass http://web1;
    }

    location ~ (\/path1|\/path2)(\/.*)? {
        proxy_pass http://web2;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

そしてnginxを再起動すると、アクティブスタンバイ構成のLBとして機能するようになる。

Node.jsでカスタムエラー(メモ)

Node.jsでカスタムエラーをつくろうと思って、
Errorをinheritsしただけでは、error.stackが利用できなかったので、色々試行錯誤した結果をメモ。

ちなみに環境は
Node.js 0.10.29

// lib/error/base.js

'use strict';

var util = require('util');

function BaseError(message, code) {
  Error.call(this);
  Error.captureStackTrace(this, this.constructor);

  this.name = this.constructor.name;
  this.status = code || 500;
  this.message = message || 'BaseError';
}

util.inherits(BaseError, Error);
module.exports = BaseError;
// lib/error/extend.js
'use strict';

var util = require('util'),
  BaseError = require('./base');

function ExtendError(message) {
  BaseError.call(this, message || 'ExtendErrorMessage');
}

util.inherits(ExtendError, BaseError);
module.exports = ExtendError;
// lib/sample.js
var BaseError = require('./error/base'),
  ExtendError = require('./error/extend');

var be = new BasicError('msg1');
console.log(be);
console.log(be.stack);
var ee = new ExtendError('msg2', 503);
console.log(ee);
console.log(ee.stack);

って感じにすると

{ [BaseError: msg1]
  name: 'BaseError',
  status: 500,
  message: 'msg1' }
BaseError: msg1
    at /Users/tmarcus/Projects/node-test/lib/sample.js:4:5
    :
    :
{ [ExtendError: msg2]
  name: 'ExtendError',
  status: 503,
  message: 'msg2' }
ExtendError: msg2
    at /Users/tmarcus/Projects/node-test/lib/sample.js:7:5
    :
    :

という感じで出力されてるのでいけてるっぽい?

Vagrant VirtualBox NICアダプター追加に関する覚書

VirtualBoxから作ったVagrant BaseBoxにNicを追加する設定を追加するVagrantfileの忘備録

  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--nic2", "hostonly"]
    vb.customize ["modifyvm", :id, "--nictype2", "82540EM"]
    vb.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"]
  end

  config.vm.network "private_network", ip: "192.168.56.20"

Xmemcache + TimeUnitの組み合わせでミリ秒を利用して嵌った

実験環境:
xmemcached : 1.3.8
memcached : 1.4.11

作ろうとしていた機能は以下の様なものです。

  1. キャッシュを探してデータがあればそれを返す。なければ次の処理を実行する。
    1. 別システムからデイリーで変更されるIDのリストを取得する
    2. それぞれのデータにプログラム側が持ってるメタ情報をくっつける。
    3. 組み立てたデータを毎時15時パージするようにキャッシュに放り込む
    4. 組み立てたデータを返す。

実際に起きた現象はこんなかんじです。
1日目・2日目は正常にデータが更新される。
3日目以降は2日目のデータが残り続ける。

結論からいうと、TimeUnitで時間の単位変換をしようとして、toSeconds(ttl)を利用する際に、粒度の細かい方から粗いほうへ変換した際に値の切り詰めが発生してしまった感じです。
値の切り詰めに関しては、TimeUnit (Java Platform SE 6)を参考にしてください。

Vagrantを試してみる

諸般の事情でCentOS5.4を使ったテストをする必要があって、今更感はあるがどうせならということでVagrantを使って環境構築を試してみる。

これを書いている時点ではCentOS5.4のboxが無いので、それを作っていく。

基本的には
Vagrant の VirtualBox 用 Base Box ファイルを手動で作ってみる | CUBE SUGAR STORAGE
を参考にしていったが、一部Guest Additionはライセンス的に使えない環境なのでスキップ。
あと、5系なので(?)/etc/udev/rules.d/70-persistent-net.rulesにはファイルが作られないので、それもスキップ

// TODO 詳細な手順を書く