3

我有一个 java web 应用程序,预计会有很多用户对其产生很大的负载。同时,有一些计划任务需要大量处理,我正在寻找一些自动化的方法来启动这个线程并根据 web 请求的高负载暂停它。是否有任何现成的解决方案可用于此任务?

4

1 回答 1

1
  • 将 ajavax.servlet.Filter与静态计数器一起使用,由过滤器递增和递减。这样您就知道当前负载(= 当前正在处理的请求数)
  • 使用@Startup并拥有一个常规任务(或任何其他调度程序@Singleton@Schedule如 Quartz),例如每 5 分钟
  • 在该任务中检查负载。如果它很低,则足以启动真正的任务。
  • 例如,您还可以监视正在运行的任务中的当前负载,并暂停或退出。

例如,如果实际任务正在处理队列的内容,则此方法有效。

否则,如果第一个任务的频率高于实际任务的频率,或者您必须确保实际任务每天只运行一次(或至少每天一次),您可能需要做一些簿记)。

示例代码:

过滤器:

@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 回答