IPv6 Access Checker @yadiary.net You accessed over SSL connection.


システムの背景

この郵便番号検索システムの構築は、郵便番号を検索するシステムが必要だったわけではなく、CouchDBのフロントエンドアプリケーションを構築する事が目的でした。

さらに郵便番号を選択した理由は、配布されている郵便番号CSVファイルは随時アップデートされる実データで、再利用について制限がないからです。

またCouchDBに格納されたデータのプレゼンテーションだけでなく、外部アプリケーションがJSON形式でデータを取り出すことができるデータベースとしても機能するように設計されています。

これはデータがHTML文に組込まれているプレゼンテーションレイヤーの情報は再利用が難しいと感じていたため、 データの再利用に焦点を当てたアプリケーションを構築してみたいという考えがあったためです。

アプリケーション自体は、Ruby用CouchDBライブラリであるYALToolsを使ったショーケースとしての役割も担っていて、アプリケーションの開発に利用することでYALToolsにあった、いくつかのバグを発見・修正することができました。

郵便番号検索システムの構造

バックエンドDBはCouchDBを使い、フロントエンドにはApache + FastCGIを配置されています。 これはCouchAppのようにCouchDBがWebサーバの役割を担う構成とは異っています。

System Overview Diagram

このFastCGIはRubyスクリプトで記述され、ライブラリとしてYALToolsを使用しています。

YALTools libraryとPostal Code Search System Packageの役割分担

YALToolsは別途開発しているCouchDBへの接続環境を管理するためのライブラリとDBメンテナンス用のコマンド群です。

YaPostalライブラリは、アプリケーション本体で主にFastCGIスクリプトを中心とした外部クライアントとのインタフェースを管理しています。 CouchDBとのトランザクションはYALToolsにより、詳細はブラックボックスとしてカプセル化し、YaPostalライブラリからはView名とページ番号によりデータベースの一部にアクセスしています。

FastCGIスクリプトを含む、アプリケーション本体

FastCGIスクリプト本体はライブラリパスの設定と実行に必要な設定ファイルを示すための最小限の機能だけを持ち、 YaPostal::ControllerクラスがQUERY_STRINGのパース、Viewの選択を行ない、YaPostal::Renderクラスがそのデータを元に画面出力を生成します。

#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-

Rev = "1.6"
app_uri = "postal"
basedir = "/app/lib/#{app_uri}/#{Rev}"
confdir = "/app/data/#{app_uri}/#{Rev}"
$:.unshift "#{basedir}/lib"

ENV['GEM_HOME'] = "#{basedir}/gems"
require 'rubygems'
require 'fcgi'
require 'cgi'
require 'yapostal'

FCGI.each {|request|
 Thread.current[:current_request] = nil

  out = request.out
  main = YaPostal::Controller.new(confdir, request)
  
  out.print main.run
  
  request.finish
}

今回のアプリケーションは検索がメインの単純な構造なので画面遷移は基本的にありませんが、 "mode"パラメータによりHTML出力とJSON出力の処理を振り分けています。

YaPostal Class Diagram

FastCGIからみるとYALToolsのクラスはMVCモデルでいうところの、Modelに相当する役割を担いますが、その他にもCouchDBへの接続を担うオブジェクトやYALToolsに含まれるスクリプト群を利用して郵便番号データベースの初期化、差分データを利用した更新処理などのメンテナンスを行なっています。

入力をサポートするFlexBoxとサポートFastCGIアプリケーション

都道府県名、市区郡名、町村名の3つの欄は、入力補完をサポートするためにFlexBox jQueryプラグインを利用しています。

下の図では入力された県名に対応する市、郡名がリストに表示されて、対象が59個ある事がFlexBoxによって示されています。

FlexBoxが入力された福島県に対応する市区郡名を表示している様子

動的な入力補完を実現するために、3つのFastCGI(pref.fcgi, city.fcgi, street.fcgi)が含まれていて、FlexBox自体にも手を加えてクエリに対する補完情報を加える事ができるように'k','j'の2つのパラメータを取るようにしています。

