メイン

2008年7月15日

TCP/IP入門
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

このブログを読んでる方にはWebプログラマが多いかと思いますが、Webの仕組みを基礎から理解してプログラムは書いてますでしょうか。
もちろんそんなことは知らなくても抽象化されてるので気にする必要は全然ないのですが、やはりエンジニアとしてはちゃんとどういうものか理解してプログラムを書いた方がよりよいプログラムが書けると思います。

そこで先日の社内勉強会で、TCP/IPについて軽くおさらいしてみました。
かくいう僕もTCP/IPについて勉強したのは7, 8年前だったのでいろいろ復習してたんですが、忘れていたり、実はちゃんと理解できてなかったことがありました。

せっかくなので資料を公開しておきます。
よかったら参考にしていただければと思います。

Read this document on Scribd: tcpip

TCP/IPの勉強にはマスタリングTCP/IP 入門編がおすすめです。

マスタリングTCP/IP 入門編 第4版
竹下 隆史 村山 公保 荒井 透 苅田 幸雄
オーム社
売り上げランキング: 1104
おすすめ度の平均: 5.0
5 まとめ方はうまい
5 ネットワークの基礎を学ぶ上での教科書
4 辞書としてはかなり有用
5 第3版との異同
5 TCP/IPのバイブル

2008年5月 1日

コマンドラインから使うBitTorrentクライアント
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

yukiです。

唐突ですが、BitTorrentクライアントは何をお使いでしょうか?これまで私はずっとBitComet を使ってきましたが、私の非力な自宅マシンだとどうしても負荷が高く、その間は何も出来ないような状態に陥っていました。GUIから使おうとすると、見やすさや使いやすさはさすがに良いのですが、あまりの負荷とその間何も出来ない状況はあまりよろしくないと考え、今回はUNIX系でCLIから操作できるクライアントはないだろうか、と探していて見つかったEnhanced CTorrentをご紹介することにします。

Enhanced CTorrentは、C++で書かれたCtorrentをベースにしたBitTorrentクライアントです。Ctorrentからバグフィックスや改良・軽量化を重ねており、現在のバージョンは3.3.1になっています。

Enhanced Ctorrentは現在はSorceforgeでバグレポートやダウンロードができますので、早速使ってみました。

インストール

インストールは非常に簡単で、普通にwgetで落としてきて展開し、configureしてmake installします。

% wget http://jaist.dl.sourceforge.net/sourceforge/dtorrent/ctorrent-dnh3.3.1.tar.gz
% tar zxvf ctorrent-dnh3.3.1.tar.gz
% cd ctorrent-dnh3.3.1
% ./configure
% make
% sudo make install

torrentファイルからダウンロードする

早速torrentファイルをダウンロードして、ダウンロードしてみましょう。 やり方は非常に簡単で、これだけです。

ctorrent [torrent.file]

これだけで同じディレクトリ内にダウンロードが開始されます。
注意点としては、デフォルトだと2706-2106番ポートを使うようになっていますが、オプションでポートを指定することが出来ます。とても簡単なうえ、デーモンとして起動することも出来ますのでバックグラウンドで動作させたい場合にも非常に便利です。

2008年4月24日

rpmパッケージを作ろう
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

先日社内勉強会でrpmパッケージの作り方についてやってみました。
資料を公開しておくのでよろしければご参照ください。

Read this doc on Scribd: rpm

参考用に以前GNU Autotools用のサンプルプログラムで作ったbatのrpmパッケージを使いました。
次のようなコマンドでrpmパッケージを作成できます。
基本的な機能をある程度網羅したつもりなので、参考になれば幸いです。

rpmbuild -ta bat-0.0.3.tar.gz

bat-0.0.3.tar.gz

2008年4月 7日

LD_PRELOADを使って任意の関数呼び出しにフックしてみる
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

先日の社内勉強会のLTでLD_PRELOADについて簡単にやってみました。

LD_PRELOADって?

環境変数$LD_PRELOADを使うと他のライブラリの読み込みの前に任意のライブラリを先に読み込ませることができます。
実行プログラムの形式にELF形式を採用しているOSで使うことができます。
Linuxであれば問題なく使用できるはずです。

何ができるのか

プログラムを変更することなく、任意の関数を上書きしたり、任意の関数にフックすることができます。

libhookwriteを作ってみた

簡単なサンプルプログラムとしてlibhookwriteというのを作ってみました。
libhookwriteはその名の通りwrite(2)にフックをかけることができます。
といってもできることは限られていてファイルのタイムスタンプの更新か、任意のプログラムをsh経由で実行することしかできません。

ダウンロード

libhookwrite-0.0.1.tar.gz

インストール

お約束通り

tar zxvf libhookwrite-0.0.1.tar.gz
cd libhookwrite-0.0.1
./configure
make
sudo make install

rpmでもいけます。

rpmbuild -ta libhookwrite-0.0.1.tar.gz
sudo rpm -ivh libhookwrite-0.0.1-1.i386.rpm

使い方

環境変数$LD_PRELOADにlibhookwrite.soを指定します。
さらに環境変数$HOOKWRITE_UPDATE_FILEか$HOOKWRITE_COMMANDを指定します。

HOOKWRITE_UPDATE_FILEにファイル名を指定すると、write(2)が呼ばれたときに指定されたファイルのタイムスタンプを現在時刻に更新します。

HOOKWRITE_COMMANDに任意のコマンドを指定すると、write(2)が呼ばれたときに指定されたコマンドを/bin/sh経由で実行します。

例えば、次のようなシェルスクリプトcat.shを実行すると、write(2)が呼ばれた時点で$HOME/tmp/catというファイルのタイムスタンプを現在の時刻に更新して、"hoge"と出力します。

#!/bin/sh
HOOKWRITE_UPDATE_FILE=$HOME/tmp/cat ¥
  HOOKWRITE_COMMAND='echo hoge' ¥
  LD_PRELOAD=/usr/lib/libhookwrite.so ¥
  /bin/cat $@

使い道

例えばエディタがファイルを保存したときに、何らかのアクションを起こしたい場合に使えるかもしれません。
プログラムに依存しないので、vimだろうがemacsだろうが何でもいけるはず。
ただ、スワップファイルの書き出しにも反応してしまいますが。(^^;

vimを使ってsymfonyプロジェクトの開発をやってて、ファイルを保存したい瞬間にsymfony ccを走らせてキャッシュクリアしたい場合はこんな感じのaliasを作ればいいでしょうか。

alias vim="LD_PRELOAD=/usr/lib/libhookwrite.so HOOKWRITE_COMMAND='/symfony/project/symfony cc' /usr/bin/vim"

プログラム

プログラム自体は非常に簡単です。

static ssize_t (*write_org) (int fd, const void *buf, size_t count) = NULL;

write(2)と同じプロトタイプ宣言を持つ関数ポインタwrite_orgを定義しています。
オリジナルのwriteを保存するのに使います。

__attribute__((constructor))
void
_save_original_functions()
{
    write_org = (ssize_t(*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");
}

dlsym(3)を使ってwriteのアドレスを取り出して、write_orgに保存しています。
__attribute__((constructor))というのはgccの拡張になってて、これを指定しておくとmain関数が呼ばれる前に実行してくれます。

後は単純にwrite関数を改めて定義して、その中に任意の処理を書いておきます。
最後に return write_org(fd, buf, count);でオリジナルの処理を呼び出して終わりです。

参考

man ld.soでマニュアルが読めます。
LD_PRELOADの他にもいろいろな機能がありますので、一度読んでおくといいかもしれません。

fakechroot

LD_PRELOADを使った面白いソフトウェアでfakechrootというのがあります。
chroot(2)の実行にはroot権限が必要ですが、fakechrootでは擬似的に一般ユーザ権限でchrootを実現しています。
LD_PRELOADを使って、ファイル操作に関わる部分にすべてフックをかけて擬似的にchroot環境を提供しているんでしょうね。

Mac OS Xだと

実行プログラムの形式がELFではなくMach-Oが採用されています。
なので、LD_PRELOADは使えないはず。
代わりにDYLD_INSERT_LIBRARIESというのが使えます。

man dyld

詳しく検証してないので、詳細はよくわかってません。

まとめ

LD_PRELOADを使うとプログラムに直接手を加えることなく、外から挙動をコントロールすることができます。
応用範囲は無限大です。

2007年12月21日

なんて読むのかわからない
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

韓国大統領選挙に出馬するのを忘れていたと思っていたら、 いつの間にかmixi新CTOにノミネートされてた今日この頃、 みなさんいかがお過ごしでしょうか。 今日はちょっと趣向を変えて、ライトな感じのエントリでいこうかと思います。

ITエンジニアに英語が苦手な方が多いかと思います。 僕も英語が大の苦手で、英語に対してコンプレックスを持つ者の一人です。 そんな僕ですが、なんとか簡単な会話を英語でこなすことができるようになりました。 僕の英語の学習の課程は、以前のエントリ 「海外経験のない典型的理系人間が日常会話レベルの英語を話せるようになるまでの道のり」 で紹介したので、よかったら参照してください。

英語に限らず、IT業界にいると読み方のよく分からない単語が出てきます。 妙に省略された単語だと読み方がさっぱり分からない事がありますが、 通常の英単語であれば辞書の発音記号を見ればなんとなくわかります。 が、そこは英語苦手の多いIT業界。 勘違いやローマ字読みなどで一風変わった読み方に出会う事も少なくありません。

そこで今回は、読み方のよく分からない単語や、 面白い勘違いの読み方がある単語を大募集します。 コメント、TB、はてブなどで読み方のよく分からない単語をぜひ教えてください!!

参考までに僕の方でいくつかあげておきます。

alt - オルト

僕はいつも「オルト」と呼んでますが、 ローマ字読みで「アルト」と発音する方が多いようです。 「alternative - オルタナティブ」からきてるので、 「オルト」と呼ぶのが近いと思ってますがどうなんでしょうか。

warning - ウォーニング

やっぱりこれもローマ字発音で「ワーニング」と呼ぶ方が多いです。

fatal - フェイタル

ローマ字読みで「ファタル」というのを聞いた事があります。

allow - アラウ

(ry

prepare - プリペア

(ry

require - リクワイア

読み方知らない方が以外に多くいます。

MySQL - マイシクー

日本だと「マイエスキューエル」じゃないと逆に通じないでしょうか。

PEAR - ペア

PHPのライブラリを集めたアーカイブ群

CPAN - シーパン

「クーパン」ですか? もう分からない、助けて

参考

新版 UNIX 由来/読み方辞書が非常によくまとまってて面白いです。 これを読むだけでかなり解決するかと思われます。 ぜひ一読をおすすめします。

abbreviationとacronym

最後にちょっとしたトリビア。 IT用語には省略語が多いですが、省略語にはabbreviationとacronymの2種類があります。 acronymはそれを単語のように発音する省略語で、abbreviationはそうじゃないやつ。 なので、SCSI(スカジー)はacronymになりますが、USB(ユーエスビー)はabbreviationになります。

2007年12月 3日

ソフトウェア開発におけるハリー・ポッターは?
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

こんにちは! やまもと@テスト番長です。

前回のエントリでご案内したQA勉強会を先日無事開催致しました。
集まってくださった皆様と非常に有意義な時間を過ごす事が出来ました。ありがとうございました。
またいずれ何かしら出来ればと思っておりますので、その際は宜しくお願い致します。

さて、今日は面白い小話を見つけましたので、ご紹介したいと思います。
ITコンサルタントの草分け、「オレンジジューステスト」の話でも有名な、ジェラルド.M.ワインバーグ氏へのインタビューです。

Interview with Jerry Weinberg
http://www.citerus.se/kunskap/pnehm/pnehmartiklar/interviewwithjerryweinberg.5.484cc23b1165f30e75680002483.html

インタビューの後半は品質の問題について話が進んでいくのですが、
一番最後の質問にこうありました。

Q:もしあなたがソフトウェア開発におけるJ.K Rowlingだとしたら、誰をハリー・ポッターにしますか?

A: ええと、私は(J.K Rowlingのような)億万長者ではないので適切かどうか分かりませんが、ハリーは、魔法を使えるのにも関わらず「彼はただのテスターだから」と値切られるテストマネージャーにするでしょう。
ヴォルデモートは、「いいえ」と言うことが出来ないか、ハリーのいうことを聞かないプロジェクトマネージャーたちだと思います。


流石の表現力です。自分も「魔法」を身に付けたいと切実に思いますが、この例えでいくとホグワーツはどこになるのでしょうね。

2007年10月10日

Wikiのプラグイン記法を実装する
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

bokkoです。

普段からWikiを使っていると、「○○する記法がほしいなあ」と思うことがあると思います。
しかし、単純に記法を追加しようとすると、ほかの記法とぶつかってしまったり、思わぬ副作用を引き起こす可能性があるため、大抵のWikiクローンには独自でプラグインを作るための仕組みがあります。
例えば、どこかにplugin_nameというスクリプトファイルを用意し、{{plugin_name 引数}}と書かれた部分をそのスクリプトファイルを実行した結果に置き換える、という風に。

というわけで、今日は私がローカルで使っているオレオレWikiクローンでのプラグイン機構の実装例を紹介しようと思います。実現するためのコードは以下のようになっています。(ほかの機能のためのコードが混ざってしまっていてちょっと見づらいですが)

private function createPlugin(){
    $dir = Config::GetPluginDir().'/';
    $hd = null;
    $file = null;
    $str = 'if($hd = opendir($dir)){
                  while(false !== $file = readdir($hd)){
                      if($file === \\\'\\2.php\\\'){
                          require_once($dir.$file);
                      }
                  }
              }
              if(function_exists(plugin_\\2)) return \\\'\\1\\\'.plugin_\\2(\\\'\\3\\\', $this->plugined_file).\\\'\\4\\\';
              else return \\\'Not Found!\\4\\\';';
    // 引数なし 例:{{lastupdate}}
    $this->text = preg_replace("/([^<])\{\{([^\{ ]*)()\}\}([^>])/e",
                                          "eval('$str')",
                                          $this->text);
     // 引数あり 例:{{strlen abc}}
     $this->text = preg_replace("/([^<])\{\{([^\{]*)\s([^\{]*)\}\}([^>])/e",
                                           "eval('$str')",
                                           $this->text);
} 

まず、テキストの中{{plugin_name}}、または{{plugin_name 引数}}というのがあれば、その中身をevalに放り込みます。その後、plugin_nameの部分に該当するファイル名と関数名があれば、その関数を実行し、結果を返します。ファイルや関数が存在しない場合は、「Not Found!」という文字列を返します。(実際に実用的なプラグインの仕組みを作る場合はもっと厳密な決まりが必要だと思います)

時刻を取得する場合は、以下のようなコードになります。

function plugin_lastUpdate($arg, $file){
    return date("Y/m/d H:i:s");
}

2007年9月25日

Rubyでネットワークサーバを書く
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

先日公開したブラウザだけでネットワーク対戦ゲームができるサイト「プラッシュ」では、 フラッシュとネットワーク通信を行う専用のXMLSocketサーバを開発しました。 このXMLSocketサーバはrubyで書かれています。 LLでデーモンを書く需要が、それほどあるとは思えませんが、デーモンを書く際に気をつけた点、工夫した点をまとめてみたいと思います。

なぜrubyを選んだのか

rubyを選んだのには理由は2つあります。

  • Railsを採用した
  • LLで早く開発をしたかった

僕も昨今のRailsブームにのって個人的にRailsを使い始めていました。 プラッシュは完全に新規プロジェクトで環境を選択する事ができたので、迷わずRailsを選択しました。

では、なぜCのようなコンパイル言語で書かなかったのか。 速く動くものを開発するよりも、早く開発をしたかったからです。 Webサービスにとって開発スピードは最も重要な項目の1つです。 最初から速いものを作る必要はありません。早く市場に出さないとうまくいくかどうかもわかりません。 速くするのは後からでも全然構わないのです。

デーモンになる

デーモンになるために必要なのは次の4つです。

  • fork -> setsid -> fork
  • ルートディレクトリに移動する
  • umask をクリアする
  • 標準入出力、標準エラー出力を /dev/null に向ける

僕は次のようなメソッドを定義して実行してます。

def daemonize
  exit! 0 if fork
  Process::setsid
  exit! 0 if fork
  Dir::chdir('/')
  File::umask(0)
  STDIN.reopen  '/dev/null', 'r' 
  STDOUT.reopen '/dev/null', 'w' 
  STDERR.reopen '/dev/null', 'w' 
end

デーモンについては以前勉強会やった内容を公開していますので、よかったらそちらをご覧下さい。 UNIXデーモンを作ろう

全てのエラーを補足する(堅牢性)

デーモンはバックグランドで24時間動き続けないといけません。 デーモンが落ちてしまうと全くサービスが継続できなくなってしまいますから、多少のエラーが発生しても大丈夫なように作らないといけません。 幸いな事にrubyの場合は、ruby自体が落ちてしまわない限り、あらゆるエラーを補足することができますので、上位のところで全てのエラーを補足するようにするだけで問題ありません。

メモリリークに気をつける

Webアプリのプログラムのように短時間で処理が終了してしまうものは、メモリリークを気にする必要などほとんどありませんが、 デーモンのように24時間動き続けるようなシステムでメモリリークがあると、 最初は調子よく動いていても長い間実行するとメモリをたくさん消費して大変な事になってしまいます。 といってもrubyの場合はruby側でメモリ管理をしてくれるのでメモリリークする心配はあまりありません。

スコープ内にあるローカル変数はスコープから抜けたら勝手にrubyのGCが開放してくれるので気にする必要はありません。 気をつけないといけないのは永続的に使用しているオブジェクトになります。 永続的に使用しているオブジェクトに必要ないものが出てきたら忘れずに、Array#delete、Hash#deleteを呼ぶか、nilを代入するなどして、 rubyのGCが開放できるような状態にしてやる必要があります。

LLのGCのアルゴリズムに参照カウンタを採用しているものがありますが(php, perl, python)、GCのアルゴリズムが参照カウンタの場合、 循環参照のオブジェクトの開放ができなくてメモリリークになってしまう問題があります。 rubyのGCのアルゴリズムはmark-sweepになってるそうなので、この点は安心できます。 pythonは参照カウンタですが、循環参照のオブジェクトを開放する機構があるそうです。

IOを多重化する

ネットワークサーバは(inetdのようなものを使わない限り)複数コネクションを扱えないといけません。 通常ネットワークサーバが複数プロセスを扱う時は1コネクションに対して、 1プロセス or 1スレッドを生成するマルチプロセス/スレッドモデルで処理をするのが一般的です。

rubyで実装するので、プロセスモデルでコネクションをさばくには処理速度やリソース消費の観点から懸念がありました。 実際に試してないのでもしかしたら余計な心配だったのかもしれませんが。 スレッドモデルも考えたのですが、 rubyのスレッドはネイティブスレッドではなくruby自身が持っているもので、 複数コネクションをさばくにはお話にならないくらいコンテキストスイッチの速度が遅くて使い物になりませんでした。

そこでIO#selectを使ってIOを多重化することにしました。 それぞれ単純な役割を持った4つのスレッド「コネクションをacceptする」「ソケットから入力を読み取りキューに登録する」「接続が切れたコネクションを開放する」「キューから命令を取り出して実行する」で処理を行うようにしました。 次のようなプログラムで処理しています。

def main
  server = TCPServer.new(@port)

  Thread.fork {
    while true
      begin
        add_connection(server.accept)
      rescue Exception => error
        logger.fatal error
      end
    end
  }

  Thread.fork {
    while true
      begin
        read_instructions
      rescue Exception => error
        logger.fatal error
      end
    end
  }

  Thread.fork {
    while true
      begin
        manage_connection
      rescue Exception => error
        logger.fatal error
      end
    end
  }

  while true
    begin
      dispatch
    rescue Interrupt
      break
    rescue Exception => error
      logger.fatal error
    end
  end
rescue Exception => error
  logger.fatal error
  exit(1)
end

このように生成されるスレッドを限定する事でコンテキストスイッチの遅さは問題なくなります。 IOを多重化することでコネクションが増えても、1ソケット分のオブジェクトが増えるだけになり、 コネクションが増えてもそんなに負荷が上がらないような構造になっていると思います。

とはいえ、この方式にもいくつか問題点はあります。 1つは命令実行スレッドが命令をシーケンシャルに実行するので、1つ重い処理があると他の命令が実行されなくなってしまうので、 全体の処理に影響を与えてしまうことです。 これに関しては命令実行スレッドを増やしたり、命令に実行優先順位をつけるなどして対処することができると考えています。

もう一つはマルチコアのCPUで1つのコアしか活用できない点です。 rubyのスレッドはネイティブスレッドではないので、OSから見るとただの1プロセスにしか見えません。 なので、せっかくマルチコアのCPUを搭載していても1つのコアしか使用する事ができません。 これに関しては複数プロセスで動作できるようにしたり、少し作り込みが必要になってきます。

まとめ

rubyでネットワークサーバを書く時に気をつけた点についてまとめてみました。 他にも「こうした方がいいよ」とか「こういうのがあるよ」とかありましたら、いろいろ教えていただければと思います。

2007年9月17日

DRBDで2TBのハードディスク容量を使う方法
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

こんにちは、naoyaです。

先日、フォト蔵のサーバのハードディスク空き容量が減ってきたので、ハードディスクを500GBx4から1TBx4のハードディスクに交換しました。

フォト蔵のサーバでは、以前satoが紹介したようにDRBDを使って写真や動画のデータを相互バックアップしています。

フォト蔵のサーバのハードウェアとソフトウェア環境は、次のとおりです。

  • HDD: 1TB x 4
  • OS: Fedora Core 5(2.6.20)
  • DRBD: 0.7.24

ハードディスクは、二本ずつソフトウェアRAID0で組んでいます。

# cat /proc/mdstat
Personalities : [raid0]
md1 : active raid0 sdb1[0] sdc1[1]
      1953519872 blocks 64k chunks

md0 : active raid0 sda3[0] sdd1[1]
1943639872 blocks 64k chunks

unused devices:


この状態で、次のコマンドでDRBDを起動させてみました。

# /etc/init.d/drbd start

そうすると、次のエラーメッセージが表示されてしまいました。

/etc/init.d/drbd start
Starting DRBD resources:    [ d0 d1 d2 ioctl(,SET_DISK_CONFIG,)
failed: Cannot allocate memory
...

調べてみると、vmalloc sizeを192m割り当ててると、うまくいくそうなので、grubの設定ファイル(/etc/grub.conf)に、次の内容に変更してみました。

...
  title Fedora Core (2.6.20-1.2320.fc5smp)
  root (hd0,0)
  uppermem 524288
  kernel /vmlinuz-2.6.20-1.2320.fc5smp ro vmalloc=192m root=LABEL=/
  initrd /initrd-2.6.20-1.2320.fc5smp.img
...

vmallocの設定は、rootより後ろに書けないので注意してください。

この設定で、初めてDRBDで2TBのハードディスク容量を使うようにすることができました。


最初、移行するとき、DRBD上のファイルシステムはXFSにしていたのですがbonnie++でハードディスクに負荷をかけると落ちてしまうので、従来通りext3に変更して現在稼働中です。

次は、現在satoがDRBD 8系でのprimary/primaryの構成を試しているようなので、フォト蔵のサーバにも組み込めるか検討したいと思っています。


2007年9月 6日

PHPでSSL通信する時の注意点
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

yukiです。
今回はPHPでSSL通信したい時の注意点などを紹介します。

PHPでSSL通信を行う際には、

  • fsockopen
  • pfsockopen
  • file_get_contents
  • fopen
  • stream_socket_client

など様々であり、利用する場面がありますが、SSL通信が許可されている必要があります。
よくHTTP_Requestなどを利用してPOSTしたいがhttpsだとうまくいかない!という記事を見かけますが、参考になればと思います。

  • * allow_url_fopenが有効かどうか

上記の関数についてfile_get_contents・fopenでは上記設定が有効かを調べます。
php.iniで設定されていますが、通常デフォルトで使用可能なのですが、レンタルサーバーなどでは使えないこともありますので調べてみましょう。
phpinfo()関数を利用するか、コマンドラインでは
php -i | grep allow_url_fopen

で知ることが出来ます。
またphp4.0.3以前では
--disable-url-fopen-wrapper

でコンパイルされていると利用不可となっています。

  • サポートされているプロトコル・ラッパーを調べる
通信する際のプロトコル、及びラッパが使用可能かを調べます。この場合はhttps://(PHP4.3.0以降)が対象です。 phpinfo()ではRegisterd PHP Streamで確認できます。 SSL通信の場合OpenSSLがインストールされている必要があり、PHP4.3.0以降では静的にコンパイルされ組み込まれている必要がありますが、PHP5以降ではモジュールとしてコンパイルされていても使用できます。

レンタルサーバーなどでPHP4.3以降を利用し、かつOpenSSLサポートがなければ、管理者によってリコンパイルされなければなりません。

ですが、もしcurlコマンド(SSLが有効であること)が使える環境であれば、popen・proc_open関数から利用することもできます。(レスポンス速度等の問題はありますが)

なおOpenSSLのバージョンもPHPによって異なるので注意が必要です。

以下をまとめると次のような表になります。

PHP再コンパイルOpenSSL
~4.0.4×0.9.6~
4.0.5~4.2.3×0.9.5~
4.3.0~4.3.10.9.5~
4.3.2~0.9.6~
5.0.0~×0.9.6~

利用するなら、PHP5がお手軽なようです。

2007年8月24日

5分でできるウェブサーバのセキュリティ向上施策
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

こんにちは、naoya です。

先日、ウノウが公開しているサービスの中にいくつかの脆弱性が見つかったため、社内で「脆弱性発見大会」を開催しました。この大会は、二人一チームに分かれてウノウが公開している各サービスの脆弱性を見つけることを目的とした大会です。結果は、いくつか各サービスに脆弱性が見つかり、すぐに修正することができました。

僕のチームは、ウノウのホームページやラボブログなど細かいサービスを担当しました。その中で、いくつかのウェブサーバにセキュリティ上あまい設定がありました。

今日は、ウェブサーバのセキュリティ向上のための設定方法についてエントリします。なお、ウェブサーバはApache 2.2系を前提としています。

サーバ情報の表示しない

ウェブサーバ(Apache)で、404などのエラーページを表示したとき、ヘッダやページの下にApacheやOSのバージョンが表示されます。こういったサーバ情報をわざわざ表示する必要はありません。サーバ情報の表示しないようにするには、Apacheの設定ファイル(httpd.conf)に、次の設定を追加します。

  ServerTokens ProductOnly
  ServerSignature Off

この設定を追加後、Apacheを再起動するとServerヘッダにはApache、エラーページにもサーバの情報は表示されなくなります。


.で始めるディレクトリは公開しないようにする

ウノウでは、すべてのサービスをsvn(Subversion)で管理しています。アップデートもsvnで行っています。そのため、.svnディレクトリが誤って公開されていることがあります。.svnディレクトリには、ソースコードが入っていますので公開しない方がいいです。.svnだけでなく、.で始まるディレクトリを公開しないようにするようには、Apacheの設定ファイル(httpd.conf)に、次の設定を追加します。

.svnディレクトリにはソースコードが入っているので、注意する必要があります。

  <Directory ~ "/\..+/">
        Order Deny,Allow
        Deny from All
  </Directory>


最後に、PHPのセキュリティ向上施策も追記しておきます。

PHPファイルに対してリクエストすると、HTTPヘッダにX-Powered-Byという情報が入っています。X-Powered-Byヘッダには、PHPのバージョンが次のような形で含まれています。

X-Powered-By: PHP/4.3.11

このヘッダを隠すには、PHPの設定ファイル(php.ini)に、次の設定を追加します。

  expose_php = Off


この他にも、ウェブサーバのセキュリティ向上のための情報がありましたら、ぜひ教えてください!

2007年8月23日

赤ちゃんの目をシミュレートするテストツール?「TinyEyes」
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

こんにちは! やまもと@テスト番長です。

ラボブログでご紹介するネタを暖めていたら、結構話が大きくなってきてしまい、更にもう少し暖めたくなりました。
なので今回は代わりに、先日幸せの青い鳥を探してネットをうろうろしていた時に見つけた軽めのネタをご披露したいと思います。


tinyeyes
tinyeyes posted by (C)フォト蔵

生まれたての赤ちゃんはまだモノが良く見えていないんだそうです。
その赤ちゃんの視界をシミュレートするサイトです。
「TinyEyes」

赤ちゃんが生まれてからの週数と、対象までの距離をセットして画像をアップロードすると、それがどんなふうに見えているのかシミュレートして表示してくれます。

新生児向けのWEBコンテンツを作ることになったら、大活躍しそうなテストツールですね!(多分出番ない)

2007年8月21日

Flashの新しい可能生 Asynchronous Flash + XMLSocket
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

昨日ラボプロジェクトとして実験的に開発している新規プロジェクト「プラッシュ」をβ公開しました。 簡単に説明するとプラッシュはFlashとXMLSocketを使う事でブラウザだけでネットワーク対戦ができるゲームポータルサイトです。 今回はプラッシュで使われているFlashとXMLSocketを使ったアプローチについて考察してみたいと思います。

はじめに

正直に告白すると僕はFlashを一行も書いた事がありません。(汗) なので、Flashの部分に関してはFlash側の開発者であるyossyに聞いたり、Webで調べた情報がほとんどです。 不正確な情報が含まれてる可能性がありますが、その辺を考慮していただければと思います。

FlashのXMLSocketで何ができるのか

FlashのXMLSocketを使うと直接ソケット通信を行う事ができます。 AjaxやCometのような技術は元々ステートレスなHTTP上で非同期通信を実現していますが、 XMLSocketは直接ソケットを叩けるので自然な非同期通信を行う事ができます。 AjaxやCometはデータのやり取りをする度にコネクションが切れますが、XMLSocketはずっとコネクションをはったまま通信を行います。

通信の度にコネクションを確立するアプローチだと、毎回接続するためのコストがかかります。 XMLSocketはずっとコネクションをはっているので、通信の度に接続する必要がなく、よりリアルタイムな通信を実現する事ができます。 プラッシュではそれをネットワーク対戦ゲームに応用しました。

Flashを使ったリアルタイム通信で何ができるのか

それは僕にもわかりませんが、大いなる可能生は感じています。 Flashを使う最大のメリットはブラウザだけで動作する事です。 それにリアルタイム通信が加わった時に、従来ブラウザだけではできなかったことがブラウザだけでできるようになり、新たなる市場が開拓されるかもしれません。

何が必要なのか

FlashでXMLSocketを使用した通信を行うには次のものが必要です。
・Flash Player 5以降
・XMLSocketサーバ
・プロトコル

Flash Player 5以降

Flash Player 5以降でないとXMLSocketは使えないそうです。

XMLSocketサーバ

XMLSocketは直接ソケットを叩くので、独立したサーバが必要になります。 プラッシュではオリジナルのXMLSocketサーバを開発しました。

プロトコル

XMLSocketでの通信はソケットを直接叩くので具体的なデータのやり取りについては定められていません。 汎用的なプロトコルは存在しないので、クライアント側、サーバ側であらかじめ決められたプロトコルを定めて通信を行う事になります。 プラッシュではXMLをベースにした独自プロトコルで通信を行っています。

Flash+XMLSocketを使った既存の実装は

Flash+XMLSocketを使ったチャットの実装はいくつか公開されているようです。 それ以上本格的なものはなかなか見つからないのが現状です。

天鳳というオンライン麻雀がありますが、これはFlash+XMLSocketで作られています。 天鳳は大変素晴らしい実装なので一度遊んでみるといいと思います。

Flash+XMLSocketをもっと普及させるには

Flash+XMLSocketを使ったリアルタイム通信は古くから存在するにも関わらず、それほど注目されていませんでした。 僕はこの技術に大いなる可能生を感じていて、もっと広く普及しないかなと思っています。 そこでこの技術が普及するために何が必要かを考えてみました。

名前をつける

技術がより一般的になるためには呼びやすい名前が必要です。 「FlashとXMLSocketを使ってリアルタイム通信するやつ」なんてのはかったるくて呼びづらい。 何か良い名前はないでしょうか。

開発の敷居を下げる

より多くの実装が出てくるには開発の敷居を下げる事が重要。 開発の敷居を下げるために必要なことをつらつらと書いてみます。

フリーの汎用的なXMLSocketサーバ

既にXMLSocketサーバの実装はいくつかあるようですが、開発が止まっていたり、チャットに特化しているのが実情のようです。 フリーで汎用的なXMLSocketサーバがあれば開発の敷居を大きく下げる事ができると思っています。

モジュールのような形でプログラムを書く事ができて、LLで実装できるようなやつ。 プラッシュではRubyでXMLSocketサーバを書いてます。 LLでもうまくやれば十分サーバの開発は可能です。

汎用的なプロトコル

実装するたびに毎回独自プロトコルを作るのは大変ですから、汎用的なプロトコルが欲しいところ。 汎用的で可読性が高くて単純で拡張性が高いプロトコルがいいかなと思っています。 汎用的なプロトコルを定義するだけでなく、もちろんそれをベースにしたFlashライブラリ、XMLSocketサーバの実装も必要です。

まとめ

みなさんもFlash+XMLSocketを使って何か実装してみてはどうでしょうか。 今までにない何かが作れるかもしれません。

今回プラッシュで作った成果物は何らかの形でうまく公開できないか思案中です。 公開する時には、またこのブログで紹介したいと思います。

2007年8月13日

プログラミングに使いやすいフォントを選ぶ
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

yukiです。

人によってまちまちですが、見易さや生産性にかなり影響する(と思っている)プログラミング時のフォントについて紹介します。
マカーの方はデフォルトで十分読みやすいフォントが入っているので、ここではwindows向けとして紹介させて頂きます。
個人的に選ぶポイントは、


  • ゼロ・オーは斜線で区別がつく

  • 日本語も使える

  • 長時間見ても疲れない(一番大事)


です。これいいよ!というのがあったら絶賛募集中です。

有名どころかもしれませんが

M+フォント

M+フォント
M+フォント posted by (C)フォト蔵
普段はコレを使わせていただいています。
自分的にはゼロ(0)とオー(O)の差が分かりやすく◎です。
ゼロの中にスラッシュやドットが入っていて読みやすく、等幅なので使いやすいです。

VLゴシックフォントファミリ

上記のM+を元に製作されたフォントです。 弊社CTOが過去に参加されていたVineLinuxのProjectVineの方が製作されています。

小夏フォント

ちょっとクセがありますが、縮小しても見やすくいい感じのフォントです。

XANO明朝フォント

日立と契約し無償で配布されているフォント。明朝体なので若干日本語が厳しめですが、英数字には良いかも知れません。

また、ClearTypeを使うとWindowsでも多少美しくなるので、ClearTypeに対応したフォントがあれば試してみる価値があるかもしれません。

2007年7月27日

ベンチャー流Webサービスの作り方(開発チーム編)
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

前回はWebサービスを作るときの企画の部分について書きました (ベンチャー流Webサービスの作り方(企画編))。 今回はWebサービスを作るときの組織作りについて書いてみたいと思います。

僕がウノウに入って始めたのがフォト蔵の開発でした。 当初は開発が僕、ディレクションが代表の山田という二人体制でやってましたが、 組織が大きくなるにつれてだんだんと人数が増えていきました。 現在は僕も山田もフォト蔵からは離れて新しいチームで開発を行っています。

二人体制から始めて、少しずつ人数を増やしていって、 立ち上げメンバーが開発から離れるまでいろいろ経験しながら 自分が感じた事を簡単にまとめたいと思います。

・最終決断は一人で

何をするのか、戦略はどうするのか、方向性は何なのか、最終的な決断はリーダーが一人で行います。 個人の主張を尊重しすぎて、各々が好きな事を始めると体制がめちゃくちゃになります。 2:8の法則は、どんなに優秀な人、やる気のある人を集めても必ず成り立ちます。 最終的なビジョンの部分まで考えて行動できるのはリーダーだけです。

最終決断をリーダーがくださない状態になると以下のような事柄が発生します。

方向性がブレる - 大きなことやるにはチームが一丸となって取り組む必要があるのです が、 一人一人が自分のやりたい事しかやらなくなるので、何がやりたいのかがさっぱり分からなくなります。

全体の事を考えなくなる - サービスは一つの事柄だけとらえてはダメで全体として考え ないといけないのですが、 自分の範囲でしか物事を思考しなくなります。 過去の例としては、 「富豪的に機能を追加・変更する -> サーバ負荷が高くなる -> 誰も異議を唱えない」 「重大な不具合が発生 -> リーダは知らんぷり -> 他の開発者は自分の案件だけ -> 緊急対応にも関わらず対応してるのは担当者だけ」 というのが実際に起こりました。

・リーダーに必要な要素

では、リーダーはどういうことをやればいいのかをまとめてみます。

ビジョナリーである - 企業としてサービスの開発を行うなら大きなビジョンを持ちまし ょう。 小さな前進しか考えられないのであればリーダーの資格はありません。

決断力がある - 大きな事を実現するには大きな決断が必要です。 大きな決断をくだすのは、言うのは簡単ですが実行するのはなかなか難しいです。 失敗を恐れずに実行しましょう。決断をくだすことができる精神力を鍛えましょう。

こだわりを捨てられる - 実際にやってみるとうまく行かない場合がほとんどです。 そういう時に事実を客観的に受け止めて、考え方を変えるのは実はなかなかできません。

技術が分かる - 一流のプログラマである必要はありませんが、 プログラムを書けるようにはなっておきましょう。 技術が分からなければ実現可能性があるかどうかの判断もできません。 どうしても技術が分からないというのであれば、信頼の置ける参謀が必要です。

技術にこだわらない - 技術ができる人に多いのですが、 技術にこだわりすぎる人がいます。 最終目標はサービスの成功であって、高度な技術を活用することではないはずです。 あくまでも技術は目的を実現するための手段であることを心得ましょう。

雑用を積極的に引き受ける - 良いシステムを作るには現場の開発者の力が必要です。 リーダーは積極的に雑用をこなして、開発者が開発に集中できる体制を整えましょう。

開発者の希望をできるだけ尊重する - 開発者がシステムを作る原動力はモチベーション です。 どんなに優秀な人でもモチベーションのある人とない人とでは、 自ずと結果が違ってきます。 最終決断をくだすのはリーダーですが、 その中でもできるだけ開発者の意向を尊重するようにしましょう。

・コア開発者を捕まえる

自社でシステムを作るのですから、コアはしっかりと握っておきたいところです。 できるだけ自社のエンジニアに開発してもらいましょう。 外注するなら協業にしましょう。 いいサービスを作るのにはモチベーションが必要です。 単なる受託開発では真剣にやってもらえないので、協業にして密にやりとりしましょう。最悪なのが外注先のたらい回しです。 システムがどんどん汚くなって収集がつかなくなります。

・無駄なミーティングを増やさない

人数が増えてくるとだんだんミーティングの数が増えてきます。 何も考えずにやってると、いつの間にかミーティングの時間だけが増えて、 一生懸命やってるのに全然進まないという事態に陥ります。 定期的に見直して、ミーティングの数を減らす、効率よく行う努力を怠らないようにしましょう。

・ミーティングに参加する人数を増やさない

人数が増えてくるとミーティングに参加する人数がどんどん増えてきます。 人数が増えてくると時間がかかって議論がまとまらなくなるので全然進まなくなってきます。 細かい単位に分けたり、メリハリをつけるなどして工夫しましょう。

・フルコミットする

片手間でやるのはやめましょう。 受託開発をして日銭稼ぎつつ、 あるいは本業を持ちつつ空いた時間で片手間でサービスの開発を行うのは想像以上に厳しいです。 パートナーが別に仕事持っているならいさぎよく辞めてもらいましょう。 今の仕事を捨てられない程度の覚悟しかないのなら、 最初からやってもらわない方がマシです。

収益の不透明なサービス開発にフルコミットしてもらうのは、 組織的にも資金的にも苦しいと思います。 なんとかしてフルコミットしてもらえる体制作りをしましょう。 それは経営者の仕事であり、リーダーの仕事でもあります。

・まとめ

Webサービスの開発は戦略から要件定義、開発まで全て自分達で行います。 身内だけでやっていると、結果に対する評価がどうしても甘くなってしまって緊張がなくなりがちです。 適度な緊張感とモチベーションを維持しつつ、開発を続けていくにはしっかりとしたチーム作りが必要不可欠です。

2007年6月18日

ベンチャー流Webサービスの作り方(企画編)
このエントリーをブックマークに追加 このエントリーをlivedoorクリップに追加

尾藤正人(a.k.a BTO)です

僕はウノウが株式会社化するタイミングでウノウに参画しました。 それ以来はずっと二年半程Webサービスの開発に従事してきました。 ウノウに参画した当初はWebサービスのことは全く分かっておらず、 単なるLinux好きのエンジニアにすぎませんでした。

ウノウ株式会社の創業時に参画することにより、 サービスの企画から開発、運用まで携わることができました。

最初はエンジニアが自分一人だけだっとところから、 現在のように数多くの優秀なエンジニアを抱える企業に成長するまでの組織作りにも関わることができました。

全く経験のないところから始めたので、それこそいろんな失敗を重ねてきました。 そこで今までの経験を元にベンチャーがWebサービスを開発するにあたって気をつけておいた方がいいことをまとめてみます。

Webサービスの開発を始めるには、何はなくとも企画から。 今回はWebサービスを企画するにあたって気をつけたいことをまとめます。

・自分が思いついたことは他人も同じことを思いついている

人間の想像力はそれほど他人と変わるものではなく、 自分が思いついたアイデアは他の人も同じことを思っている可能性が高いです。 大事なのはそれを実際に形にする行動力。

・行動力

思いついたらまず行動しましょう。 すぐに行動しないと判断がブレます。 行動しないと何も生まれません。 「それ同じこと考えてたんだよね」と後でいうのは完全に言い訳です。

・スピード重視

とにかくスピードを重視しましょう。 遅延はコスト増、成功確率低につながり、いいところはほとんどありません。

・少人数体制

企画は少人数で行いましょう。 人数が多いと「船頭多くして船山に登る」になってしまい、 決定事項も全員の意見をうまくまとめた最小公倍数的なものになってしまいます。 これでは、思い切ったことや、大きなことができません。 相談するのはいいですが、最終的な決断は一人、多くても二人で行うのが理想です。

・ブレストをしよう

単なるアイデア出しは人数が多い方がいいです。 いろんな人と話をしたり、ブレストしたりしていろんなアイデアを出しましょう。

・機能追加は慎重に

Webサービスは気軽に機能拡張することができます。 そのためいろいろ機能を追加しがちですが、 一回追加した機能を外すのは機能を追加するよりも難しいです。 新機能の追加は慎重に行いましょう。 「システムを複雑にするのは簡単だが、簡単にするのは難しい」を肝に銘じておきましょう。

・ユーザの反応は予想と違うと考えよう

ユーザの反応、使い方は企画者側が想像したのと違うと考えておくべきです。 予想通りだったら問題ないですが、 予想通りいかなかった場合にうまく舵取りできるような体制にしておかないといけません。

・ユーザ視点で考えよう

Webサービスはユーザに使ってもらわないと意味がありません。 「ユーザの反応 >>>> 自分のやりたいこと」の図式を頭に叩き込んでおきましょう。 自分のやりたいことを優先させるのは単なる自己満足にすぎません。

・コアユーザは少ないことを認識しよう

熱狂的に使ってくれるようなコアユーザの割合は基本的には少なくて、 せいぜい一割か多くて二割ぐらいです。 アクセスの多くを占めるのは傍観者で、多くの傍観者を生み出すのがコアユーザです。 コアユーザに喜んでもらえるようなサービス作りを心がけましょう。 コアユーザに気に入ってもらわなければサービスは伸びません。

・聞いていい意見といけない意見をしっかり区別しよう

ユーザからの意見はしっかり聞きましょう。 そして聞いていい意見といけない意見をしっかり区別しましょう。 聞いていいかどうかの判断は非常に難しいですが、 コアユーザに喜んでもらえそうな意見を採用しましょう。

サービスを大きくするには広がりが大事です。 他のユーザに影響の与えないような意見は開発コストがかかるだけで、 サービスが大きくなる原動力にはなりえません。

・自分のリテラシーを徹底的に下げる

ユーザは自分達が想像するよりも無知であることを認識しましょう。 「これぐらい分かるだろう」という考えは危険です。 自分のリテラシーを徹底的に下げて物事を考えるようにしましょう。

・方向転換する勇気

サービスを立ち上げた人は自分の考えにこだわりのある人が多いです。 ユーザの反応を見て、想像と違った場合にそれを認めるのは勇気のいることです。 ユーザの反応がよくない場合はそれを素直に認めて方向転換しましょう。

Flickrが最初はMMORPGを開発する会社だったのがうまくいかず、 写真共有サービスとして方向転換して成功したのが顕著な例です。 ここまで大幅な方向転換は稀ですが、小さな方向転換はいろんな場面ででてきます。

・シンプルに

とにかくシンプルにしましょう。 基本的にWebサービスの開発は「企画->開発->ユーザの反応を見る->企画」の繰り返しです。 先に述べたように、追加した機能を外すのはそんなに簡単ではありませんし、 予想と違って方向転換を行う必要がいくつも出てきます。

最初に作り込んでしまうと、 ユーザの反応がよくなかったときに方向転換するのが難しくなります。 できるだけシンプルにしておいて、まずはユーザの反応を見ましょう。 ユーザの反応が良ければ拡張・継続、悪ければやめればいいだけです。

・こだわりを持とう

ユーザの反応を見て素直に認めるのも大事ですが、時にはこだわりも大事です。 周りから大反対されても自分の信念に従って突き進むことも必要です。 iPod登場時のAppleユーザの反応は冷ややかでした。 何がうまく行くかなんてのは誰にも分からないし、 最初からうまくいくことも多くはありません。

・あきらめない

たとえ自分が考えた通りにうまくいかなくても粘りましょう。 どん底の状態でも起死回生は可能です。 あきらめた時点で終わりです。とことんやりましょう。

・愛だよ、愛 by Keita

最終的に大事なのは、そのサービスに対する愛です。 どんなに優秀な人でも、あなたがそのサービスにかける情熱には勝てません。 この熱意がサービスを成長させるためには必要です。

・まとめ

Webサービスを開発するにあたって企画の部分で気をつけないといけないことをまとめてみました。 人それぞれ考え方は違うとは思いますが、僕なりに経験を重ねいろいろ考えた上で現在の結論に至っています。 今後自分でWebサービスを開発したい方の参考になれば幸いです。