※ パクレゼルヴではWeb開発エンジニアを大募集中!詳細はこちら

Archive

Archive for the ‘Apache’ Category

mod_rewriteでGETパラメータ名を変更する  

2010/4/16 金曜日 20:22:56

mod_rewriteのお話

旧システムから新システムの以降など、システムの仕様が変わる時でも古いURLを引き継ぎたい場合に役に立つ小技です。

問題1

GETパラメータの名前aaaをbbbに変更したい場合はどのようにすれば良いか?

ついつい以下のように設定してしまうかと思いますが、うまく動きません。

RewriteRule filename.html\?aaa=(.*) filename.html?bbb=$1 [L]

RewriteCondを使い、QUERY_STRINGの条件を指定すると、うまく動きます。

RewriteCond %{QUERY_STRING}     aaa=(.+)
RewriteRule filename.html filename.html?bbb=%1 [L]

%1で、RewriteCondでマッチしたパターンを取得できる。

問題2

GETパラメータの名前aaaをbbbに変更したいが、aaa以外のパラメータはそのまま残したい場合はどのようにすれば良いか?

解答1

QSAをつける。

RewriteCond %{QUERY_STRING}     aaa=(.+)
RewriteRule filename.html filename.html?bbb=%1 [L,QSA]

解答2

以下の場合、aaaのみbbbに書き換える事ができる。

RewriteCond %{QUERY_STRING}     ^(.*)aaa=(.+)$
RewriteRule filename.html filename.html?%1bbb=%2 [L]

オマケ

『上記試してみましたが、うまく動きません!』という場合

上から順に評価されるので、こんな事しているとうまく動かない。

#ファイルが存在する場合はそれを表示する
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.* - [L]
# ↑ファイルが存在した時点で、上記が評価されて終わってしまう。

#パラメータ名を書き換える。
RewriteCond %{QUERY_STRING}     ^(.*)aaa=(.+)$
RewriteRule filename.html filename.html?%1bbb=%2 [L]

順番を変更する事でうまく動く。

#パラメータ名を書き換える。
RewriteCond %{QUERY_STRING}     ^(.*)aaa=(.+)$
RewriteRule filename.html filename.html?%1bbb=%2 [L]
#↑先に評価される。

#ファイルが存在する場合はそれを表示する
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.* - [L]

そんな感じで、お役に立てれば幸いです。

マカー Apache, Tips

存在するファイルはスルーしたい(mod_rewrite)  

2009/2/7 土曜日 17:21:05

mod_rewriteのお話。
ファイルが存在する場合はそのファイルを表示し、存在しない場合はindex.phpを表示するようにしたい。
よくある例が以下のようになっているるのですが、実際にはうまく動かないことがあります。

RewriteEngine on
RewriteBase /
# ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ /index.php [L,QSA]
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

以下のように書くと期待通りに動作します。

RewriteEngine on
RewriteBase /
# ファイルが存在するか、ディレクトリが存在する場合は、そのファイルを表示する
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.* - [L]
# ファイルが存在しない且つ、ディレクトリが存在しない場合は、index.phpを表示
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^$ /index.php [L,QSA]
RewriteRule ^(.*)$ /index.php?jb=$1 [L,QSA]

これで目的は達成されるのですが、最初の例でなぜうまくいかないのか納得できないのです。
この挙動について説明できる方がおられれば、ご教授いただけると幸いです。

マカー Apache, Tips

海外からのアクセスを防ぐ  

2008/11/27 木曜日 15:45:09

海外からのアクセスを防ぐ。
そんなお困りな方は、.htaccessで大体のことはできます(サーバが.htaccessに対応している必要がありますが・・)。

order deny,allow
deny from all
allow from .jp

とすれば、jpドメイン以外からのアクセスを防ぐことはできます。
しかし、これだけでは、apacheの設定具合等によっては普通にアクセスできてしまう場合があるので、IPで直接制限をかけた方が良いかなと。

JPNICが管理しているIPアドレスは以下から確認できるので、それのみアクセスできるようにすれば、一応国内からのみアクセスということができます。
http://www.nic.ad.jp/ja/dns/jp-addr-block.html

設定方法としては以下。

order allow,deny
allow from all
deny from 210.128.0.0/11
deny from 221.16.0.0/12
 ・
 ・

.htaccessサンプル(一応2008/11/27付のデータで作成)

ずらっと、大量に記述する必要がありますが、こんなに多量にあってもIPv4はもう喝々で、更に桁数の増えるIPv6にそのうち移行するとか言う話も出てきていたりします。
そんな感じ。

下音タヌキ Apache, Tips

アクセスログ  

2008/8/25 月曜日 11:27:10

はいどうも
のびーにょです

表題のとおりなんですけど、皆さんアクセスログってどう処理してます?

僕の場合はシステム側でDBに取るようにしてます。

オーバーヘッドとか色々考えなきゃだめな部分ありますけど、割と便利です。

まず、Apacheの標準のアクセスログだとPOSTの値がとれません。

※こんな方法もあったりしますが
http://neta.ywcafe.net/000607.html

で、僕はアクセスすべてをDBに保存しています。
レコード数が多くなりすぎたりすると処理に時間がかかってしまいますので月別、週別でアーカイブしていったり、場合によっては日別でテーブルを分けるなどの処理が必要ですが・・・
以下bash

