Asial Blog

Recruit! Asialで一緒に働きませんか?

バックエンド(インフラ)の一覧

MySQLのクライアントエンコーディング

カテゴリ :
バックエンド(インフラ)
タグ :
icon
森川です。

前回はマルチバイト関連でしたが、今回もマルチバイトです。前回ソースを解析するなどと言ってしまいましたが、中々難しくまだ途中です。決してあきらめたわけではないので、もう少しすればここに書けるようになると思います。

さて、今回はMySQLの文字コードについてです。4.1から文字コードの設定が色々と増えたので、設定をきちんとしていなくて問題が起きることも多かったのではないでしょうか。まずは簡単におさらいです。

CentOS4.4のパッケージを使用している場合はデフォルトの文字コードは以下のようになります。

apacheのアクセスログ

カテゴリ :
バックエンド(インフラ)
タグ :
icon
こんばんは、牧野です。
今回はアルゴリズムの話は置いておき、apacheの話題です。

先日、あるサイトのapacheのアクセスログを調べていて気付いたのですが、

リクエストがタイムアウトしてしまい、クライアントがデータを受信できなかった時でも
アクセスログにはリクエストのあった時間のログが残ってしまうんですね。。
ステータスコード200で。。。

これは、携帯でアクセスできるウェブサーバがあれば簡単に確認することができます。
(携帯の方がタイムアウトするまでの時間が短いので)

次のようなプログラムをサーバに置いて、

  1. <?php
  2. sleep(70);
  3. echo 'Hello!';
  4. ?>

あとはアクセスログを見ながらこのプログラムに携帯からアクセスするだけです。
すると、、、

通信開始

70秒経過前に端末側ではタイムアウトメッセージ

70秒後に、ステータスコードが200で、リクエストが合った時刻のログが書き込まれる

実際にどんなデータがやりとりされているかを見るには、Linuxなら
tcpdump
コマンドが使えます。

/usr/sbin/tcpdump -n 'port 80'
という感じで実行すると80番ポート流れるパケットの概要を見ることができます。
今回はポートだけを指定していますが、もっといろんなマッチング条件を指定することも可能です。

これを実行して改めてアクセスしてみると、

  1. 19:25:25.289060 210.136.161.151.44924 > 192.168.1.207.http: S 1392407767:1392407767(0) win 32768  1460,wscale 0,nop> (DF)
  2. 19:25:25.289093 192.168.1.207.http > 210.136.161.151.44924: S 573743362:573743362(0) ack 1392407768 win 5840  1460,nop,wscale 0> (DF)
  3. 19:25:25.292958 210.136.161.151.44924 > 192.168.1.207.http: P 1:123(122) ack 1 win 32768 (DF)
  4. 19:25:25.293023 192.168.1.207.http > 210.136.161.151.44924: . ack 123 win 5840 (DF)
  5. 19:26:17.095988 210.136.161.151.44924 > 192.168.1.207.http: F 123:123(0) ack 1 win 32768 (DF)
  6. 19:26:17.129320 192.168.1.207.http > 210.136.161.151.44924: . ack 124 win 5840 (DF)
  7. 19:26:35.290859 192.168.1.207.http > 210.136.161.151.44924: P 1:265(264) ack 124 win 5840 (DF)
  8. 19:26:35.290974 192.168.1.207.http > 210.136.161.151.44924: F 265:265(0) ack 124 win 5840 (DF)
  9. 19:26:35.294709 210.136.161.151.44924 > 192.168.1.207.http: R 1392407891:1392407909(18) win 0 (DF)
  10. 19:26:35.294711 210.136.161.151.44924 > 192.168.1.207.http: R 1392407891:1392407909(18) win 0 (DF)

最初ウェブサーバにパケットが飛んで、
ウェブサーバが返信
クライアント(docomoゲートウェイサーバ)がヘッダー情報送信
ウェブサーバ受け取り

ここでプログラムはsleep()。

クライアント(docomoゲートウェイサーバ)がタイムアウトして、コネクション切断リクエスト
ウェブサーバが返信
でも、ウェブサーバはデータ送信して、
続けてコネクション切断リクエスト送信
docomoゲートウェイサーバが返信
docomoゲートウェイサーバが2回接続終了リクエスト

となっているようです。(違ってたら教えていただけると助かります。)

やはり、apacheはコネクション切断リクエストを受け取った後でもかまわずレスポンスを返して、ステータスコード200が記録されているってことかな。
ちなみに、tcpdump実行時に -X オプションを追加すると、パケットデータが文字列で表示されるのですが、ネットワークを流れるデータを簡単に覗けることが実感できます。。

話をアクセスログに戻しますが、apacheの設定でログのフォーマットを変えることで、タイムアウトしたアクセスを判別できるようにすることが可能です。
例えば、httpd.confを

  1. LogFormat "%h %l %u %t \"%r\" %>s %b" common
  2. →LogFormat "%h %l %u %t \"%r\" %>s %b %D %X" common
  3. CustomLog logs/access_log combined
のように、LogFormatに%Dや%Xを加えておくと、タイムアウトのアクセス判別の参考に使えそうです。
(参考ページ)
http://httpd.apache.org/docs/2.2/ja/mod/mod_log_config.html

%Dはリクエストの処理にかかった時間(マイクロ秒)、%Xは応答が完了したときの接続ステータスを表します。
他にもいろんな出力が可能なので、必要に応じてカスタマイズしてはいかがでしょうか。

coLinux 0.8.0でカーネルを再構築してsshfsを使う

カテゴリ :
バックエンド(インフラ)
タグ :
kernel.png
こんにちは、スパイシーチキン担当の熊谷です。

先週のことになりますが、いつものようにお昼ご飯でスパイシーチキンを注文したところ売り切れですと言われてしまった日がありました。何十回とスパイシーチキンを注文してきて初めて「売り切れ」に遭遇ですよ!売り切れる事なんてないと思っていただけに、その日はショックを受けてしまいました。スパイシーチキンの人気が上がってきたのでしょうか。

さて、今回も前回に引き続きcoLinuxネタで攻めたいと思います。SSHを通して開発サーバにアクセスしそこでエディタ等を使ってコードを書くというサーバ環境での開発、または、自分用にカスタマイズし何をするにもとても使いやすくなっている自分のマシン上で開発を行うローカル環境での開発の大きく分けて二通りあると思います。

私の場合、前回も述べましたがメイン環境は今のところWindowsで、そのマシン上で開発を行っています。SSHクライアントソフトであるputtyを通してなんだかんだするのはもちろんなんですが、メイン環境がWindowsということもあって、coLinuxや開発サーバにsambaをインストールしWindowsのファイル共有機能を使ってなんだかんだすることもあります。しかしこの場合、ローカルネットワーク内ならこれで不便は感じないのですが、ローカルネットワーク外にあるファイルを操作したい場合問題があります。scp等を使ってファイルをやりとりすればいいだけのことですが、せっかくWindowsを使っているというかGUIの環境なんですから、ローカルネットワーク内と同じようにエクスプローラ等を使ってファイルを操作したいという欲求が出てきます。

そんな問題を解決するのが、sshfsです。これを使うとSSHを通してネットワーク先にあるマシンのファイルシステムをマウントしてくれます。マウントさえしてしまえばあとはsambaを使ってファイル共有の設定をするだけで、Windowsからはローカルネットワーク内での操作と同じ感覚でファイル操作を行うことが出来ます。

このsshfsを使うにはFUSEモジュールが必要になります。Linuxの場合はカーネル2.6.14でカーネルにマージされたので、簡単な方法はカーネルをそれ以上に上げてfuseを使えるようにしてしまえばいいということになります。前回インストールに使ったcoLinuxは0.7.1なんですが、このカーネルは2.6.12ということでFUSEがサポートされていません。パッチ等を当てれば出来るわけですが、開発者たるもの人柱になるべきということで開発版である0.8.0にアップデートしましょう。こちらのカーネルは2.6.17なのでFUSEはもちろんサポートされているので、coLinux用にカーネルをコンパイル、再構築します!

では、早速取りかかりましょう。

まずはcoLinux 0.8.0本体とそのソースをダウンロードです。今回は以下のURLからダウンロードしました。
http://www.henrynestler.com/colinux/testing/devel-0.8.0/20070412-gcc412/

ここにあるdevel-coLinux-20070412-gcc412.exeが本体でdevel-colinux-20070412-gcc412.tar.gzがソースになります。前回は0.7.0を使っていたので、それをアンインストールしてから0.8.0をインストールします。

あとはcoLinux上での作業です。

今実行しているcoLinuxのソースをダウンロードし展開します。
  1. mkdir colinux
  2. wget http://www.henrynestler.com/colinux/testing/devel-0.8.0/20070412-gcc412/devel-colinux-20070412-gcc412.tar.gz
  3. tar xvfz devel-colinux-20070412-gcc412.tar.gz
次にlinuxのカーネル2.6.17を近くのミラーサーバからダウンロードします。例えば以下のように。
  1. wget http://ring.asahi-net.or.jp/pub/linux/kernel.org/kernel/v2.6/linux-2.6.17.tar.bz2

ダウンロードしたら展開して先ほどダウンロードしたcoLinuxのパッチをカーネルソースに当てます。
  1. tar xvfj linux-2.6.17.tar.bz2
  2. ln -s linux-2.6.17 linux
  3. cd linux
  4. patch -p1 < ../devel-colinux-20070412-gcc412/patch/gdt-noalloc-2.6.17.diff
  5. patch -p1 < ../devel-colinux-20070412-gcc412/patch/base-2.6.17.diff
  6. patch -p1 < ../devel-colinux-20070412-gcc412/patch/timer-2.6.17.diff
  7. patch -p1 < ../devel-colinux-20070412-gcc412/patch/coconsole-2.6.17.diff
  8. patch -p1 < ../devel-colinux-20070412-gcc412/patch/serial-core.diff
  9. patch -p1 < ../devel-colinux-20070412-gcc412/patch/serial-2.6.17.diff
  10. patch -p1 < ../devel-colinux-20070412-gcc412/patch/conet-2.6.17.diff
  11. patch -p1 < ../devel-colinux-20070412-gcc412/patch/cobd-2.6.17.diff
  12. patch -p1 < ../devel-colinux-20070412-gcc412/patch/kbd-2.6.17.diff
  13. patch -p1 < ../devel-colinux-20070412-gcc412/patch/mouse-2.6.17.diff
  14. patch -p1 < ../devel-colinux-20070412-gcc412/patch/cofs-core.diff
  15. patch -p1 < ../devel-colinux-20070412-gcc412/patch/cofs-2.6.17.diff
  16. patch -p1 < ../devel-colinux-20070412-gcc412/patch/cloop-core.diff
  17. patch -p1 < ../devel-colinux-20070412-gcc412/patch/cloop-2.6.17.diff

次にcoLinux用のカーネルの設定をコピーします。
  1. cp ../devel-colinux-20070412-gcc412/conf/linux-2.6.17-config .config
FUSEモジュールを使うようにこの設定ファイル.configを編集します。
  1. # CONFIG_FUSE_FS is not set
上記のように記述されている部分を下記のように変更します。
  1. CONFIG_FUSE_FS=m
または、
  1. make menuconfig

で、「File systems」の項目の「Filesystem in Userspace support」を「m」にします。次にMakefileに記述されているEXTRAVERSIONの部分を下記のように変更します。
  1. EXTRAVERSION = -co-0.8.0
これであとはカーネルをコンパイルしモジュールを作成しモジュールをインストールします。
  1. make vmlinux
  2. make modules
  3. make modules_install
これでFUSEモジュールを使う準備が整いましたので
  1. modprobe fuse
するなり
/etc/modulesにfuseを追加するなり場合によっては再起動するなりしてください。

あとはsshfsをインストールします。
  1. apt-get install sshfs
おめでとうございます!これで完了です。下記のようなコマンドを打つと、
  1. sshfs hoge_user@hoge_server: /mnt
/mntにhoge_serverのhoge_userのホームディレクトリがマウントされます。
ただこのままの状態だとsambaを経由してアクセスできないので、/etc/fuse.confに
  1. user_allow_other
と記述し下記のようなコマンドでマウントすることにより
  1. sshfs -o allow_root hoge_user@hoge_server: /mnt
samba経由でアクセスすることが可能になります。あ、もちろんsambaの設定/etc/smb.confでこのディレクトリを共有するのを忘れずに!

coLinuxでDebian etchを使う

カテゴリ :
バックエンド(インフラ)
タグ :
colinux01s.png
こんにちは、スパイシーチキン担当の熊谷です。

