Создает ли балансировка нагрузки на стороне сервера веб-приложения несколько экземпляров одиночного компонента JScF AppScoped? - PullRequest
0 голосов
/ 23 мая 2019

Предположим, я развернул свое веб-приложение в AWS или GAE, а в моем приложении в JSF имеется компонент Singleton ApplicationScoped Bean с методами "void setList (List)" "List getList ()". Я вызываю этот метод из компонента SessionScoped, когда пользователь вносит изменения в список. Я хочу убедиться, что все пользователи получат изменения в своем собственном сеансе, отправив им уведомление, чтобы они могли снова получить список. Если балансировщик нагрузки AWS или GAE разделяет приложение в нескольких случаях, как они управляют этим одноэлементным компонентом ApplicationScoped? Много ли экземпляров синглтона? как они синхронизируются? есть ли риск, что один экземпляр имеет другую информацию?

Я предполагаю, что все экземпляры приложения на каждом сервере, участвующем в балансировке нагрузки, должны быть как-то обновлены, но это уничтожит цель балансировки нагрузки, поскольку работа будет реплицирована повсеместно. Возможно, что работа синглтона не сбалансирована по нагрузке, но я не знаю. Документация очень обширная и с ней трудно ознакомиться.

@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 записывать список в базу данных каждый раз, когда он изменяется, и получать его оттуда каждый раз, когда его запрашивают из сеанса.

1 Ответ

2 голосов
/ 23 мая 2019

Я проигнорирую термины «балансировка нагрузки» / «балансировка нагрузки» в вашем вопросе и предположу, что вы на самом деле имели в виду «кластеризация» / «кластеризация».Как в случае: один и тот же файл WAR развертывается на нескольких серверах, которые находятся за одним прокси-сервером (который выполняет фактическую балансировку нагрузки, но сама балансировка нагрузки не является причиной наблюдаемой проблемы).

Да,каждый сервер кластера получит свой собственный экземпляр любого компонента в области приложения.Это включает в себя не только JSF @javax.faces.bean.ApplicationScoped, но также CDI @javax.enterprice.context.ApplicationScoped и @javax.inject.Singleton и EJB @javax.ejb.Singleton.

. Обычный подход заключается в отслеживании общих данных в одной общей информации.Источник, который используется всеми серверами кластера.Обычно для этого используется СУБД на основе SQL.Обычно вы запускаете SQL-запрос для получения самых последних данных из БД при каждом запросе / просмотре.Если вы используете для этого JPA, вы обычно используете кэш 2-го уровня для кэширования данных, чтобы уменьшить количество обращений к БД.Это можно настроить для всего кластера.

Если данные являются неизменяемыми (то есть доступны только для чтения после создания), то альтернативный подход к сохранению в БД - полагаться на постоянство сеанса.Имейте боб @SessionScoped, который читает из @ApplicationScoped во время writeObject() и пишет, если отсутствует в @ApplicationScoped во время readObject().Один пример из реальной жизни реализован в коде JSF <f:websocket> и OmniFaces <o:socket>.

...