Apache httpd 2.4の便利そうな新しいコア機能

Apache httpdの2.4系を触っていて、面白そうだなーと思う新しいコア機能を幾つか紹介したいと思います。こういうの欲しかった!と思える機能がちらほら見受けられます。

MPMをLoadableに扱える

PreforkやWorker、eventのMPM切り替えを、これまではコンパイル時に行う必要がありましたが、それぞれのMPMがモジュール化されLoadableになりました。これによって、MPMを切り替えて試したりする作業が格段にやりやすくなったと思います。 むしろこれになれて2.2系を触ると、うおおおーっめんどくさい!ってなります。

モジュール単位やディレクトリ単位でログレベルを制御

エラーログの出力レベルを、モジュール単位で設定できたり、ディレクトリ単位で設定できるようになりました。例えば、通常はnoticeのままにmod_mrubyだけdebugで出力して、ある任意のディレクトリはdebugよりもさらに細かいtrace1で出力させるという書き方もできます。 [program lang=’apache’ escaped=’true’]

LogLevel notice mruby:debug
<Directory /usr/local/apache/htdocs/trace_dir>
  LogLevel trace1
</Directory>

[/program] debugよりも更に細かいtrace[1-8]というレベルも追加されました。

If、ElseIf、Elseディレクティブの追加

リクエスト単位の設定において、変数等を条件にIfやElseディレクティブで設定を条件分岐させる事ができるようになりました。例えば、ローカルからのアクセスはログを最大限出力するようする、HTTP/1.0のようなHostヘッダの指定がない場合とある場合でリダイレクト先を変える、といった処理は以下のようにかけます。 [program lang=’apache’ escaped=’true’]

<If "%{REMOTE_ADDR} =~ /127.0.0/">
  LogLevel trace8
</If>
 
<If "$req{HOST} == ''">
  Redirect permanent / http://http10.example.com/
<Else>
  Redirect permanent / http://http11.example.com/
</If>

[/program] 条件分岐内で可能なExpressionやVariablesに関しては、公式ドキュメントを見ると良いと思います。

Defineディレクティブの追加

C言語のマクロのような、Defineディレクティブによって、IfDefineと併用することでマクロのような設定を書けるようになりました。Defineの内容はhttpd起動時の引数の-Dオプションにも対応しています。 例えば、mod_mrubyのテスト用の設定と本番用の設定を分ける場合に、 [program lang=’apache’ escaped=’true’]

# apachectl -DMOD_MRUBY_TEST 相当のDefineが以下の設定
Define MOD_MRUBY_TEST
 
<IfDefine MOD_MRUBY_TEST> 
  Define vhost test.example.com 
  Define log_level debug 
  Define mod_mruby_log_level mruby:debug
  LoadModule mruby_module mod_mruby_test.so
</IfDefine>
 
<IfDefine !MOD_MRUBY_TEST> 
  Define vhost production.example.com 
  Define log_level notice 
  Define mod_mruby_log_level mruby:warn
  LoadModule mruby_module mod_mruby.so 
</IfDefine> 
 
DocumentRoot /usr/local/apache/vhosts/${vhost}/htdocs 
LogLevel ${log_level} ${mod_mruby_log_level}

[/program] というように書けます。なかなか便利ですね。mod_macroも標準モジュールに入ったのでどのように使い分けるかも考えてみると良いかもしれません。

アクセス制御にはRequireディレクティブを使用

ここは特に気になっていたので、以前「Apache 2.4系でのモダンなアクセス制御の書き方」という記事にまとめたので詳しくはそちらを御覧ください。 例として、「アクセス元のuserがsuperadminだったら無条件で許可、または、IPアドレスが192.168配下で、かつ、adminグループであるか192.168.1以下のIPアドレスっだたら許可。ただし、上記が問題なくても、groupがblacklistに所属している場合はさすがにだめ」の場合は以下のようになります。 [program lang=’apache’ escaped=’true’]

<Location /admin>
  <RequireAll>
    <RequireAny>
      # userがsuperadminだったら無条件で許可
      Require user superadmin

      # または、IPアドレスが192.168以下で、かつ、adminグループであるか
      # 192.168.1以下のIPアドレスっだたら許可
      <RequireAll>
        Require ip 192.168
        <RequireAny>
          Require group admin
          Require ip 192.168.1
        </RequireAny>
      </RequireAll>
    </RequireAny>

    # ただし、上記の中でgroupがblacklistに所属している場合は
    # さすがにだめ
    <RequireNone>
      Require group blacklist
    </RequireNone>
  </RequireAll>
</Location>

[/program] こちらも、条件分岐内で可能なExpressionやVariablesに関しては、公式ドキュメントを見ると良いと思います。

KeepAliveTimeoutをミリ秒で設定できる

そのままの意味です。これまでは、秒単位でしか設定できなかったのですが、ミリ秒でより細かく制御できるようになりました。大規模サービスにおいては、チューニング時に必要になる場面が出てくるかもしれませんね。

まとめ

以上のように2.4系のコア機能は、これまで欲しいけど意外となかった機能を増強し、痒い所に手が届く機能が幾つか追加されたように思います。 また、モジュールでもmod_remoteipやmod_proxy_express、mod_heartmonitor等、新たに幾つか興味深い機能が追加されているので、今後紹介していきたいと思います。