ついに技術ブログを書けというお達しが出てしまいまして、お昼ご飯というかスパイシーチキンの登場を期待していた多くの方にとってちょっと寂しい思いをさせてしまいますが、スパイシーチキン担当としてこれからも隙を見てスパイシーチキンネタを書きたいと思いますので、期待してください。

そんなことで、今回は開発環境について書きたいと思います。弊社では、以前は共有の開発用サーバがありそこに繋いで開発を行っていたのですが、現在、基本的に一人一台の開発用PCが支給されています。その開発用PCにそれぞれLinuxをインストールし開発を行っています。Linuxのディストリビューションは好きなものを選んで良いことになっていますが、一応弊社の基本はCentOSのようです。で、私はというともちろんDebianです。昔々はRPM系のディストリビューションを使っていたのですが、Debianのパッケージ管理システムや操作性になれてしまうともう戻れなくなります。

ということで開発用PCにはDebian etchをインストールして、私のメイン環境であるThinkPad X40からSSHを通して開発しています。が、しかし。実はメイン環境であるThinkPad X40にはcoLinuxをインストールしていてそこで開発ということもしています。ネットワークが繋がっていれば会社から支給されているマシンにアクセスして開発ということで問題ないのですが、繋がっていない場合等を考えるとローカルで作業したいという気持ちもあるからです。


coLinuxでも同じようにDebian etchを使いたい!

そんな思いを実現するには・・・、方法はいろいろあります。coLinuxのサイトで配布されているsargeからdist-updateでetchにアップデートする方法やqemuを使用してディスクイメージを作成する方法等々。で、私はというと、coLinuxでスクラッチからインストールして使っています。

その方法ですが、まずcoLinuxをダウンロードしてインストールします。現在バージョン0.8.0と0.7.1があるのですが、私は0.7.1を使っています。インストールでは使用するディスクイメージを選ぶことが出来るのですが、自分でスクラッチから作るので選択しません。また、ネットワークドライバについてはTAPを使ってWindows XPでNATの設定をしています。

次にDebianのサイトからetchのインストールCDをダウンロードします。Debianの場合インターネットに繋がる環境があれば完全なCDセットは必要ないので、netinst CDイメージか名刺サイズのCDイメージで十分です。

そしてこのCDイメージからinitrd.gzを取り出します。DAEMON ToolsでマウントするかLinuxでマウントするかして取り出してください。取り出したinitrd.gzをinstaller-initrd.gzへファイル名を変更してcoLinuxのディレクトリにコピーします。

次に、ディスクイメージの作成です。コマンドプロンプトでcoLinuxをインストールしたディレクトリ内で
  1. fsutil file createnew rootfs_3gb.img 3221257728
  2. fsutil file createnew swap_192mb.img 201358848
上記例では3GB用のディスクイメージと192mb用のスワップイメージを作成しています。

次に、etchをインストールするための設定ファイル(installer.conf)はcoLinuxをc:\coLinuxにインストールしたとして、
  1. kernel=vmlinux
  2. cobd0=c:\coLinux\rootfs_3gb.img
  3. cobd1=c:\coLinux\swap_192mb.img
  4. cobd2=c:\coLinux\debian-testing-i386-businesscard.iso
  5. cofs0=c:\coLinux
  6. root=/dev/ram0 vga=normal ramdisk_size=14409 rw --
  7. initrd=installer-initrd.gz
  8. mem=128
  9. eth0=tuntap,"TAP"
になります。この設定ファイルをつかってcoLinuxを起動します。
  1. colinux-daemon.exe @installer.conf -t nt
すると文字化けしていますが、etchのインストーラーの画面が表示されます。

このChoose languageでは言語を選ぶわけですが、日本語が化けるのでEnglishを選択し、次の画面ではotherを選択でJapanを選択します。

次にSelect a keyboard layout画面になりますが、ここでAlt+F2を押して画面を切り替えEnterを押してコンソールにします。

インストーラはcoLinux上でのインストールというのは基本的にサポートしていないので、必要な諸設定をこのコンソール上で行います。
  1. mkdir -p /mnt/modules
  2. mount -t cofs cofs0 /mnt/modules
  3. tar -zxvf /mnt/modules/vmlinux-modules.tar.gz
  4. mknod /dev/cobd0 b 117 0
  5. mknod /dev/cobd1 b 117 1
  6. mknod /dev/cobd2 b 117 2
  7. mkdir /target
