tomcatをipv6環境でipv4アドレスでlistenさせる方法(再掲載)
なんかけっこう困っている人がいまだに多いようなので、昔mixiに書いてた自分用のまとめをこちらに転載します。
試した環境:
apr-1.3.2 tomcat-native-1.1.14 sun-jdk-1.6.0.07 tomcat-6.0.16 ipv6 enabled gentoo linux(2.6.26 base kernel) tomcat6には実装が異なる3種類のHttp Connectorが付属しています。 参照: http://tomcat.apache.org/tomcat-6.0-doc/config/http.html (機能や特性の比較表がこのページの一番下にある。) org.apache.coyote.http11.Http11Protocol Pure Javaコネクタ。ブロッキングIO。昔からあるやつ。 以降、Traditionalコネクタとする。 org.apache.coyote.http11.Http11NioProtocol Pure Javaコネクタ。SSLのハンドシェイクに関してノンブロッキングIOをする。 NIOを利用したもの。tomcat6から利用可能。 以降、NIOコネクタとする。 org.apache.coyote.http11.Http11AprProtocol Nativeコネクタ。tomcat-nativeを経由してaprを利用する。 以降、Nativeコネクタとする。 どのコネクタを利用するかは、server.xml(gentooだと/etc/tomcat-6/server.xml) で設定します。(server.xml内のConnector要素、protocol属性の値) javaでは、今のとこipv6な環境でipv4のアドレスを積極的に使用するには、 -Djava.net.preferIPv4Stack=true を指定してjavaを起動しなければなりません。 gentooの場合、/etc/init.d/tomcat-6をそのまま使用するなら、 /etc/conf.d/tomcat-6に JAVA_OPTS="-Djava.net.preferIPv4Stack=true" or CATALINA_OPTS="-Djava.net.preferIPv4Stack=true" とします。 ですが、tomcat-native経由の場合は、このプロパティ値の影響を受けないようです。 そこで、いろいろ試してみました。 デフォルトの設定 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> protocol="HTTP/1.1"の場合は、tomcat-nativeが利用できる環境では、 Nativeコネクタが使用され、利用できない環境ではTraditionalコネクタ が利用されます。 tomcat-nativeあり -> IPv6でlisten(Nativeコネクタ) tomcat-nativeなし -> IPv6でlisten(Traditionalコネクタ) tomcat-nativeなし & preferIPv4Stack=true -> IPv4でlisten(Traditionalコネクタ) つまり、インストール直後はtomcat-native環境では、 どうあがいてもIPv6でlistenされるということになります。 次に、address属性の値にIPv4アドレスを指定してみます。 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" address="0.0.0.0" /> tomcat-nativeあり -> IPv4でlisten(Nativeコネクタ) tomcat-nativeなし -> IPv6でlisten(Traditionalコネクタ) <- これおかしくない? tomcat-nativeなし & preferIPv4Stack=true -> IPv4でlisten(Traditionalコネクタ) tomcat-nativeなしだと、address属性にIPv4アドレスを指定しても、 なぜかIPv6でbindされてしまう。この特性は、NIOコネクタを使用しても同じ。 NIOコネクタを使用する設定。 <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" address="0.0.0.0" /> tomcat-nativeあり、なし関係なく、 preferIPv4Stack=true -> IPv4でlisten(NIOコネクタ) preferIPv4Stack=false -> IPv6でlisten(NIOコネクタ) <- これおかしくない? この結果、 Nativeコネクタは、 Connectorのaddress属性にIPv4アドレスを指定するだけで、IPv4アドレスでlisten。 Traditionalコネクタ、NIOコネクタは、address属性へのIPv4アドレス指定かつ、 preferIPv4Stack=trueでIPv4アドレスでlisten。 という結果になりました。 同様に、Apacheと接続するのに使用されるAJPコネクタも、 tomcat-native経由とそうでないものがあります。 tomcat-native環境だと、address属性の指定のみでIPv4アドレスでlistenし、 tomcat-native環境以外では、加えてpreferIPv4Stack=trueも必要です。 気になるのは、NIOコネクタとNativeコネクタの性能差ですね。 どちらのパフォーマンスがよいでしょうか。もしくは、使い分け方。 知っている方おしえてください。













