我在 Debian 上使用 Apache 2.4.10 作为前端 Web 服务器,后端使用 Tomcat 8.0.28 实例。它们的目的是提供标准 jsp 页面,其中一些页面是动态刷新的。
我的 Web 应用运行良好,但通过 SSE 广播通知时除外。几分钟后,Tomcat 就崩溃了,停止提供页面(HTTP 500),有时会将 SSE 内容与常规 HTML 流混合在一起。
重要提示:在开发环境中,所有 SSE 内容均运行良好,即当我们在 Windows 7/10 下运行不带 Apache 的 Tomcat 时。这个细节以及我在日志中读到的内容使我相信问题出在 Apache 上。
Apache 能够处理 SSE 请求吗?
如果是的话,我应该应用哪种配置?
非常感谢您的帮助。
附加信息:
Apache 的配置:
- Apache 2.4.10 (Debian 64 bits) OpenSSL/1.0.1k
- mpm-event, with mod_headers, mod_ssl, mod_rewrite, mod_proxy, mod_proxy_http
- The Tomcat's integration is operated with the mod_proxy_ajp
Web 应用程序配置:
- Tomcat 8.0.28, with java version "1.7.0_79" (OpenJDK 64 bits)
- The connector is set to use the AJP/1.3 protocol
- SSE server based upon Jersey 2.5.1
- Tomcat hosts several Web Apps, all routed through a ProxyPass directive (such as ProxyPass /webapp1 ajp://10.10.12.2:8015/webapp1, ProxyPass /webapp2 ajp://10.10.12.2:8015/webapp2, and so on).
Tomcat 日志:
[list] 07-Apr-2019 19:55:19.580 INFO [pool-13-thread-1] org.apache.coyote.AbstractProcessor.setErrorState An error occurred in processing while on a non-container thread. The connection will be closed immediately
java.io.IOException: Relais brisé (pipe)
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
[...]
at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101)
[...]
at org.apache.coyote.ajp.AbstractAjpProcessor.action(AbstractAjpProcessor.java:410)
[...]
at org.glassfish.jersey.server.Broadcaster.broadcast(Broadcaster.java:150)
[...]
at SAR.DTS.Base.b.o.run(ThreadMajRappels.java:58)
[...]
at java.lang.Thread.run(Thread.java:745)[/list]
07-Apr-2019 20:10:05.344 INFO [ajp-nio-8015-exec-10] org.apache.catalina.connector.CoyoteAdapter.checkRecycled Encountered a non-recycled response and recycled it forcedly.
org.apache.catalina.connector.CoyoteAdapter$RecycleRequiredException
at org.apache.catalina.connector.CoyoteAdapter.checkRecycled(CoyoteAdapter.java:710)
at org.apache.coyote.ajp.AbstractAjpProcessor.recycle(AbstractAjpProcessor.java:943)
at org.apache.coyote.ajp.AjpNioProtocol$AjpConnectionHandler.release(AjpNioProtocol.java:163)
Apache 日志:
[Sun Apr 07 20:05:22.338619 2019] [proxy_ajp:error] [pid 6573] [client xx.xx.x.xxx:61445] AH00893: dialog to 10.10.12.2:8015 (10.10.12.2) failed, referer: http://yy.yy.yy.yyy/webapp1
[Sun Apr 07 20:10:05.344774 2019] [proxy_ajp:error] [pid 6573] [client xx.xx.x.xxx:62693] AH00992: ajp_read_header: ajp_ilink_receive failed, referer: http://yy.yy.yy.yyy/webapp1
[Sun Apr 07 20:10:05.344783 2019] [proxy_ajp:error] [pid 6573] (120006)APR does not understand this error code: [client xx.xx.x.xxx:62693] AH00878: read response failed from 10.10.12.2:8015 (10.10.12.2), referer: http://yy.yy.yy.yyy/webapp1
[Sun Apr 07 20:10:05.344745 2019] [proxy_ajp:error] [pid 6573] (104)Connection reset by peer: AH01030: ajp_ilink_receive() can't receive header
答案1
是的,Apache 可以!
我找到了一种让 SSE 在 Apache + Tomcat 中运行的方法,即用非常简单的 HTTP 连接器替换 AJP 连接器:
在 Apache 配置中:
# This statment prevents Apache from redirecting to the local URL.
# Oddly, it is unnecessary when using the AJP Connector...
ProxyPreserveHost On
ProxyPass /webapp1 http://10.10.12.2:8016/webapp1
在 Tomcat 配置中:
<Connector
port="8016"
protocol="org.apache.coyote.http11.Http11NioProtocol"
proxyPort="80" />
我不知道这是否是最初问题的正确答案,但它让我更接近目标......
现在,我将尝试 1) 找到(如果有)适合 AJP 的正确配置和 2) 使 http 配置与 SSL 和 SSE 一起工作。