#!/bin/bash
mysql -uユーザ名 -pパスワード rutty_test -hホスト << EOT
ALTER TABLE access_log RENAME AS access_log_`date +%Y_%m_%d`;
CREATE TABLE \\`access_log\\` (
  \\`id\\` int(11) unsigned NOT NULL auto_increment,
  \\`access_date\\` datetime NOT NULL,
  \\`carrier\\` enum('DOCOMO','EZWEB','SOFTBANK','OTHER')NOT NULL default 'OTHER',
  \\`u_id\\` int(11) unsigned default NULL,
  \\`jb\\` varchar(255) NOT NULL,
  \\`parameter\\` longtext,
  PRIMARY KEY  (\\`id\\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

EOT

とかのBASHを日別とか週別とか月別とかで実行してやればテーブルのサイズはそんなに大きくなることはないと思います。

フレームワークとか使っているならPOSTとかGETで受け取るものはすべてラッピングできると思うので、そこでDBにほりこんでおけばすべての値を得ることができると思います。

アクセスログをDBに入れておくと何が嬉しいか

集計するとき楽なんですよね。

ちなみに上にあるアクセスログのテーブルのカラムの一つ”jb”ってのは僕の使っているフレームワークののページ名です。
それ集計するだけで日別の各ページのアクセス数がとれるのですごく楽です。

携帯メインなのでキャリアの情報も格納しておけばさらにキャリア別でとれるし。

さっきのBASHを少し変えて、1週間前のテーブルなら削除するとかの処理入れておけばDBもそんなに大きくならなくていいかなーと思います。
集計結果を保存しておくテーブルは当然別につくり、cronとかで日別集計、週別集計、月別集計のバッチ組んでやれば古いデータは必要ないですし、CDなりDVDなりに焼いてやればHDDも圧迫しませんし。
POSTの値も保存できるので作ったアプリケーションの障害時に何が原因かってのも追えますしね。
結構お勧めです。

のびーにょ Apache, MySQL, Tips, データベース

Apacheチューニング その1  

2008/5/2 金曜日 10:12:49

M役員様、結婚おめでとうございます。姜子牙です。新居乱入はいつにしましょう?

4月のサーバパフォーマンスチューニング月間が完了し、ややほっとしております。一度最大瞬間風速でサーバが応答不能に近い状態になって以来、あれやこれやと調べつつ折を見て設定変更なんかを行ってきたので、それを書きたいなと思います。

このチューニングについては、GIGAZINEさんのサイトが主な情報源だったのですが
http://gigazine.net/index.php?/news/comments/20070119_gigazine_complete/
そこに被る部分、被らない部分、なんかできちゃった部分なんかを記載していきたいなーと思います。また赤裸々に情報を提供して頂いているGIGAZINEさんには感謝感謝です。

私が管理しているサーバはWebはApacheを、DBにはMySQLを使用しています。OSはLinuxで、開発はPHPなので標準的なLAMP構成です。

全部を一気に書くのはさすがに文章量が多すぎるため、まず今回はApacheに焦点を当てて行きたいと思います。(尚、Apacheは2.0以降が対象になると思います。1.*系ではだいぶ違うかも)

今回のApacheのチューニングでは、主に以下2つを対象にして行っています。
1、不要なModuleを外す
2、待機プロセス数の変更

Apacheでは各種機能をCoreから分離してModule形式で使用することができます。
MySQLと比較すると、MySQLは必要に応じて再構築(Configureを変更して、再度Make)が必要だったりするのですがApacheはコンフィグファイルのLoadModuleディレクティブで追加削除し、Apacheのリブートで適用できたりします。便利です。

しかし、ここで二つの問題にぶち当たります。
1-1、どのモジュールが使用されていて、どのモジュールが不要なのか判別がつかない
1-2、Includeしているconfの中などに散らばってLoadModuleディレクティブが書かれている

自分ですべてのプログラムや設定を把握していればいいのですが、そのようなことは少ないです。
Apacheの管理してんだからその上に乗っかるコード全部読んで把握しろと言われたら田舎に帰るか、土に還るか、野生に帰ると思います。

というわけで、ApacheのModuleの一つであるServer-infoを使用します。設定方法の詳細は割愛しますが、以下のようなLocationディレクティブをconfに追加します。Allow句のIPアドレスは任意に変更してください。

<location /server-info>
SetHandler server-info
Order allow,deny
Allow from 255.255.255.255
</location>

その後、Apacheの再起動を行うと、以下のようなURLでアクセスできます。(www.pakureserve.jpでの例です。尚アクセスしても404 Not Foundになります)
http://www.pakureserve.jp/server-info

このページでは、現在Loadされているモジュールの一覧が表示されそれがハンドラされるか否か、またConfファイルのどこかで関連のディレクティブが記載されていたらそのファイル名と行番号を表示してくれたりします。

“Current Configuration”に何らかの内容が表示されていたら、Confのどこかに関連の記載があり”Content handlers”がonの場合、ハンドラでそのモジュール機能が使われる可能性があるようです。(ハンドラの方は自信あまりなかったりします)

そのため、”Current Configuration”が空欄で且つ”Content handlers”がnoneのモジュールを今回は外しました。
/etc/init.d/httpd configtest でSyntax OKとなれば、コンフィグの記載はOKとなります。
/etc/init.d/httpd graceful で再起動します。

これで不要なモジュールをLoadせず稼働するため、少し処理が軽くなります。

やや余談:
httpdにも restart はあるのですが、現在接続中の人も接続を強制的に切断してしまうため稼働中サーバの変更を適用する場合は graceful を使用すると大きな影響なく再起動ができます。

うう・・・長くなっているので、2、待機プロセス数の変更 については次回エントリということで・・・。

[姜子牙](*’▽’) < 「秒間100アクセスでも結構動くよー」
[のびー](*゚Д゚) < 「いやいや、200くらいはサクサクいかないとねえ?」
[姜子牙](;’-') < 「うそん」

はい、逝ってきます。

姜子牙 Apache, Tips