【问题标题】:Tomcat's behaviour when two simultaneous requests come from same ip当两个同时请求来自同一个 ip 时 Tomcat 的行为
【发布时间】:2011-02-16 07:04:28
【问题描述】:

当我尝试同时向我的服务器 (http://myserver) 运行 2 个 wget 命令时,tomcat 似乎分配了两个线程来处理它们。但是我相信当tomcat同时从同一个IP地址接收到两个请求时,它不会创建一个新线程来处理第二个请求,因为它认为这两个请求都来自同一个会话。

如果我想检查两个线程是否相同或不同,使用 thread.getId() 是唯一的方法吗?我认为这个 id 可能会被新线程重用。除了threadid之外,是否存在线程的任何唯一属性来检查其身份?

【问题讨论】:

  • afaik,tomcat 在单独的线程中处理每个请求。参考this

标签: java tomcat


【解决方案1】:

我建议永远不要依赖线程来识别它们的来源。 没有关于线程的 Servlet 规范保证,并且较新的 Servlet 规范实现使用了 NIO。你在薄冰上滑冰。

【讨论】:

    【解决方案2】:

    Web 服务器几乎总是会为多个并发请求分配多个线程(或进程),因为客户端在不必等待每个响应时可以更快地工作。

    但是,较新的服务器可能会使用异步 IO (nio),并且单个线程可以同时为多个客户端提供服务。

    是的,Thread.getId() 是一种识别线程的方法。

    会话 ID 是用于识别来自单个客户端的请求的机制。

    IP 地址不是这样做的好方法,因为当多台机器隐藏在 NAT 后面时,可能会暴露同一个 IP。

    【讨论】:

    • 谢谢。但我猜如果第一个线程死了,JVM 可能会将一个线程的 id 重用于第二个线程。
    • 是的,Java 服务器经常在一个线程完成其循环后(不是“死亡”),为多个请求重用同一个线程;但不是同时。 (尽管 Java 异步 IO [nio] 允许这样做。)
    【解决方案3】:

    我相信 Tomcat 总是会创建一个新的执行线程,无论它是否来自同一个 IP。如果在特定 IP 上运行的客户端应用程序具有通过 session-id 发送的机制,那么 Tomcat 将简单地将相同的会话上下文与请求线程相关联[使其有状态]。

    在您的情况下,您需要自定义 wget 以保留 session-id [Tomcat web-app 可能通过 cookie 或作为 url 参数发送它 - @987654321 @]。 wget 然后需要将其与后续请求一起发送回[url 重写并包含jsessionid 参数,或交换cookie]。这样,Tomcat 将能够处理来自唯一客户端实例的每个请求并将状态与其关联。

    【讨论】:

    • 谢谢,知道了。我只是习惯于在来自同一个 m/c 的 2 个同时请求上测试 tomcat 的行为。另外,如果我想知道线程的身份,我可能不会使用 thread.getId() 因为 ID 可以重复使用。还有其他方法可以检查吗?
    • 听起来您正在尝试使用 Tomcat 处理线程作为为给定客户端保持状态的一种方式? Tomcat 将使用线程池并重用这些线程。保持状态的唯一方法是在请求参数中提供它或使用 cookie 来识别会话。
    • 如图所示,想办法提取和交换jsessionid
    • 我没有尝试使用线程来进行数据持久化。现在明白了,不管请求的来源是什么,tomcat都会分配新的线程进行处理;对于相同的来源,上下文是共享的谢谢。
    猜你喜欢
    • 2012-03-17
    • 2013-01-21
    • 2015-02-14
    • 2012-06-23
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    相关资源
    最近更新 更多