Apache 与 Tomcat 通过 AJP 通信的关键是确保 mod_proxy_ajp 显式启用、Tomcat AJP Connector 绑定 127.0.0.1(或内网 IP)、ProxyPass 路径与 context path 严格一致、手动透传 X-Forwarded-For 等头,否则易现 503、404、IP 丢失或重定向错乱。Apache 启用 `mod_proxy_ajp` 与 Tomcat 通过 AJP 协议通信,关键不在“通不通”,而在于协议稳、路径准、IP真、端口安。AJP 是二进制协议,比 HTTP 代理更轻量、更高效,但默认不启用、不安全、不自动传客户端信息——配置漏掉任意一环,就容易出现 503、404、真实 IP 丢失或重定向错乱。
确认并启用 mod_proxy_ajp 模块
apache 2.4 不默认加载该模块,仅启 `mod_proxy` 不够,`mod_proxy_ajp` 必须显式启用,否则 `proxypass ajp://` 会静默失败或报 invalid url。
- 运行命令检查是否已加载:
CentOS/RHEL:httpd -M | grep proxy_ajp
Debian/Ubuntu:a2enmod -l | grep proxy_ajp
输出中必须含 proxy_ajp_module (shared) - 编辑模块加载文件(如
/etc/httpd/conf.modules.d/00-proxy.conf或/etc/apache2/mods-available/proxy_ajp.load),确保以下两行未被注释:LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_ajp_module modules/mod_proxy_ajp.so - 若系统中同时存在
mod_jk,建议禁用它——两者共存易引发连接复用冲突,导致随机 Connection refused 或 503
限定 Tomcat 的 AJP Connector 绑定地址
Tomcat 默认 AJP 配置为 <Connector port="8009" protocol="AJP/1.3">,监听 *:8009,等于把内部通信端口暴露在公网,既高危,又常因 IPv6 回环(::1)与 Apache 的 127.0.0.1 不匹配而连不上。
- 编辑
$CATALINA_HOME/conf/server.xml,找到或新增 AJP Connector,强制指定address:
单机部署:address="127.0.0.1"
分离部署:address="192.168.21.31"(填 Tomcat 实际内网 IP) - 完整示例:
<Connector port="8009" protocol="AJP/1.3" address="127.0.0.1" redirectPort="8443" connectionTimeout="60000" keepAliveTimeout="60000" maxThreads="500" /> - 重启 Tomcat 后执行:
ss -tlnp | grep :8009,输出应为127.0.0.1:8009,而非*:8009或:::8009 - 跨机器时,确保防火墙放行目标 IP + 8009 端口(如:
firewall-cmd --permanent --add-port=8009/tcp)
严格对齐 ProxyPass 路径与 Tomcat context path
AJP 不解析 URL,只做字节流转发,路径是字面匹配,差一个字符或斜杠,就会引发静态资源 404、重定向跳转错误、Session 丢失等隐蔽问题。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 假设 Tomcat 应用部署在
/myapp(即context.xml或 WAR 包名决定的上下文路径),则 Apache 配置必须完全一致:ProxyPass /myapp ajp://127.0.0.1:8009/myappProxyPassReverse /myapp ajp://127.0.0.1:8009/myapp - 结尾斜杠必须统一:写成
/myapp/和/myapp是两个不同路径,不能混用 - 避免使用
ProxyPassMatch(如^/(.*\.jsp)$),它会绕过 AJP 逻辑,降级为 HTTP 处理 - 不要图省事写
ProxyPass / ajp://...,除非 Tomcat 确实部署在根路径,否则所有请求都会被错导向根上下文
手动补全关键请求头与特殊支持
AJP 协议本身不自动透传 X-Forwarded-For、X-Forwarded-Proto 等头,也不支持 WebSocket。这些需额外配置,否则日志里全是 127.0.0.1,HTTPS 重定向变 HTTP,ws 连接直接断开。
- 在 Apache 虚拟主机中添加:
RequestHeader set X-Forwarded-For %{REMOTE_ADDR}sRequestHeader set X-Forwarded-Proto "https"(若前端有 SSL 终止) - 如需代理 WebSocket(如
wss://domain.com/ws),不能走 AJP:
必须启用mod_proxy_wstunnel
单独配置 HTTP 协议代理:ProxyPass /ws ws://127.0.0.1:8080/ws - Tomcat 若启用了
RemoteIpValve,依赖上述头字段还原真实 IP,缺一不可

















