假设我将我的web应用程序部署在亚马逊网络服务或GAE上,并且我在JSF中的应用程序有一个带有方法"void ApplicationScoped ( List)“"List getList()”的单例List Bean。当用户修改列表时,我从SessionScoped bean调用此方法。我希望通过向所有用户推送通知消息来确保所有用户在自己的会话中获得更改,以便他们可以再次获得列表。如果亚马逊网络服务或广域网的负载均衡器将应用程序拆分成几个实例,他们如何管理这个单一的ApplicationScoped bean?单例的实例是否很多?它们是如何同步的?一个实例有不同信息的风险吗?
我认为参与负载平衡的每个服务器中的所有应用程序实例都需要以某种方式更新,但这将扼杀负载平衡的目的,因为工作将被复制到任何地方。单例工作可能不是负载均衡的,但我不知道。文档非常广泛,而且很难熟悉。
@ManagedBean( name = "theModelBean",
eager = true )
@Singleton
@ApplicationScoped
public class ModelBean {
ArrayList<Data> theList;
public List<Data> getList(){
return theList;
}
public void setList( List<Data> aList ) {
this.theList = aList;
}
}
@ManagedBean( name = "theController" )
@SessionScoped
public class Controller {
@ManagedProperty(value = "#{theModelBean}")
private ModelBean theModelBean;
public foo(){
ArrayList<Data> list = new ArrayList<>;
list.add( new Data() );
theModelBean.setList( list );
}
}
我希望负载平衡不会干扰我的逻辑,希望它能以透明的方式为我处理所有事情。否则,我可能不得不让theModelBean在每次列表更改时将列表写入数据库,并在每次从会话请求列表时从数据库中获取列表。
发布于 2019-05-24 02:28:34
我将忽略您问题中的“负载平衡”/“负载平衡”术语,并假设您实际上是指“集群”/“集群”。如下所示:将相同的WAR文件部署到多个服务器,这些服务器都位于单个代理之后(代理执行实际的负载平衡,但负载平衡本身并不是所观察到的问题的原因)。
是的,集群中的每个服务器都将获得自己的任何“应用程序范围”bean的实例。这不仅包括JSF,还包括@javax.faces.bean.ApplicationScoped
@javax.enterprice.context.ApplicationScoped
和@javax.inject.Singleton
以及EJB @javax.ejb.Singleton
。
通常的方法实际上是跟踪单个公共数据源中的共享数据,该数据源由集群的所有服务器使用。通常使用基于SQL的RDBMS来实现这一点。通常,您在每次请求/视图时都会触发一个SQL查询,以便从数据库中获取最新的数据。如果你使用JPA来做这件事,你通常会使用二级缓存来缓存数据,这样就可以减少DB的命中率。这可以在整个群集范围内进行配置。
如果数据是不可变的(即在创建后是只读的),那么在DB中保存的另一种方法是依赖会话持久性。有一个@SessionScoped
bean,它在writeObject()
期间从@ApplicationScoped
bean中读取,并在readObject()
期间写入@ApplicationScoped
。一个真实的示例是在JSF <f:websocket>
和OmniFaces <o:socket>
背后的代码中实现的。
https://stackoverflow.com/questions/56278403
复制相似问题