简体   繁体   English

在分布式Java Web应用程序中,如何在所有机器上的所有servlet之间共享值?

[英]In a distributed Java web application, how to share a value between all servlets on all machines?

If I have a distributed java web application deployed in a cluster and I have say 10 servlets & 10 JSPs running the show, and if I want to share some data, say a variable or a simple POJO between all the threads of all the servlets on all the machines, what is the way to do it? 如果我在集群中部署了一个分布式Java Web应用程序,并且说有10个servlet和10个JSP运行该节目,并且如果我想共享一些数据,请在上面所有servlet的所有线程之间说一个变量或简单的POJO。所有机器,该怎么做?

No framework like Spring/Struts is used and let's say I'm only using the basic Servlets and JSPs. 没有使用像Spring / Struts这样的框架,可以说我只使用基本的Servlet和JSP。 Usually we think about ServletConfig, ServletContext, HttpSession and HttpServletRequest objects to store information which needs to be passed/shared from one component to another. 通常,我们考虑使用ServletConfig,ServletContext,HttpSession和HttpServletRequest对象来存储需要从一个组件传递/共享到另一个组件的信息。 ServletContext has the largest scope because it's accessible from all the servlets and JSPs in the web app. ServletContext具有最大的范围,因为可以从Web应用程序中的所有Servlet和JSP对其进行访问。 But in case of distributed application I guess ServeltContext object would be created one per JVM, so even for a single web app every machine in the cluster will have a different java object for ServletContext, correct? 但是,在分布式应用程序的情况下,我估计每个JVM将创建一个ServeltContext对象,因此,即使对于单个Web应用程序,集群中的每台计算机都将为ServletContext使用不同的Java对象,对吗? So in such a scenario what should be done to share a POJO between all the servlets on all the machines of a single web app? 因此,在这种情况下,应该怎么做才能在单个Web应用程序的所有计算机上的所有Servlet之间共享POJO?

If it's not possible using plain Servlets and JSP, do any frameworks make is possible? 如果不能使用普通的Servlet和JSP,是否有任何框架可以实现? Would appreciate any inputs. 将不胜感激任何投入。 Many thanks! 非常感谢!

In a distributed architecture, it is useful to think beyond objects and think about "services". 在分布式体系结构中,考虑对象之外的内容并考虑“服务”很有用。 There are several possible solutions for this but all of them would include some form of service you could access from any of your 10 nodes. 有几种可能的解决方案,但是所有解决方案都将包含您可以从10个节点中的任何一个访问的某种形式的服务。

So, you could for example create an 11th machine and host an API for putting and getting objects (values/maps/etc?). 因此,例如,您可以创建第11台计算机并托管用于放置和获取对象(值/地图/等)的API。 That would create a shareable region between the nodes. 这将在节点之间创建一个可共享区域。

However, this opens a whole world of possible issues if not done correctly, because you need to think about sinchronization, deadlocks, dirty reads and other concurrent processing stuff in a cross-JVM mindset. 但是,如果您未正确完成操作,那么这可能会带来很多问题,因为您需要考虑跨JVM思维方式中的同步,死锁,脏读和其他并发处理问题。

Also, many systems sinchronize their nodes via the database, but this approach is somehow deprecated nowadays in favor of the more recent "microservices" approach where persistence is distributed, not monolithic. 同样,许多系统通过数据库同步其节点,但是如今以某种方式不赞成使用此方法,而采用了最新的“微服务”方法,其中持久性是分布式的,而不是整体式的。

You can use hazelcast, a framework as memcache but with auto-discovery for clustering . 您可以使用hazelcast(框架作为memcache,但具有自动发现集群功能)。 I use to used for the session and cache sharing on my Amazon cluster and works like a charm http://hazelcast.com/use-cases/caching/ 我曾经用来在我的Amazon集群上进行会话和缓存共享,并且像一个迷人的http://hazelcast.com/use-cases/caching/

But if you want keep in simple you can always use as I said before memcached http://memcached.org/ 但是,如果您想保持简单,可以随时按照我在memcached http://memcached.org/之前所说的那样使用

you are using spring already, so maybe spring session project is a right choice for you - http://projects.spring.io/spring-session/ . 您已经在使用spring,因此spring session project可能是您的正确选择-http://projects.spring.io/spring-session/ For sure its the easiest one to run. 当然,它是最容易运行的一种。

Sharing things between servers is: 服务器之间共享的内容是:

  • error prone 容易出错
  • sometimes complicated 有时很复杂

The most common thing to want is user session data across a load balanced cluster of servers. 最常见的需求是跨负载平衡的服务器群集的用户会话数据。 If someone is talking to one server, then gets load balanced to a different server, you want to keep their session going. 如果某人正在与一台服务器通信,然后使负载平衡到另一台服务器,则您要保持他们的会话继续进行。 Tomcat Clusters does this, and it's already built in. Tomcat Clusters可以做到这一点,并且它已经内置。

https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html https://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html

The last time I played with that, it was touchy; 我上一次玩这个游戏很容易。 don't count on session replication always working in any servlet container, and you'll be better off. 不要指望会话复制始终在任何servlet容器中都可以正常工作,这样您会更好。 Also, session replication is crazy expensive; 而且,会话复制非常昂贵。 once you're past a few machines, the cost (in RAM) of having all session data everywhere... starts to add up quickly, and you can't add more users easily anymore. 一旦您经过几台计算机,所有会话数据随处可见的成本(在RAM中)便开始迅速增加,您再也无法轻松地添加更多用户。

Wanting to share things between multiple JVMs is a code smell; 想要在多个JVM之间共享东西是一种代码味道。 if you can architect around it, do so. 如果您可以围绕它进行设计,那就这样做。 But other than clustering, you have the two normal options: 但是,除了群集以外,您还有两个常规选项:

  • a database. 数据库。 Tried, true, tested; 尝试过,真实,经过测试; keep details that need to change there. 保留需要更改的细节。
  • an in-memory store. 内存中的商店。 If it gets called on every request, and/or must be really fast for whatever reason, just consider keeping it in memory; 如果在每个请求上都调用它,并且/或者由于某种原因必须非常快,则只需考虑将其保留在内存中即可; memcached is a multi-machine in-memory key-value-store that does just this. memcached是执行此操作的多机内存键值存储。

The simplest solution is ConcurrentHashMap https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html 最简单的解决方案是ConcurrentHashMap https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html

If you want to scale your application - you will need something like hazelcast - http://hazelcast.com/ 如果你想扩展您的应用程序-你会需要像hazelcast - http://hazelcast.com/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM