我很兴奋地看到Tomcat 9终于支持Unix域套接字,但似乎我的设置是坏的或不完整的。
不幸的是,我似乎在互联网上找不到server.xml anywhere 的工作示例。似乎发生的事情是,unix域套接字没有远程IP,Tomcat在它的堆栈的几个地方使用了远程IP。
当我向socket发出curl请求时,第二个请求崩溃并冻结了服务器。
sudo curl -kv -H "Connection: close" -H "x-forwarded-for: 127.0.0.1" http://localhost/hawtio/auth/login --unix-socket /opt/app-name/http.sock
我在Tomcat日志中看到崩溃:
#first request
SEVERE [http-apr-/opt/app-name/http.sock-exec-1] org.apache.coyote.http11.Http11Processor.service Error processing request
#011java.lang.NullPointerException
#011#011at java.base/java.util.regex.Matcher.getTextLength(Matcher.java:1770)
#011#011at java.base/java.util.regex.Matcher.reset(Matcher.java:416)
#011#011at java.base/java.util.regex.Matcher.<init>(Matcher.java:253)
#011#011at java.base/java.util.regex.Pattern.matcher(Pattern.java:1133)
#011#011at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:624)
#011#011at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
#011#011at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
#011#011at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
#011#011at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
#011#011at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:890)
#011#011at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2113)
#011#011at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
#011#011at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
#011#011at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
#011#011at java.base/java.lang.Thread.run(Thread.java:829)
# second request
SEVERE [http-apr-/opt/app-name/http.sock-Acceptor] jdk.internal.reflect.NativeMethodAccessorImpl.invoke Error allocating socket processor
#011java.lang.NullPointerException
#011#011at org.apache.tomcat.util.net.AprEndpoint.setSocketOptions(AprEndpoint.java:820)
#011#011at org.apache.tomcat.util.net.AprEndpoint.setSocketOptions(AprEndpoint.java:87)
#011#011at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:149)
#011#011at java.base/java.lang.Thread.run(Thread.java:829)
设定:
- Ubuntu 18.04版
- 雄猫9.0.64
- Java 11最新版本
- Apache可移植运行时/ Tomcat本机1.2.35
设定:
<Service name="CatalinaLocal">
<Connector
protocol="org.apache.coyote.http11.Http11AprProtocol"
unixDomainSocketPath="/opt/app-name/http.sock" />
<Engine
defaultHost="localhost"
name="Catalina">
<Host
name="localhost"
appBase="webapps"
unpackWARs="true"
autoDeploy="false"
deployIgnore="(?!.*hawtio).*">
<Valve
className="org.apache.catalina.valves.RemoteIpValve" />
</Host>
</Engine>
</Service>
如果您取出RemoteIpValve,则会出现相同的行为。
编辑
相关代码如下:https://github.com/apache/tomcat/blob/9.0.x/java/org/apache/tomcat/util/net/AprEndpoint.java#L807
// Do the duplicate accept check here rather than in serverSocketaccept()
// so we can cache the results in the SocketWrapper
AprSocketWrapper wrapper = new AprSocketWrapper(socket, this);
// Bug does not affect Windows. Skip the check on that platform.
if (!JrePlatform.IS_WINDOWS) {
long currentNanoTime = System.nanoTime();
if (wrapper.getRemotePort() == previousAcceptedPort) {
if (wrapper.getRemoteAddr().equals(previousAcceptedAddress)) {
if (currentNanoTime - previousAcceptedSocketNanoTime < 1000) {
throw new IOException(sm.getString("endpoint.err.duplicateAccept"));
}
}
}
previousAcceptedPort = wrapper.getRemotePort();
previousAcceptedAddress = wrapper.getRemoteAddr();
previousAcceptedSocketNanoTime = currentNanoTime;
}
这有点有趣,因为这段代码只出现在AprEndpoint连接器中(即Apache Portable Runtime,或通过JNI(Java Native Interface)调用Apache服务器),但我无法找到它所引用的bug,它试图修复。它可能与直接使用APR无关,这可能是一个疏忽。
1条答案
按热度按时间cgvd09ve1#
对于任何也经历过这个问题的人...我开始与Tomcat开发人员交谈,他们同意这是一个bug,并为Tomcat打开了一个PR修复程序。尚未发布,但希望很快。
https://github.com/apache/tomcat/pull/532