3

強い負荷をかける多くのユーザーがいると予想される Java Web アプリケーションがあります。同時に、多くの処理を必要とするいくつかのスケジュールされたタスクがあり、このスレッドを開始し、Web 要求の高負荷に応じて一時停止する自動化された方法を探していました。このタスクに使用できるソリューションはありますか?

4

1 に答える 1

1
  • javax.servlet.Filterフィルターによってインクリメントおよびデクリメントされる静的カウンターで を使用します。このようにして、現在の負荷 (= 現在処理されているリクエストの数) を知ることができます。
  • および と一緒に@Startup使用して、定期的なタスク (または Quartz などの他のスケジューラー) を実行します。たとえば、5 分ごとです。@Singleton@Schedule
  • そのタスクで、負荷を確認します。低い場合は、実際のタスクを開始するのに十分です。
  • たとえば、実行中のタスクの現在の負荷を監視し、一時停止または終了することもできます。

たとえば、実際のタスクがキューの内容を処理している場合、これは機能します。

それ以外の場合は、最初のタスクの頻度が実際のタスクの頻度よりも高い場合、または実際のタスクが 1 日に 1 回 (または少なくとも 1 日 1 回) のみ実行されるようにする必要がある場合は、簿記を行う必要がある可能性があります。 )。

コード例:

フィルター:

@WebFilter("/*")
public class LoadFilter implements Filter {
    private final static Logger log = Logger.getLogger(LoadFilter.class
            .getName());

    private final static AtomicInteger load = new AtomicInteger();

    public static int getLoad() {
        return load.get();
    }

    public void init(final FilterConfig fc) throws ServletException {
        log.info("Hello from init()");
    }

    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {

        final int currentLoad = load.incrementAndGet();
        try {
            log.info("Current load (enter): " + currentLoad);
            chain.doFilter(req, resp);
        } finally {
            final int newLoad = load.decrementAndGet();
            log.info("Current load (exit): " + newLoad);
        }
    }

    public void destroy() {
        log.info("Bye from destroy()");
    }
}

そしてEJB

@Singleton
@Startup
public class StartupSingleton {
    @Schedule(second = "*/10", minute = "*", hour = "*", persistent = false)
    public void execute() {
        // Check load; if low, run task(s)
        if (LoadFilter.getLoad() < 10) {
            // Run tasks
        }
    }
}
于 2013-09-04T09:14:43.590 に答える