Tomcat在将unixDomainSocket用作连接器时崩溃

fgw7neuy  于 2022-11-13  发布在  Unix
关注(0)|答案(1)|浏览(255)

我很兴奋地看到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无关,这可能是一个疏忽。

cgvd09ve

cgvd09ve1#

对于任何也经历过这个问题的人...我开始与Tomcat开发人员交谈,他们同意这是一个bug,并为Tomcat打开了一个PR修复程序。尚未发布,但希望很快。
https://github.com/apache/tomcat/pull/532

相关问题