В последнее время у нас происходят сбои сервера Domino. Мы обнаружили, что сбои вызваны параллельными вызовами одной и той же страницы Xpage одним и тем же пользователем.
Теперь мы связали вызовы Ajax с Xpage, чтобы они были синхронными, и сбои прекратились.
Поскольку мы хотели бы перейти к большему количеству вызовов Ajax к Xpages (стиль Xagent) в будущем развитии, мы хотели бы знать, почему это происходит и как это решить. Мы не можем найти код в javacode, который необходимо синхронизировать.
Это известная проблема. Как мы можем обойти эту проблему, не выполняя все вызовы синхронно?
Резюме решения, которое вызывает ошибку:
Веб-страница вызывает Xpage, который вызывает XAgent через SSJS в afterRenderResponse. Javaclass читает Post Request и отправляет JSON обратно через FacesContext.
Подробное описание:
Мы вызываем Xpage через вызовы Ajax POST. Иногда эти вызовы выполняются в отношении одной и той же Xpage одним и тем же пользователем параллельно. (Именно тогда мы получаем сбои)
IE в javascript (Angular):
Код, который крашит сервер:
$http.post('xpage1.xsp',data1,config).then(){
Do stuff with response from call1
}
$$http.post('xpage1.xsp',data2,config).then(){
Do stuff with response from call2
}
Код, который работает:
$http.post('xpage1.xsp',data1,config).then(){
Do stuff with response from call1;
$$http.post('xpage1.xsp',data2,config).then(){
Do stuff with response from call2
}
}
где данные - это просто объект, содержащий данные запроса, а конфигурация - это просто конфигурация для HTTP-вызова.
Xpage вызывает javacode в событии AfterRenderResponse Xpage. ((Среда XAgent)
Javacode использует объект FacesContext для чтения запроса и создания ответа. Он читает опубликованный JSON и получает документ. который создает объект Java. Затем мы создаем новый JSON из JavaObject через GSON и отправляем этот JSON в качестве ответа на браузер.
private static FacesContext faccon;
private static ExternalContext extcon;
private static HttpServletRequest request;
private static HttpServletResponse response;
private String logOn = "";
private boolean javaDebuggingOn = false;
public SaveCtrl() {
faccon = FacesContext.getCurrentInstance();
extcon = faccon.getExternalContext();
request = (HttpServletRequest) extcon.getRequest();
response = (HttpServletResponse) extcon.getResponse();
}
public void post() throws IOException {
String processName = className + "." + "post";
response.setHeader("Cache-Control", "no-cache");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(200); // HTTP OK
ResponseWriter writer = faccon.getResponseWriter();
//Handle JSON in POST Request
String requestBody = extractPostRequestBody(request);
String action = requestData.get("action");
//Send JSON response
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create();
List myList = getList(action);
String jsonOut= gson.toJson(myList );
writer.write(jsonOut);
writer.endDocument();
faccon.responseComplete();
}
Задача HTTP аварийно завершает работу и перезапускается
Упоминается ли в log.nsf или журналах в data/IBM_TECHNICAL_SUPPORT что-либо, имеющее отношение к сбою (например, проблемы с памятью)?
Нет, мы отслеживаем память и память jvm, проблем с памятью и подробностей в аварийных дампах, которые мы отправили в IBM, нет. единственная подсказка в том, что он указывает на xpage, который мы вызываем как на проблему
Какая версия Домино?
9.01 FP7, а также 9.01 FP10
Как вы гарантируете, что объекты в FacesContext хранятся в потокобезопасном виде? Для меня полное описание ошибки звучит как проблемы параллелизма (в вашем коде)...
Добавлен код в Вопрос о том, как я ссылаюсь на FacesContext. Может быть, не правильный путь. Какой код здесь синхронизировать?
Извините, я думал, что вы что-то сохраняете в FacesContext ("...и отправляете JSON обратно через FacesContext...").
Но вызов XAgent из XPage с веб-сайта, и когда это делается параллельно для одного пользователя, это приводит к сбоям сервера: это проблема параллелизма. В XPages есть некоторые средства защиты от DOS, которые «блокируют» запросы от одного и того же пользователя.
Добавил только часть получения и записи Json в код.
Значит, есть встроенная защита от одновременного запуска одной и той же Xpage для одного и того же пользователя? Тогда эта защита, похоже, не работает, как если бы она работала одновременно с ее сбоем.
Нет, существует защита от запуска слишком большого количества потоков HTTP для одного и того же пользователя. Затем запросы будут заблокированы до тех пор, пока поток не будет завершен. В вашей архитектуре вы создаете запрос в самом запросе. Что делать, если запрос заблокирован из-за слишком большого количества запросов? Тайм-аут? Как вы получаете доступ к XAgent из своего XPage? Здесь много открытых вопросов. Что вы пытались изолировать проблему?
Мы не вызываем запрос внутри запроса. Они вызываются асинхронно, поэтому другой вызов не вызывается внутри другого вызова. Приведенный выше JS — это не полный код, а лишь краткое изложение логики. Я могу вставить весь код JS, чтобы вы могли видеть. У нас есть одна Xpage, на которой работает js. код на кнопке. Этот код нажатия кнопки создает 2 отдельных асинхронных вызова URL-адреса Xpage. Этот Xpage вызывает код Java в AfterRenderResponse. IE просто используется как служба REST. Ответ возвращается в формате JSON.
«Веб-страница вызывает Xpage, которая вызывает XAgent через SSJS в afterRenderResponse». Я ухожу.
Это обычный вызов XAgent. IE вызывает Xpage с помощью SSJS в ответе после рендеринга. Код SSJS — это вызов класса Java с методом запуска, который возвращает JSON. Не уверены, что это классифицируется как запрос в рамках запроса?
Вы устанавливаете viewState = "nostate"
на своей странице XPage? Если нет, вы сериализуете и десериализуете деревья компонентов для страницы, и они совместно используются. Это может вызвать проблемы, и я могу понять, почему это может привести к сбоям. Если вы используете его только для доступа к REST, нет необходимости хранить деревья компонентов, поэтому установите его в свойствах XSP приложения. По умолчанию он не включен, поскольку типичные приложения XPages должны хранить историю страниц. Но вы используете его не как типичное приложение XPages, а как простое сервисное приложение REST.
см. stackoverflow.com/questions/36062424/… для получения дополнительных идей
viewState = "nostate" установлен на Xpage
Ответ заключался в том, что при чтении кода и записи ответа произошла ошибка, когда он был изменен на компонент REST, вызовы которого выполняются параллельно.
Вылетает ли Domino полностью, так что вам приходится его перезапускать?