FlexBoxの拡張内容や、使用するリクエストの内容については、ブログ記事 http://yasu-2.blogspot.com/2010/12/flexboxquery.htmlを参照してください。

稼働環境

このアプリケーションは、ほぼこのサイトで公開している現行の郵便番号検索システムと同一です。

VMWareを利用して以下のような環境での稼働を確認しています。

ダウンロード

配布用に、無駄に複雑な構成が必要な一部機能を削除したバージョンを作成しました。 将来的には変更をマージして、全体の配布ができる事を目指します。

Download from sf.net → http://sourceforge.net/projects/lscouchdb/files/postal-code-searcher.20110403.tar.bz2/download

GitHut経由での最新版のダウンロード

最低限の稼働確認を行なった最新版はGitHubから入手可能です。

$ git clone git://github.com/YasuhiroABE/postal-code-searcher.git

含まれているソフトウェアとライセンス

このアーカイブに含まれているソフトウェアと、対象となるライセンスは次の通りです。

FlexBox用のパッチは jquery.flexbox.1.5.js.diff の名前で、このアーカイブに含まれています。 この部分のライセンスはオリジナルのFlexBoxのライセンスに準じます。

この他の私(Yasuhiro ABE, yasu@yasundial.org)が作成したコードは、特別な表記がない限りApache License 2.0に準じます。

インストール

インストール場所としては、/app直下を想定しています。

