Подтвердить что ты не робот

Spring Ошибка потока веб-потока LockTimeoutException

Мы используем Spring Web Flow (2.0.9) в среде кластеризации Weblogic 10. И в производстве мы получаем много LockTimeoutException: невозможно получить блокировку разговоров через 30 секунд.

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

Пожалуйста, найдите код, который пытается заблокировать FlowController в SWF. То, что я не могу понять, это блокировка на сервлете, к которому обращаются или что-то еще?

Пожалуйста, помогите понять в веб-приложении, когда происходит эта блокировка, какой ресурс действительно заблокирован в SWF?

Чтобы понять концепцию ReentrantLock, см. ссылку ниже.

Что такое блокировка и концепция повторного входа в целом?

Спасибо заранее.

Трассировка стека исключений

org.springframework.webflow.conversation.impl.LockTimeoutException: Unable to acquire conversation lock after 30 seconds
    at org.springframework.webflow.conversation.impl.JdkConcurrentConversationLock.lock(JdkConcurrentConversationLock.java:44)
    at org.springframework.webflow.conversation.impl.ContainedConversation.lock(ContainedConversation.java:69)
    at org.springframework.webflow.execution.repository.support.ConversationBackedFlowExecutionLock.lock(ConversationBackedFlowExecutionLock.java:51)
    at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:166)
    at org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle(FlowHandlerAdapter.java:183)
    at org.springframework.webflow.mvc.servlet.FlowController.handleRequest(FlowController.java:174)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)

Реализация блокировки в SWF

package org.springframework.webflow.conversation.impl;

import java.io.Serializable;
import java.util.concurrent.locks.ReentrantLock;

/**
 * A conversation lock that relies on a {@link ReentrantLock} within Java 5 <code>util.concurrent.locks</code>
 * package.
 * 
 * @author Keith Donald
 */
class JdkConcurrentConversationLock implements ConversationLock, Serializable {

    /**
     * The lock.
     */
    private ReentrantLock lock = new ReentrantLock();

    public void lock() {
        // ensure non-reentrant behaviour
        if (!lock.isHeldByCurrentThread()) {
            lock.lock();
        }
    }

    public void unlock() {
        // ensure non-reentrant behaviour
        if (lock.isHeldByCurrentThread()) {
            lock.unlock();
        }
    }
}
4b9b3361

Ответ 1

Spring Webflow работает как государственная машина, выполняя переходы между различными состояниями, которые могут иметь связанные представления. Не имеет смысла иметь несколько одновременных выполнения переходов, поэтому SWF использует систему блокировки, чтобы удостовериться, что выполнение каждого потока (или разговор) обрабатывает только один HTTP-запрос за раз.

Не зацикливайтесь на концепции ReentrantLock, он просто предотвращает тот же поток, ожидающий блокировки, которую он уже удерживает.

В ответ на ваш вопрос на время обработки запроса выполняется только поток (конкретный экземпляр беседы), который заблокирован Spring Webflow. Сервер будет обрабатывать запросы от других пользователей или даже запросы от одного и того же пользователя к другому исполнению потока.

LockTimeoutException затруднительно для устранения неполадок, поскольку проблема с корнем - это не поток, который бросает исключение. Исключение LockTimeoutException происходит потому, что другой более ранний запрос занимает больше 30 секунд, поэтому было бы неплохо узнать, почему предыдущий запрос занял так много времени.

Рекомендации по устранению неполадок:

  • Внедрение FlowExecutionListener, который измеряет, сколько времени занимает каждый запрос, а также длинные запросы журнала вместе с событием flowId, stateId и переходом, это позволит вам оттачивать длительные запросы.
  • Одним из хороших способов избежать исключения LockTimeoutException является отключение кнопок отправки и ссылок с помощью javascript после нажатия кнопки/ссылки. Очевидно, это не решает проблему начального 30-секундного запроса +.

Вы можете увеличить тайм-аут для исключения LockTimeoutException, но это не решает актуальную проблему и приводит к худшему опыту пользователя. 30-секундные запросы - проблема.

Наконец, вы упомянули:

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

Я предлагаю вам попробовать повторно создать проблему с открытием окна инструментов разработчика браузера, наблюдая вкладку "Сеть", возможно, в фоновом режиме, хранящем блокировку, есть запрос AJAX.

Ответ 2

Попробуйте манипулировать таймаутом. Здесь описано, как это сделать https://jira.springsource.org/browse/SWF-1059. Возможно, это поможет вам найти, где настоящая проблема.