【问题标题】:How are asynchronous requests handled by servlets?servlet 如何处理异步请求?
【发布时间】:2014-07-11 00:23:04
【问题描述】:

如果这是一个不好的问题,我提前道歉。

我是后端开发的新手,我正在尝试使用 Java servlet 使用 GAE 构建即时消息服务。

我假设发送消息的过程是这样的: 1. 客户端发送 JSON 文件到 servlet。 2.Servlet解析JSON文件并将消息归档到数据库。

所以我的问题是:

  1. 如果在 servlet 正在将上一条消息保存到数据库的过程中,下一个用户尝试发送另一条消息会发生什么?

  2. 由于用户请求的到达与servlet周期不同步,新的请求会不会丢失?

  3. 是否会有某种机制对请求进行排队,或者我必须自己实现?

我想我真的很困惑分布式系统中不同功能之间的异步请求是如何工作的。

而且,如果有任何关于后端设计模式的推荐读物?还是只是一般性的介绍?

非常感谢!

【问题讨论】:

  • 全部基于 HTTP。根据您为每个新请求使用的框架,将实例化一个新线程。了解 HTTP 和 servlet

标签: java google-app-engine servlets backend


【解决方案1】:

请阅读有关 Java Web 技术、Web 容器和 Servlet 的深入讨论主题的官方教程: http://docs.oracle.com/javaee/6/tutorial/doc/bnafd.html

但是要回答你的问题:

  1. 当另一个 HTTP 请求进来时,将创建一个新线程 Web 容器,并将同时运行您的 servlet。
  2. 将同时处理新请求
  3. 答案取决于您的具体问题、性能和 SLA 要求。最简单的解决方案是解析每个请求并将其写入数据库。如果您正在处理大量同时进来的请求,我建议您就该主题开始一个全新的讨论。

【讨论】:

    【解决方案2】:

    您需要确切地知道“线程”是什么?当另一个请求发送到 Servlet。像tomcat这样的容器会为这个请求分配另一个线程。每个线程都相互独立。

    【讨论】:

      【解决方案3】:
      1. 服务器请求将并行运行,您的代码可能会同时访问/编辑相同的数据。您应该使用Datastore transactions 来防止数据损坏。

      2. 不,请求是独立的,它们是并行运行的。

      3. 可以在代码中使用任务队列来使更新按顺序运行,但我强烈建议您不要这样做:首先任务队列会使您的请求加倍,其次它将强制分布式并行系统顺序运行,基本上否定了 AppEngine 的全部目的。

      并行处理在服务器编程中必不可少 - 它们使服务器能够处理大量请求。您应该编写考虑到这一点的代码 - 在这些情况下使用数据存储事务来防止可能的数据损坏。

      【讨论】:

        【解决方案4】:

        在 servlet 生命周期中,init() 和 destroy() 方法只被调用一次 - 但 service() 将在每次新请求到来并命中应用程序时被调用,并且将与 servlet 的新实例共享请求通过不同的线程。因此,创建 servlet 最基本的规则之一是不要在 servlet 类中创建全局变量。

        您的变量可以被任何其他类读取/写入。您无法控制以确保他们都用它做明智的事情。其中一个可能会覆盖它/错误地增加它,等等

        这是每个 JVM 的一个 servlet 实例。因此,线程可能会尝试同时访问它。因为它是全局的,并且您没有提供任何同步/访问控制,所以它不是线程安全的。此外,如果您曾经在具有不同 JVM 的某种集群中运行 servlet,那么变量将不会在它们之间共享,并且您将拥有多个 loginAttempt 变量。

        【讨论】: