当前位置: 代码迷 >> J2EE >> 疯掉的定时任务,该怎么处理
  详细解决方案

疯掉的定时任务,该怎么处理

热度:33   发布时间:2016-04-17 23:33:40.0
疯掉的定时任务

package tools;

import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.log4j.Logger;

import oa.action.GovIndexAction;


public class TaskFilter implements Filter{



static Logger log = Logger.getLogger(TaskFilter.class);

    public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);    

public void destroy() {

}

public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOExceptionServletException {

}

public void init(FilterConfig cfg) throws ServletException {

AutoReceiveTask task = new AutoReceiveTask ();
task.ctx = cfg.getServletContext();
//设置任务计划,启动和间隔时间
scheduledExecutorService.scheduleAtFixedRate(task, 3*60, 10*60, TimeUnit.SECONDS);
}
//自动接收
class AutoReceiveTask implements Runnable{
private ServletContext ctx;
public void run() {
try{
GovIndexAction.autoReceive(ctx);
}catch (Exception e) {
log.error(e.getMessage());
}
}
}
}

//autoReceive方法

public static void autoReceive( ServletContext ctx) {
log.info("定时任务!");
HttpClient httpclient = new DefaultHttpClient();
try {
do someting...
} catch (Exception e) {

log.error("error:"+e.getMessage());
e.printStackTrace();
     }
}
}

//一个定时任务,每隔一段时间(一周、一个月),就会停掉,重启tomcat又可以了。在任务停掉的时间附近,也没有任何异常日志的记录。好蛋疼
------解决思路----------------------
不是很确定问题出现在哪里,但是可以做如下两件事情: 

1. 监控一下Queue:实际上Executors创建的是ScheduledThreadPoolExecutor这个类的对象,做强制类型转换然后调用 BlockingQueue<Runnable> getQueue() 这个方法,定时将Queue的数量输出到日志里面,看任务队列是否有变化; 

2. 监控RejectException:实际上默认的线程池有个个人认为很不好的地方,就是大家都习惯于使用Executors创建线程池,所以很多人都不知道线程池实际上有时候会拒绝掉一个任务的(具体算法不说了),而默认的处理方式是直接丢弃,解决的方法是直接使用public ScheduledThreadPoolExecutor(int corePoolSize,                                      RejectedExecutionHandler handler)这个构造器,将拒绝掉的线程监控起来(比如记录到日志里面),这样就可以知道哪些任务是拒绝了的。 


以上No.1是看线程池是否还在正常工作,No.2是看是否任务有没有被正常执行(是否被抛弃了)。
------解决思路----------------------
最好能观察、总结出,触发这一事件的原因,这样才好分析啊
------解决思路----------------------
是不是内存过多,访问数据库数量太多,
断开连接了!
------解决思路----------------------
用quatuz,在spring里面配置好即可,跟linux/unix的cronjob一样配置

你找这个问题的原因找1个月,换到quatuz框架上估计1周就搞定了,以后就不用管了
  相关解决方案