笔者在整合 apache + mod_http_ajp + tomcat 的过程中,在端口问题上颇为困扰。在使用 docker 官方推荐的方法运行一个 tomcat 的容器后,在宿主机可以顺利访问容器默认的 8080 端口。但是配置了 tomcat 的 ajp 连接器之后,在宿主机却无法访问容器的 8009 端口。当时连接器的配置如下:
<Connector protocol="AJP/1.3"
port="8009"
redirectPort="8443"
maxParameterCount="1000"
secretRequired=""/>
《配置一》
这在普通的主机中配置是没问题的。可是我的环境如下:
宿主机:Ubuntu 20+
Docker 容器镜像:tomcat:9.0.80-jdk8
启动命令:docker run -d --name tomcat-apps tomcat:9.0.80-jdk8
通过启动命令可以看出,我没有使用任何端口映射,这样的好处就是容器不会暴漏到外网,理论上只能有宿主机访问。容器启动后,得知此容器的IP地址为 172.17.0.2 ,查看该地址的 8080 端口,可以正常访问,因此,在 apache 的虚拟机配置中
<VirtualHost *:80>
ServerName sns.eagsen.com
ProxyRequests Off
ProxyPreserveHost On
# ajp 协议效率更高,但支支持 java 的应用服务器
ProxyPass / http://172.17.0.2:8080/sns/
ProxyPassReverse / ajp://172.17.0.2:8080/sns/
ProxyPassReverseCookiePath / /
</VirtualHost>
可以顺利路由到容器的 web 应用,即 http://172.17.0.2:8080/sns/ 可以正常访问。但是当 tomcat 配置了 ajp 连接器以后,见上述《配置一》,却无法访问 ajp://172.17.0.2:8009/sns/ ,经过精确诊断,是 8009 端口不通。至此,问题集中在如何开通 8009 端口上。
原来,tomcat ajp 连接器默认情况下是在 127.0.0.1 的地址上监听 8009 端口,而容器运行时,被宿主机分配了至少三个地址,也就是说容器内的 127.0.0.1 这个地址并不被宿主机所识别,因此把连接器的配置修改如下,问题解决:
<!-- 增加 address="0.0.0.0" ,在所有地址上监听 8009 端口 -->
<Connector protocol="AJP/1.3"
port="8009"
redirectPort="8443"
maxParameterCount="1000"
address="0.0.0.0"
secretRequired=""/>