由于项目需要,我们要使用最新版本tomcat9.X来部署项目,同时需要以apr的模式启动来处理一些高并发需求。
操作系统: Window10/Server2016
Tomcat版本: apache-tomcat-9.0.65 x64
(这个版本是内置了tomcat-native-1.2.35,不需要单独下载)
Java版本:OpenJDK 64-Bit 1.8.0_332 (Temurin)
tomcat配置apr模式后能够正常启动,没有任何报错信息。发现用localhost的方式来访问应用是正常的,但是换成127.0.0.1或者是本地的ip地址来访问,就出现访问不了的情况。telnet IP+端口不通,但是protocol切换成NIO就能正常浏览器访问和telnet也是正常。猜测问题的确出在apr模式上。但是为什么apr模式会有问题,默认模式没有问题呢?
用cmd netstat命令查看了一下绑定的端口
netstat -ano | findstr 8888
在apr模式下:

可以看到5820端口有在正常的listening状态。但是ip地址有些奇怪。
换回nio模式:

在NIO模式下,会有两个地址绑定,一个是IPv4,一个是IPv6。而在APR模式下只有一个IP6的地址绑定。那么问题就在于tomcat的地址绑定上。为什么NIO模式会有IPv4和IPv6,而APR模式只有IPv6呢?所以APR模式导致用本机地址127.0.0.1(IPv4)无法访问 。
这里具体原因可以从tomcat源码里面去探究(暂时掠过)
文档地址:https://tomcat.apache.org/tomcat-9.0-doc/config/http.html#HTTP/2_Support

address
对于具有多个IP地址的服务器,此属性指定将用于侦听指定端口的地址。默认情况下,连接器将侦听所有本地地址。除非JVM被配置以其他方式使用的系统属性,基于Java连接器(NIO,NIO2)将当与任一被配置在两个IPv4和IPv6地址听0.0.0.0或::。如果配置为0.0.0.0,则APR /本机连接器将仅侦听IPv4地址,如果配置为 ,则将侦听IPv6地址(以及可选的IPv4地址,具体取决于ipv6v6only的设置)::。

ipv6v6only
如果在双堆栈系统上侦听IPv6地址,连接器是否应该仅侦听IPv6地址?如果未指定,则默认值为false,并且连接器将侦听IPv6地址和等效的IPv4地址(如果存在)。
在tomcat配置server.xml中手工指定地址 address="0.0.0.0"

修改后重新启动tomcat
apr模式再次查看

有外部访问的时候

最终大功告成!问题解决了。
附上完成的server.xml内容
- <Server port="8005" shutdown="SHUTDOWN">
- <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
-
-
- <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
-
- <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
- <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
- <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
-
-
- <GlobalNamingResources>
-
- <Resource name="UserDatabase" auth="Container"
- type="org.apache.catalina.UserDatabase"
- description="User database that can be updated and saved"
- factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
- pathname="conf/tomcat-users.xml" />
- GlobalNamingResources>
-
-
- <Service name="Catalina">
-
-
-
-
-
-
-
-
-
-
- <Connector port="8888"
- protocol="org.apache.coyote.http11.Http11AprProtocol"
- address="0.0.0.0"
- enableLookups="false"
- maxThreads="1000"
- minSpareThreads="100"
- acceptCount="1500"
- disableUploadTimeout="true"
- connectionTimeout="20000"
- URIEncoding="UTF-8"
- redirectPort="8443"
- compression="on"
- compressionMinSize="1024"
- useSendfile="false"
- noCompressionUserAgents="gozilla, traviata"
- compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript "/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <Engine name="Catalina" defaultHost="localhost">
-
-
-
-
-
- <Realm className="org.apache.catalina.realm.LockOutRealm">
-
- <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
- resourceName="UserDatabase"/>
- Realm>
-
- <Host name="localhost" appBase="webapps"
- unpackWARs="true" autoDeploy="true">
-
-
-
-
-
- <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
- prefix="localhost_access_log" suffix=".txt"
- pattern="%h %l %u %t "%r" %s %b" />
-
- Host>
- Engine>
- Service>
- Server>