はじめに
Apache+Tomcat構成を運用しているが、Chromeの開発者ツールでネットワークのプロトコルを確認すると、HTTP/1.1での通信をしていることに気づいた。
HTTP/3が出ているのに、まだHTTP/1.1で通信になっているのは流石にと思ったので備忘録としてHTTP/2通信をできるようにした手順を記載しておく。
環境
Apache 2.4.58
Tomcat 9.0.85
Docker Desktop 4.28.0 (139021)
Docker version 25.0.3
準備
例によって、Docker
での検証を行う。
今回は、Apache+Tomcatの構成で静的リソースをApacheに処理させるで使用したリポジトリを少しいじっているのでこれを使う。
http2対応にあたって
http2対応にあたって以下の条件を満たせているかどうかを確認する必要がある。
- https通信をしているかどうか
HTTP/2プロトコルはALPNというTLSの拡張プロトコルを使用するため、https通信をしている必要がある。 - TLS1.2以上であるかどうか
前述のALPNがOpenSSL1.0.2以上でのサポートとなるため、TLS1.2に対応している必要がある。
https://ja.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation - Apache 2.4.17以上であるかどうか
ApacheがHTTP/2 (mod_http2)に対応したバージョンの必要がある。
https://httpd.apache.org/docs/2.4/mod/mod_http2.html - Apache Server MPM が preforkでないこと
Server MPMがpreforkの場合、制限を受けるため HTTP/2が選択されない。
https://httpd.apache.org/docs/2.4/howto/http2.html - Tomcatが9.0.x以上であること、もしくは8.5.x以上であること(一部制限あり)
TomcatがHTTP/2に対応したバージョンの必要がある。
https://tomcat.apache.org/whichversion.html
修正手順
1. mod_http2をインストールする
Apacheの有効なモジュール一覧を表示する。
httpd -M
mod_http2
がない場合は、下記を実行しmod_http2
を入れる。
yum install -y mod_http2
インストールコマンドについては、Docker内のパッケージマネージャに依存しているが、他のディストリビューションであれば下記のコマンドになると思われる。apt-get
, dnf
2. ApacheのMPM設定(prefork->event)をする
httpd -V
を実行した際に、Server MPM: prefork
となっている場合は修正する必要がある。
この場合下記のように修正する。(今回はevent
に変更する)
vi /etc/httpd/conf.modules.d/00-mpm.conf
-LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
+#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
-#LoadModule mpm_event_module modules/mod_mpm_event.so
+LoadModule mpm_event_module modules/mod_mpm_event.so
面倒な場合は、sed
で置き換えてもOK
sed -i.bak -e 's/^LoadModule mpm_prefork_module/#LoadModule mpm_prefork_module/' \
-e 's/^#LoadModule mpm_event_module/LoadModule mpm_event_module/' \
/etc/httpd/conf.modules.d/00-mpm.conf
3. ssl.confの設定
最後に、HTTP/2プロトコルを利用するための設定を行う。
vi /etc/httpd/conf.d/ssl.conf
で設定ファイルを開き、
<VirtualHost _default_:443>
+Protocols h2 http/1.1
...
</VirtualHost>
を記述し、設定は完了。
4. Apacheの再起動
systemctl restart httpd
Dockerの場合はコンテナをビルドし直して立ち上げてほしい。
docker compose up -d --build
※上記で設定は完了で、Tomcat側の設定は不要である。
一応、Claude3
に聞いてみると、
APRコネクタ(AJPコネクタ)を使う場合は、Apacheが HTTP/HTTPSリクエストを受け付け、Tomcatへはプロキシ経由でリクエストが転送されます。したがって、この設定は不要です。
確認
Chromeでのhttp protocolの確認方法は下記を参考に。
https://www.sudshekhar.com/blog/http-protocol-check-in-chrome
今回 Docker
を使用している方であれば、https://localhost/sampleで確認が可能である。
https通信だと、protocol
がh2
となっておりHTTP/2
での通信がされている。
http通信だと、protocol
がHTTP/1.1
での通信がされている。
参考
ApacheのMPM設定(preforkかworkerかevent比較)
https://performance.oreda.net/middleware/web/apache-mpm#%E7%B3%BB%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8HTTP/2 guide
https://httpd.apache.org/docs/2.4/howto/http2.htmlClaude3
https://claude.ai/
おわりに
Apache+TomcatでAJP連携しているサイトが業務であるのだが、HTTP/1.1のままなのでこの手順でアップグレードしていきたい。
Server MPMがpreforkだとHTTP/2通信になってくれなかったり、ハマることがあったが対応できてよかった。
HTTP/2対応は良いのだが、ApacheはHTTP/3対応がまだなので、このまま対応されなかったらnginx
になっていくのだろうか。