【问题标题】:Jetty thread pool and sun.HttpServer sessionJetty 线程池和 sun.HttpServer 会话
【发布时间】:2013-04-30 12:31:48
【问题描述】:

我正在尝试创建简单的 java HTTP 服务器(我也是))),但是我需要控制线程池和 TCP 会话。我想在启动时预先创建所有需要的线程,并且我需要从 HTTP 处理程序关闭 TCP 会话。

首先我尝试嵌入 Jetty。 Jetty 8 Server 类有 setThreadPool 方法,虽然它的 ThreadPool 不如标准强大(例如 Jetty 的 ThreadPoolExecutor 没有 prestartAllCoreThreads (我可以t 使用 Java 的 ThreadPoolExecutor,可以吗?)。

但似乎我可以通过

关闭来自 servlet 处理程序的 TCP 会话
HttpSession session = request.getSession();
session.invalidate(); 

但 Jetty 9 Server 现在根本没有 setThreadPool 方法。它迁移到其他地方了吗?

第二我尝试使用com.sun.net.httpserver.HttpServer。它适用于线程池

ThreadPoolExecutor thp = (ThreadPoolExecutor) Executors.newCachedThreadPool();

thp.setMaximumPoolSize(1000);
thp.setCorePoolSize(1000);
thp.prestartAllCoreThreads();

server.setExecutor(thp);

但无法控制 TCP 连接关闭(HttpExchange 类不提供任何方法)。

所以实际上我需要以某种方式将来自 Sun HttpServer 的线程控制和来自 Jetty 的会话控制结合起来?

在 Jetty 9 中控制 ThreadPool 也会很好。

如果可能的话,我也不希望使用像 Jetty 这样的第 3 方组件。

谢谢。

【问题讨论】:

  • “我宁愿不使用第 3 方组件”。您正在使用 com.sun.*,它不保证将来会出现在 JVM 中。 JVM 只承诺存在java.*javax.*(Oracle,Java 的新所有者和看守者,一段时间以来一直在更改和删除对 Sun 的引用)。您使用com.sun.net.httpserver.HttpServer 的愿望很可能会在未来满足第三方下载旧版jar 的需求。可能没有更新。
  • javax 是否包含自己的“标准”servlet 容器/http 服务器?

标签: java servlets jetty httpserver


【解决方案1】:

在 jetty-9 中,许多签名更改了服务器的连接方式。在拥有所有 getter 和 setter 的 leu 中,它被切换到更多基于构造函数的方式,因此您应该找到在那里传递线程池的能力。至于线程的预启动,请随时在 RT/Jetty 下的 bugs.eclipse.org 上为该功能打开一个错误,我们将看看。

此外,我们在 git 中为 jetty-9 提供了一个 jetty-http-spi 实现,但我们还没有为它发布任何工件。我们将它们用于 7 和 8,我们只是试图根据出现的请求来衡量它是否值得为 jetty-9 保留。那里的类​​扩展了您上面提到的 com.sun http 服务器,并允许您使用码头代替捆绑在里面的那个,所以这是另一个潜在的选择,尽管您仍然有线程池线程启动问题,我没有乍一看,这并不是一个特别难以解决的问题。

【讨论】:

  • 接受 threadPool 的构造函数不使用端口号,我看不到在创建后设置端口号的方法。这种荒谬的解决方法似乎有效: Server server = new Server(8080); ThreadPool tp = new ExecutorThreadPool(5, 10, 10, TimeUnit.SECONDS); server.setServer(new Server(tp));
【解决方案2】:

1) 我找到了在 Jetty 中调优线程池的方法:

Server server = new Server(80);
QueuedThreadPool p = (QueuedThreadPool) server.getThreadPool();
p.setMaxThreads(1012);

2) 也可以在 Jetty 和 com.sun.http 中控制 TCP 会话 Jetty:只需在响应中添加 header Connection: close,Jetty 会添加此 header 并发送 FIN 数据包

response.setHeader("Connection", "close");
response.getWriter().println(str);

但不适用于 Tansfer-Encoding: chunked,我猜这是错误。

com.sun.http:也使用

t.getRequestHeaders().add("Connection", "Close");

但它的工作方式完全不同——它不会在响应中添加标头,而是立即关闭 TCP 会话,所以在发送数据之后使用它

OutputStream os = t.getResponseBody();
os.write(str.getBytes());
t.getRequestHeaders().add("Connection", "Close");

【讨论】:

  • Jetty 关于 Transfer-Encoding 的回答:chunked:“一个 servlet 永远不应该设置 Transfer-Encoding:chunked 由服务器决定是否需要(甚至可用)分块。如果请求是 HTTP/1.0 或 SPDY,则分块不可用。如果有 Connection:close 标头,则 EOF 标记消息的结尾,因此码头不需要去分块。所以码头基本上忽略任何传输编码一个 servlet 集,因为这是一个只有 Jetty 真正知道的值。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 2021-06-01
  • 2013-09-03
  • 2021-10-31
  • 1970-01-01
  • 1970-01-01
  • 2013-04-11
相关资源
最近更新 更多