我正在研究我们拥有身份验证机制的项目。我们在身份验证机制中遵循以下步骤。
wait()
方法使当前线程等待。 notify()
方法调用到先前等待的线程并发送成功作为响应,用户将进入我们的系统。 notify()
方法调用到先前等待的线程并发送失败作为响应并向用户显示无效凭据消息。 一切正常,但最近我们转移到了集群环境。我们发现有些线程即使在用户回复后也没有得到通知,并且等待时间不受限制。
服务端,我们使用的是Tomcat 5.5,我们使用的是The Apache Tomcat 5.5 Servlet/JSP Container,制作tomcat集群环境。
答案::可能的问题和解决方案
可能的问题是集群环境中有多个 JVM。现在,我们还将集群 Tomcat URL 与生成的字符串一起发送到用户 Android 应用程序。
当用户单击回复按钮时,我们将生成的字符串与集群 Tomcat URL 一起发送,因此在这种情况下,两个请求都将发送到同一个 JVM,并且工作正常。
但我想知道是否有针对上述问题的单一解决方案。
此解决方案存在问题。 集群Tomcat死机怎么办? 负载均衡器将向第二个集群 Tomcat 发送请求,再次出现同样的问题。
最佳答案
您的问题的根本原因是 Java EE 旨在以不同的方式工作 - 尝试阻塞/等待服务线程是重要的禁忌之一。我会先说明原因,然后说明如何解决问题。
Java EE(Web 层和 EJB 层)旨在能够扩展到非常大的规模(集群中有数百台计算机)。但是,为了做到这一点,设计人员必须做出以下假设,这些假设是对如何编码的特定限制:
如果我们遵循这些规则,Java EE 容器可以成功管理集群,包括关闭节点、启动新节点和迁移用户 session ,而无需任何特定的开发人员代码。开发人员编写图形界面和业务逻辑——所有“管道”都由可配置的容器功能管理。
此外,在运行时,Java EE 容器可以由一些非常复杂的软件监控和管理,这些软件可以跟踪实时系统上的应用程序性能和行为问题。
< snark >好吧,这就是理论。实践表明有一些非常重要的限制被遗漏,这导致了 AOSP 和代码注入(inject)技术,但那是另一回事了
[关于这个,网上有很多讨论。一个专注于 EJB 的在这里:Why is spawning threads in Java EE container discouraged?对于 Tomcat 等 Web 容器也是如此]
对不起,这篇文章 - 但这对你的问题很重要。由于线程的限制,您不应阻塞 Web 请求以等待另一个稍后的请求。
当前设计的另一个问题是,如果用户与网络断开连接、电量耗尽或只是决定放弃,会发生什么情况?大概你会超时,但多久后?也许对某些客户来说太早了,这会导致满意度问题。如果超时时间过长,您最终可能会阻塞 Tomcat 中的所有工作线程,并且服务器将卡住。这会使您的组织面临拒绝服务攻击。
编辑:在发布了更详细的算法描述后改进了建议。
尽管上面讨论了阻塞 Web 工作线程的不良做法以及可能的拒绝服务,但很明显,用户会看到一个很小的时间窗口来对 Android 手机上的通知使用react,这可以保持合理的小以增强安全性。这个时间窗口也可以保持在 Tomcat 的响应超时以下。所以可以使用线程阻塞方法。
有两种方法可以解决此问题:
对于方法 1,浏览器通过对 Tomcat 上的 Web 服务的 AJAX 调用通过 Javascript 轮询服务器; AJAX 调用返回
True
如果 Android 应用程序已通过身份验证。优点:客户端,在服务器上实现最少,在服务器上没有线程阻塞。缺点:在等待期间,您必须频繁调用(可能每秒调用一次 - 用户不会注意到这种延迟),这相当于大量调用和服务器上的一些额外负载。对于方法 2,还有一个选择:
Object.wait()
阻塞线程可选地将节点 ID、IP 或其他标识符存储在共享数据存储中:如果是这样,则接收 Android 应用程序授权的节点需要:Object.notify
在正确的线程上 Object.notify()
在正确的线程上。 关于java - Tomcat集群环境的架构问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14010765/