我有一个用作简单 Web 服务器的 Vert.x Web 应用程序。Verticle的start()方法如下:
@Override
public void start() throws Exception
{
HttpServerOptions options = new HttpServerOptions();
options.setMaxHeaderSize(6000);
options.setMaxInitialLineLength(100000);
options.setTcpKeepAlive(true);
HttpServer server = vertx.createHttpServer(options);
Router router = Router.router(vertx);
router.route(HttpMethod.GET,"/*").handler(StaticHandler.create(".").setIndexPage("index.html"));
server.requestHandler(router);
server.listen(8099,result->{
if(result.succeeded())
log.info("Main Server has started! Listening on Port "+server.actualPort());
else if(result.failed())
log.error("Main Server start FAILED. Reason: "+result.cause());
});
}
该服务运行良好,可以毫无问题地显示静态内容——直到我将其放入 Docker 容器中。
当我将应用程序作为 Java jar 文件运行时:
java -jar webserv-1.0.0.jar
并使用以下 URL 运行浏览器:
http://localhost:8099
索引页面显示没有问题,并且还显示了指向其他页面的任何链接。
但随后,我使用以下 dockerfile 将 JAR 文件放入 Docker 容器中(当然是在停止服务器之后!):
FROM centos:7
RUN yum install -y \
java-11-openjdk \
java-11-openjdk-devel
RUN mkdir /home/factor3
ENV JAVA_HOME /usr/lib/jvm/java-1.11.0-openjdk/
RUN groupadd apprun && adduser factor3 -G appgroup
RUN chown factor3 /home/factor3
EXPOSE 8099
USER factor3
COPY ./app/webserv-1.0.0.jar /home/factor3
COPY app/asets /home/factor3
WORKDIR /home/factor3
ENTRYPOINT ["java","-jar","webserv-1.0.0.jar"]
创建映像(称为 webserv:1.0.0)后,我在 docker 中运行应用程序:
sudo docker run -p 8099:8099 --name webpages webserv:1.0.0
并在同一浏览器上使用相同的 URL:
http://localhost:8099
我得到以下失败:
java.lang.IllegalStateException: Response head already sent
at io.vertx.core.http.impl.Http1xServerResponse.checkHeadWritten(Http1xServerResponse.java:675)
at io.vertx.core.http.impl.Http1xServerResponse.setStatusCode(Http1xServerResponse.java:144)
at io.vertx.ext.web.impl.RoutingContextImplBase.unhandledFailure(RoutingContextImplBase.java:217)
at io.vertx.ext.web.impl.RoutingContextImpl.checkHandleNoMatch(RoutingContextImpl.java:142)
at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:134)
at io.vertx.ext.web.impl.RoutingContextImpl.doFail(RoutingContextImpl.java:591)
at io.vertx.ext.web.impl.RoutingContextImpl.fail(RoutingContextImpl.java:184)
at io.vertx.ext.web.impl.RoutingContextImpl.fail(RoutingContextImpl.java:173)
at io.vertx.ext.web.handler.impl.StaticHandlerImpl.lambda$sendFile$6(StaticHandlerImpl.java:438)
at io.vertx.core.http.impl.Http1xServerResponse.lambda$doSendFile$1(Http1xServerResponse.java:559)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)
at io.vertx.core.impl.EventLoopContext.lambda$runOnContext$0(EventLoopContext.java:38)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)
此故障持续发生。
我是否在 Vert.x 的 Http1xServerResponse 类中发现了一个错误,导致它在 Docker 容器中时失败?或者 Docker 中有什么东西会导致多个请求到达同一个路由?有没有其他人将 Vert.x 应用程序放入 Docker 容器并看到这种行为?
有没有办法(一些配置、代码更改或其他方法)使 Vert.x Web 应用程序在 Docker 容器中正常工作?为什么 Vert.x Web 应用程序可以正常工作,但放在 Docker 容器中时突然抛出 IllegalStateExceptions?
有人请帮助解决这个问题。