【问题标题】:Configuring Tomcat to only raise one Servlet per application将 Tomcat 配置为每个应用程序仅引发一个 Servlet
【发布时间】:2009-08-04 16:08:27
【问题描述】:

据我了解,为了服务请求,Tomcat 可以创建任意数量的 servlet 副本。

这迫使我的 servlet 没有重量级状态,而是将所有状态存储在(单例)servlet 上下文中。

是否可以将 Tomcat 配置为将我的 servlet 视为单例,并且无论负载如何始终只引发一个 servlet 实例?

【问题讨论】:

    标签: java tomcat servlets


    【解决方案1】:

    根据 Servlet 规范,(v2.4,第 2.2 节“实例数”):

    SRV.2.2 实例数

    对于不在分布式环境中托管的 servlet(默认),servlet 每个 servlet 声明容器必须只使用一个实例。 但是,对于 servlet 实现SingleThreadModel 接口,servlet 容器可以 实例化多个实例以处理繁重的请求负载并序列化请求 到一个特定的实例。

    您的问题的答案很简单:不要实现SingleThreadModel,也不要在web.xml 描述符文件中多次声明您的servlet。

    【讨论】:

    • 相关问题——是否保证容器在调用destroy()后不会保留对servlet的引用?
    • 是的。查看 SRV.2.3.4 部分,服务结束:“一旦对 servlet 实例调用 destroy 方法,容器可能不会将其他请求路由到该 servlet 实例。如果容器需要再次启用 servlet,它必须对 servlet 类的新实例执行此操作。destroy 方法完成后,servlet 容器必须释放 servlet 实例,以便它有资格进行垃圾回收。"
    【解决方案2】:

    您不想在 Servlet 中存储状态的另一个主要原因是,如果您想在集群环境中运行,它会引入同步问题、序列化问题等。如果您不这样做,所有这些都很容易避免'不在 servlet 内部存储状态,而是在会话(或请求)对象中它所属的位置。

    所以真的......你为什么要存储状态?出于某种原因,这是一种“推荐做法”。

    【讨论】:

      【解决方案3】:

      不,我不这么认为。然而,在实践中,tomcat 只会实例化一个 servlet,即使 JavaEE 规范允许它实例化多个。大多数(如果不是全部)MVC 框架都依赖于该假设,并将大量配置状态存储在 servlet 中。

      如果您想安全起见,请不要将您的状态存储在 servlet 中,将其粘贴到另一个使用单例模式的类中,并从您的 servlet 中引用该单例。

      【讨论】:

      • 我喜欢 Spring MVC - 它可以用作对 servlet 的相当薄的包装器,但它为您提供了很多不错的东西,包括依赖注入,它可以让您将共享对象/服务分配给您的控制器(等效到 servlet)而不对它们进行硬编码(这会使测试/维护变得更好)。尝试教程或阅读诸如“Spring in Action”之类的书以开始使用。分离你的控制器和模型逻辑对于良好的 MVC 设计与分离你的视图一样重要(在这里我将你的共享状态和服务算作“模型”)。
      • “JavaEE 规范允许它实例化几个”——这取决于。一个容器(即tomcat)在每个声明中只能实例化一个servlet,除非servlet实现SingleThreadModel接口。
      • 好吧 SingleThreadModel 保证每个线程一个实例,但我不相信省略它可以保证每个容器一个实例。
      • Servlet 规范保证每个容器一个实例,除非您使用 SingleThreadModel。在这种情况下,允许容器多次实例化 servlet。
      【解决方案4】:

      同上 Matt B。在我学到这一课之前,我被严重烧伤过一次。我将状态信息存储在 servlet 对象的静态中。在我们只有一台服务器的测试中,这一切都非常有效。然后我们部署到生产环境中,在那里我们有一个服务器集群,但在我们最终解决之前遇到了非常奇怪的错误。

      使用您的 Session 或 Application 对象。这就是他们的目的。

      故事的寓意:当结构的设计者提供了一个工具并说当你想做 X 时使用这个工具,这可能是有原因的。忽略此类建议要非常谨慎。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-01
        • 2012-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-18
        • 2012-05-05
        相关资源
        最近更新 更多