上記コマンドを実行したら、Alt+F1を押してコンソールを切り替えセットアップ画面に戻ります。

で、セットアップの続きをします。Select a keyboard layoutではJapaneseを選択します。すると今度はDetect and mount CD-ROMの画面になります。

CD-ROMのドライバーをフロッピーから読むかという選択なのでNoを選び、
CD-ROMを手動で設定するのでYesを選び、noneを選択します。そうすると、今度は以下のような画面になります。

ここではCD-ROMデバイスの場所を入力するので、
  1. /dev/cobd2
と入力します。

するとLoad installer components from CDという画面になるのでカーネルモジュールを読み込まずにインストールするか聞いてくるので、Yesを選択します。


そしてしばらく待っていると、DHCPを使ったautoconfigurationが失敗して、Configure the networkの画面でContinue待ちになるのでContinueを選択して、Configure the networkの画面でConfigure network manuallyを選択します。ここではネットワークの設定になるので自分の環境の設定を入力します。私の場合、TAPには192.168.40.1というIPアドレスを設定しています。ということで、

IP addressは、
  1. 192.168.40.2
Netmaskは、
  1. 255.255.255.0
Gatewayは、
  1. 192.168.40.1
Nameserverは、
  1. 192.168.40.1
Hostnameはお好きに。Domain nameもお好きに。という感じになります。

このネットワークの設定が終わるとDebian archiveのミラーを選択する画面になるのですが、その画面になったらAlt+F2を押してコンソールを切り替えます。

このコンソール画面でディスクイメージを初期化してマウントしてベースシステムをインストールします。
  1. mke2fs -j /dev/cobd0
  2. mount /dev/cobd0 /target
  3. mkswap /dev/cobd1
  4. sync;sync;sync;
  5. swapon /dev/cobd1
  6. mkdir -p /target/dev
  7. mknod /target/dev/cobd0 b 117 0
  8. mknod /target/dev/cobd1 b 117 1
  9. mknod /target/dev/cobd2 b 117 2
  10. cd /target
  11. debootstrap --arch i386 etch /target http://ring.ocn.ad.jp/archives/linux/debian/debian
ベースシステムをインストールしたら、次にfstabの設定をします。
  1. cat < > /target/etc/fstab
  2. /dev/cobd/0 /     ext3 defaults 1 1
  3. /dev/cobd/1 swap  swap defaults 0 0
  4. proc        /proc proc defaults 0 0
  5. EOF

次にNICの設定です。
  1. cat < >> /target/etc/network/interfaces
  2. auto lo
  3. iface lo inet loopback
  4. auto eth0
  5. iface eth0 inet static
  6.   address 192.168.40.2
  7.   netmask 255.255.255.0
  8.   gateway 192.168.40.1
  9. EOF

hostsを作成します。
  1. cat < >> /etc/hosts
  2. 127.0.0.1      localhost
  3. EOF

これでインストールは一応完了です。Alt+F1を押してインストーラに戻ってGo Backを選択してmein menuに戻りAbort the installationでインストーラを終了します。

あとはcoLinuxの設定ファイルを通常起動用に変更します。rootfs_3gb.imgをrootデバイスにして、initrdをcoLinuxのデフォルトに戻します。
  1. kernel=vmlinux
  2. cobd0=c:\coLinux\rootfs_3gb.img
  3. cobd1=c:\coLinux\swap_192mb.img
  4. cofs0=c:\coLinux
  5. root=/dev/cobd0
  6. initrd=initrd.gz
  7. mem=128
  8. eth0=tuntap,"TAP"
お疲れ様です!これで完了です。この設定ファイルでcoLinuxを起動するとよけいなものが一切インストールされていないDebian etchが起動します。

本当に最小限のことしかやっていないので、設定等必要なことがありますがあとは好みで行ってください!

ちなみに、タイムゾーンの設定や
  1. tzconfig
shadowパスワードの有効や、
  1. shadowconfig on
パスワードの設定や、
  1. passwd
ユーザの追加や、
  1. adduser ユーザ名
キーボードのインストール・設定や、
  1. apt-get install console-common
ローケルのインストール・設定等。
  1. apt-get install locales
  2. dpkg-reconfigure locale
これらははじめにやっておきましょう。