Apache
起動方法
Solaris 版 Apache の起動は以下の手順で行います。
- /etc/apache/httpd.confの編集
- /usr/apache/bin/apachectl startを実行
Alias /mydoc/ "/home/user/mydoc/" <Directory "/home/user/mydoc"> AllowOverride None </Directory>
Tomcat
起動方法
Windows 版 Tomcatの起動は以下の手順で行います。
- [スタート] メニューから [プログラム] - [Apache Tomcat 5.0] - [Configure Tomcat] を選択します。
- [General] を選択します。
- [Start] ボタンをクリックします。
停止方法
Windows 版 Tomcatの停止は以下の手順で行います。
- [スタート] メニューから [プログラム] - [Apache Tomcat 5.0] - [Configure Tomcat] を選択します。
- [General] を選択します。
- [Stop] ボタンをクリックします。
WARファイル
Webアプリケーションに含まれるJSPおよびHTML、JavaのクラスファイルなどをひとつのファイルにまとめたものをWARファイルといいます。WARファイルは、ある決められたディレクトリ構成のものをJARファイルと同じ形式でまとめられたものです。
標準ディレクトリレイアウト
- *.html, *.jsp, etc
- HTMLやJSPのファイルを配置します。Javaスクリプトやスタイルシートファイル、画像などのようにクライアントブラウザから見ることのできるファイルもここに配置します。大きなアプリケーションの場合は、サブフォルダを作成して階層化することも可能です。
- /WEB-INF/web.xml
- サーブレットや初期化パラメータ等について記述したXMLファイル。
- /WEB-INF/classes
- サーブレットのクラスのように、このWebアプリケーションで必要とする(JARファイルとしてアーカイブしていない)Javaクラスファイル(関連リソースを含む)を配置するディレクトリ。もしクラスがパッケージとして組織されていれば、このディレクトリの下に階層ディレクトリを作成して配置します。例えば、com.mycompany.mypackage.MyServletと名づけたJavaクラスは /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class として配置します。
- /WEB-INF/lib
- サードパーティのクラスライブラリやJDBCドライバのように、このWebアプリケーションで必要とするJARファイル(Javaクラスファイルや関連リソースを含む)を配置するディレクトリ。
myapps以下をまとめてmyapps.warというWARファイルを作成して、他のサーバーへ配布することができます。
共有ライブラリファイル
- /shared/lib
- ここに配置されたJARファイルは、全てのWebアプリケーションから参照することができます。共有ライブラリを配置します。
TomcatへのWebアプリケーションの登録
WebアプリケーションをTomcatへ登録するには、Tomcatのフォルダ\conf\server.xml ファイルにコンテキストタグを追加します。
<Context path="/myapps" docBase="myapps" debug="0" reloadable="true">
</Context>
</Host>
Tomcatのフォルダ\webappsの下にWebアプリケーションを配置した場合、Tomcatの起動時に自動的に認識するため、上記タグの追加は必要ありません。
server.xmlにコンテキストタグを追加したら、Tomcatを再起動します。
web.xml
ウェルカムファイル
URIにディレクトリを指定した場合に開かれるファイルのことをウェルカムファイルと言います。例えば www.sample.com/ というURLを指定したときに www.sample.com/index.html が開かれたとすると、index.html がウェルカムファイルです。ウェルカムファイルのリストは web.xml で指定することができます。
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list>
サーブレットマッピング
サーブレットマッピングとは、あるURLにリクエストがあったときに、どのサーブレットを呼び出すか制御することです。
<web-apps>
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/servlet/HelloWorldServlet</url-pattern>
</servlet-mapping>
</web-apps>
サーブレットの初期化
リクエストを受ける前にサーブレットで初期化処理を行いたい場合、サーブレットのスーパークラスであるjavax.servlet.http.HttpServletクラスのinitメソッドをオーバーライドします。
初期化パラメータはデプロイメントディスクリプタ(/WEB-INF/web.xml)のservlet要素に記述します。記述する場所は、初期化パラメータを受け取りたいサーブレットを定義したservlet要素の中です。init-param要素の子としてparam-name要素とparam-value要素を記述します。次に定義例を示します。
<servlet>
<servlet-name>SampleServlet</servlet-name>
<servlet-class>com.sample.SampleServlet</servlet-class>
<init-param>
<param-name>host</param-name>
<param-value>localhost</param-value>
</init-param>
</servlet>
この例では、SampleServletの初期化パラメータとしてhostという名前でlocalhostという値を定義しています。
この初期化パラメータを受け取るにはgetInitParameterメソッドを使用します。次にinitメソッドから初期化パラメータを取得するJavaソースの例を示します。
public void init(ServletConfig sc) throws ServletException {
super.init(sc);
String host = sc.getInitParameter("host");
次にサーブレットのserviceメソッドから初期化パラメータを取得する例を示します。
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String host = this.getInitParameter("host");
OSとJVMのプロパティを表示
Tomcatのバージョン、OSやJVMのプロパティを表示します。
Tomcat Version: Apache Tomcat/5.0.28
OS Name: Windows 2000
OS Version: 5.0
OS Architecture: x86
JVM Version: 1.4.2_04-b05
JVM Vendor: Sun Microsystems Inc.
WEBサーバのチューニング
ファイルシステム
- アクセスが複数ドライブに分散されるようにする。
- ループバックファイルシステムが利用できる。
ログ
- ばかにならない量のログが生成される(Apache のログは 10,000リクエスト毎に約1MB増える)。
- さしあたって使用しないログは取らない(エージェントログ等)。
- エラーログは必ず取る。そして必ず監視する。
ネットワークコードのパラメータ
- listen キューの長さ
サーバ性能を超えて到着する要求をごく短期間バッファリングできる。 - 世の中の迷惑になるパラメータ変更を行わない。
Nagle アルゴリズムの禁止。
ループバックファイルシステム
lofs (loopback virtual file system) は、架空のファイルシステムを作り、ファイルに別のパス名を与えることができる。 例えば、/ の上に /tmp/newroot をループバックマウントすると、ルート以下の全てのファイルシステムが、/tmp/newroot 以下にコピーされたかのように見える。
Nagle アルゴリズム
TCP/IP Nagle アルゴリズムは、基本的にはバッファリングの方法である。 どんなに小さなパケットであっても、全てのパケットに対して一定のオーバヘッドがある。 このために Nagle アルゴリズムは小さいパケットを(0.2 秒以上の遅延は無い様に)一緒に集めることによって、転送されるバイと数のオーバヘッドを減らしている。
Apacheのチューニング
ログ
Apache にはリクエストされたアクセスがどのようなブラウザから送られてきたのかを、ログに出力するオプション機能がある。この機能により、利用されているブラウザの傾向を知ることができる。エージェントログを有効にするには、AgentLog オプションを設定する。
AgentLog logs/agent_log
Apache には、インターネット上のどのサイトのリンクを辿って自サイトへアクセスしてきたか(リンキング)をログに出力させる機能がある。この機能を有効にするには、RefererLog オプションを設定する。
RefererLog logs/referer_log
エージェントログおよび参照者ログは、必要の無い限り取らない方が望ましい。
HostnameLookups
Apache 1.3では、HostnameLookups の初期設定は off である。 この設定だと、DSNルップアップによる余分な処理が無くなるので、HTMLファイルが表示されるまでの時間が短くなる。 しかし、1.3以降のバージョンでは、allow from domain や deny from domain ディレクティブを使うと、二重リバースNDSルックアップという代償を払うことになる(リバースに加えて、リバースが誤魔化されていないかの確認のためのフォワード)。 ディレクティブの範囲を <Location /server-status> セクションで制限することで、上記の二重リバースDNSルックアップを避けることができる。 例えば、 .html ファイルと .cgi ファイル以外はルックアップしないようにするには、次のようにする。
HostnameLookups off
<Files "\.(html|cgi)$">
HostnameLookups on
</Files>
幾つかのCGIの中でホスト名が必要であれば、それを必要としている特定のCGIでだけ gethostbyname コールをするように設定する。
<Limit GET> 〜 </Limit> に記述することによって外部からのアクセスを制限する。
<Limit GET> order deny, allow deny from all allow from www.foo.co.jp </Limit>
この記述によって、www.foo.co.jp 以外のホストが <Directory></Directory> タグで指定したディレクトリにアクセスするのを禁止する。
FollowSymLinks and SymLinksIfOwnerMatch
URLスペースに Options FollowSymLinks が無い場合、あるいは Options SymLinksIfOwnerMatch がある場合は、シンボリックリンクをチェックする為に Apache が余分なシステムコールを発する場合がある。各ファイルネーム要素につき、1コールである。例えば、
DocumentRoot /www/htdocs
<Directory />
Options SymLinksIfOwnerMatch
</Directory>
があって、/index.html というURI (Uniform Resource Identifiers) がリクエストされた場合には、Apache は lstat (2) を /www、/www/htdocs、/www/htdocs/index.html に対して行う。lstat の結果はキャッシュに保存されることはないので、リクエストの度に起こる。
どうしても symlinks セキュリティチェックが必要なら、次の様にする。
DocumentRoot /www/htdocs
<Directory />
Options FollowSymLinks
</Directory>
<Directory /www/htdocs>
Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>
こうすれば、少なくとも DocumentRoot パスの余分なチェックが不要となる。ドキュメントルート以外に Alias や RewriteRule パスがある場合には、同様のセクションを追加する必要がある。最高の性能を引き出すためにシンボリックリンクのセキュリティチェックをゼロにするためには、全ての箇所に FollowSymLinks を設定して、SymLinksIfOwnerMatch は指定しない。
AllowOverride
URL空間で overrides を認める場合(典型的には .htaccess ファイル)、Apache は各ファイルネーム要素毎に .htaccess を開こうとする。例えば、
DocumentRoot /www/htdocs
<Directory />
AllowOverride all
</Directory>
があって、/index.html のURIをリクエストをしたとする。 Apache は /.htaccess、/www/.htaccess、そして /www/htdocs/.htaccess を開こうとする。解決策は前述の Options FollowSysLinks と同様である。最高の性能を追求する場合には、ファイルシステムの何処ででも AllowOverride Node を使用すること。
ネゴシエーション
本当に最高の性能を絞り出したい場合には、コンテンツネゴシエーションを極力避けたいところである。しかし、ネゴシエーション機能には性能の低下を補って余りあるものがある。サーバの速度を上げることができる場合がひとつある。
DirectoryIndex index
の様なワイルドカードは使わずに、次の様に全てのオプションを羅列する。
DirectoryIndex index.cgi index.pl index.shtml index.html
ここでは、一番頻繁に使うオプションをリストの頭に記述すること。
プロセスの生成
Apache 1.3以前は、MaxSpareServers、MinSpareServers、そして StartServers の設定はどれもベンチマーク結果に極端に大きな影響を持っている。特に Apache はリクエストによる負荷に見合うだけの数の子プロセスを発生させるのに準備期間が必要だった。StartServers の子プロセスを最初に発生させたら、1秒あたりの子プロセスの発生を1に制限して、MinSpareServers で指定した子プロセス数を保持していた。つまり、100のクライアントが同時にアクセスしているサーバで、StartServers の初期設定が5になっている場合には、このロードに対応できるだけの子プロセスが発生するには95秒程度かかるということになる。
1秒あたり1個発生の法則は、新しい子プロセスの発生でマシンが溢れることを懸念してのものだった。マシンが子プロセス作りで忙しい場合は、リクエストにも対応できないからである。しかし、この法則による制限は Apache の性能が酷く低いものだと解釈されることに繋がってしまったため、変更せざるを得なかった。Apache 1.3からは1秒あたりの規則を緩和したコードが採用されている。子プロセスを1つ発生させ、1秒待ち、2つ発生させ、また1秒待ち、4つ発生させ…という容量で、1秒あたりの子プロセスを32発生させているところまで乗数的に続く。この動作は、MinSpareServers 設定を満たした時点で止まる。
1秒に4つ以上の子プロセスが発生した場合には、メッセージが ErrorLog に出力される。こういうエラーが沢山出てきたら、この設定を変えることを検討する。
プロセス作成に関しては、他に MaxRequestsPerChild 設定による子プロセスの消滅指定もある。この初期設定値は30になっている。しかし、子プロセスに肥大したメモリイメージを持たせるような mod_perl の様なモジュールを使っているサーバでなければ、この値は低すぎる。サーバのページが殆ど静的なものならば、この値を 10,000 あたりまで上げてみる。
keep-alives が使われている場合には、既に開かれている接続での次のリクエストを待って、子プロセスが何もしない状態でいるということになる。KeepAliveTimeOut の12秒という初期設定は、この状態を極力減らすためのものである。ここでは、ネットワークバンド幅とサーバリソースがお互いの足を引き合う形であるが、どんな場合でもこれを60秒以上にしてはならない。それでは殆どの利点が失われてしまうからである。
mod_status and Rule STATUS=yes
Apache をコンパイルするときに mod_status を含めて、さらにRule STATUS を yes に設定した場合には、Apache はリクエストの度に gettimeofday (2) (OSによっては times (2) のこともある)に2回のコールをする。1.3 以前のバージョンでは、さらにいくつか time (2) にコールする。これは、ステータスレポートにタイミング要素を含むようにするためである。よって、最高の性能を追求する場合には、Rule STATUS=no に設定する。
DYNAMIC_MODULE_LIMIT
動的にロードされたモジュールを使わなければ、サーバ構築の際に -D DYNAMIC_MODULE_LIMIT=0 も追加した方が良い。そうすれば動的にロードされたモジュール専用にアロケートされていたRAMも使えるようになる。