$ sudo mkdir /app
$ sudo tar xjf ~/postal-code-searcher.20110403.tar.bz2
$ mv postal-code-searcher/* .

セットアップ

対象はUbuntu 10.04 LTSですが、CentOS5でも動く事は確認しています。 追加の設定内容や修正個所については、centos5.htmlを参照してください。

CouchDB 1.0.2のインストール

コンパイルするか、手間を省くためにcouchbase 1.1を導入する事もできます。

Ruby 1.9.2のインストール

Ruby 1.9.2を使う場合には、fcgiなどこの手順で解説している一部を除いて追加のモジュールの導入は不要です。 ただしopensslが使えるように、libssl-devパッケージの導入を行なってください。

全スクリプトは /usr/local/bin/ruby を実行するように設定されています。

もしPPAなどを利用して、この他の場所に導入している場合には、/app/lib/postal/1.6/sbin/change_ruby_command_name.sh を使うか、手動でスクリプト先頭の #!/usr/local/bin/ruby を書き換える必要があります。

change_ruby_command_name.shの使い方は引数なしで実行してヘルプをみるか、次のように引数に正しいrubyコマンドの場所を指定して実行します。

$ /app/lib/postal/1.6/sbin/change_ruby_command_name.sh /usr/bin/ruby1.9

CouchDB接続情報の設定

最初にCouchDBに接続するための設定ファイルの内容を適切に変更してください。

databaseの名前を"postal2"から変更する必要がなければ、/app/data/postal/1.6/yapostal.yaml の変更は必要ないと思います。 もし"postal2"から別の名前に変更した場合は、yapostal.yamlの内容を変更して、この手順中の"postal2"を新しい名前に読み替えてください。

/app/lib/postal/1.6/utils/conf/yalt.yaml

データの初期化に使用するYALTools用の設定ファイルです。接続に使用するIDは少なくともdatabase admin権限を使用してください。

/app/data/postal/1.6/yalt.yaml

FastCGIスクリプトが接続に使用するIDです。これはreader権限に設定するのがお勧めです。

/app/data/postal/1.6/yapostal.yaml

このファイルは変更する必要がないかもしれません。

デフォルトは次のようになっていて、郵便番号データを格納するデータベース名を指定してください。

---
label_name: "default.user"
database: "postal2"

FastCGI環境の設定 Apache編

Apacheを使う場合には、mod_fcgidモジュールが必要です。

Ubuntu 10.04 LTSでApacheが稼働している場合には、"libapache2-mod-fcgid"を追加で導入します。 導入後は自動的にmod_fcgidが読み込まれる($ sudo a2enmod fcgid)はずです。

事前に適当な apache2-mpm-* (apache2-mpm-worker or apache2-mpm-prefork) をインストールしておいてください。

$ sudo apt-get install libapache2-mod-fcgid

あとは通常のCGIを有効にするのと同じ手順です。 Ubuntu 10.04 LTSであれば、"/etc/apache2/sites-enabled/000-default"に次のようなディレクティブを加えます。

    Alias /postal/ "/app/contents/postal/"
    <Directory "/app/contents/postal">
        Options +ExecCGI
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>

このDeny/Allow ディレクティブの設定は保守的にしています。 実際に動かす環境に合わせて適切に設定してください。

FastCGI環境の設定 Ruby編

Ubuntu 10.04の場合は事前に $ sudo apt-get install libfcgi-dev によりFastCGIライブラリが導入されている必要があります。

Ruby用にfcgiモジュールを導入します。これはコンパイラを使用するためにUbuntuであれば事前に $ sudo apt-get install build-essential などによりgccが導入されている必要があります。

$ gem install -i /app/lib/postal/1.6/gems/ fcgi

もし ruby-1.9.2 をPPA経由で導入した場合、バージョンが古いためにgemが同梱されていない可能性があります。 手動でfcgi-0.8.8をコンパイル ($ ruby setup.rb) して、手で fcgi.so と fcgi.rb を /app/lib/postal/1.6/lib 直下にコピーしてください。

DataBaseの初期化

まず2011/02/28時点での郵便番号データを登録します。

既にデータ格納用の postal2 を作成済みであれば、2行目は必要ありません。

$ cd /app/lib/postal/1.6/sbin
$ ../utils/sbin/mkdb postal2
$ ./postalcsv2json.rb ../data/ken_all.201102.utf-8.csv | ../utils/bin/postdocs postal2

更新データの登録

毎月末になると、更新分のデータが日本郵便から公開されます。 現時点では2011/Mar./31付けで公開されているデータがあるので、この更新方法について載せておきます。

更新手順は、データをUTF-8に変換した上で、”廃止データ”を削除し、次に”新規追加データ”を登録する流れになります。2011/Mar./31付けのデータでは廃止データが空なので、必要ないですが、手順だけ載せておきます。

$ cd /app/lib/postal/1.6/sbin
$ ./postalcsv2json.rb ../data/DEL_1103.utf-8.CSV | ../utils/bin/chjson '["_deleted",true]' | ../utils/bin/postdocs postal2
$ cd /app/lib/postal/1.6/sbin
$ ./postalcsv2json.rb ../data/ADD_1103.utf-8.CSV | ../utils/bin/postdocs postal2

廃止データのJSONには "_deleted":true を追加した上で更新処理をしているため、CouchDBのBulk APIによってデータが削除されます。

新規登録データの登録は最初の初期化作業とまったく同じです。

View定義の登録

次にアプリケーションで検索に利用するView定義を登録します。

$ cd /app/lib/postal/1.6/utils
$ bin/csv2json csv/view_defs.all.csv  | bin/putdesign postal2 all

最初のViewの初期化にはCore2DuoやPhenomII X4といった2, 3GHzのCPUを使って少なくとも数分かかると思います。 Viewを初期化するために、Viewを参照します。

$ bin/lsviews postal2 all pref -g
$

Viewの更新が終るまでは、何も表示されません。 更新が終ると、正しく出力されるはずです。

$ bin/lsviews postal2 all pref -g
{"key":"三重県","value":2473}
...

稼働確認

Webブラウザを使用して次のようなURLを開きます。

http://localhost/postal/main.fcgi

Apacheの設定によって、追加で設定が必要になるかもしれません。 うまく表示されない場合には、エラーログファイルをみて対応してください。

Created: 2010-12-04, Last modified: 2011-04-03

Copyright © 2010-2012 Yasuhiro ABE <yasu@yasundial.org>

Valid XHTML + RDFa 正当なCSSです!
RDFa it (RDF/XML)!