16

Weblogic 10 クラスター環境で Spring Web Flow (2.0.9) を使用しています。そして本番環境では、多くのLockTimeoutException が発生しています: 30 秒後に会話ロックを取得できません。

ワンクリックしかない場合、またはサイト自体のホームページにアクセスしている場合に、上記の例外が発生する理由を理解しようとしています。

SWF で FlowController をロックしようとしているコードを見つけてください。私が理解できないのは、ロックがアクセスされているサーブレットにあるのか、それとも何か他のものなのか?

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's <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();
        }
    }
}
4

2 に答える 2

21

Spring Webflow はステートマシンとして動作し、ビューが関連付けられている可能性のある異なる状態間の遷移を実行します。複数のトランジションを同時に実行しても意味がないため、SWF はロック システムを使用して、各フロー実行 (または会話) が一度に 1 つの HTTP リクエストのみを処理するようにします

ReentrantLock の概念にとらわれすぎないでください。これは、同じスレッドが既に保持しているロックを待機するのを防ぐだけです。

ご質問への回答として、リクエスト処理中に Spring Webflow によってロックされるのは、フロー実行 (特定の会話インスタンス) のみです。サーバーは、他のユーザーからの要求を処理したり、同じユーザーから別のフロー実行への要求を処理したりします。

根本的な問題は例外をスローするスレッドではないため、LockTimeoutException のトラブルシューティングは困難です。LockTimeoutException は、別の以前のリクエストに 30 秒以上かかっているために発生するため、以前のリクエストに時間がかかった理由を調べることをお勧めします。

トラブルシューティングのアイデア:

  • 各リクエストにかかる時間を測定する FlowExecutionListener を実装し、長時間のリクエストを flowId、stateId、および遷移イベントとともにログに記録します。これにより、長時間実行されるリクエストを絞り込むことができます。
  • LockTimeoutException 自体を回避する良い方法の 1 つは、ボタン/リンクがクリックされたら、javascript を使用して送信ボタンとリンクを無効にすることです。明らかに、これは最初の 30 秒以上のリクエストの問題を解決しません。

LockTimeoutException のタイムアウトを増やすこともできますが、それでは実際の問題は解決されず、ユーザー エクスペリエンスが低下します。30 秒のリクエストが問題です。

最後に、あなたは次のように述べました。

ワンクリックしかない場合、またはサイト自体のホームページにアクセスしている場合に、上記の例外が発生する理由を理解しようとしています。

ブラウザの開発者ツール ウィンドウを開いて [ネットワーク] タブを見て、問題を再現することをお勧めします。ロックを保持しているバックグラウンドで実行されている AJAX 要求がある可能性があります。

于 2013-10-10T10:52:46.323 に答える
1

タイムアウトを操作してみてください。これを行う方法について説明しますhttps://jira.springsource.org/browse/SWF-1059。たぶん、これは本当の問題がどこにあるかを見つけるのに役立ちます.

于 2012-04-01T00:16:59.570 に答える