分享

quartz执行卡死

 WindySky 2017-09-04

在quartz中经常会碰到由于网络问题或者一些其他不稳定因素导致的线程卡死问题,这往往会导致数据处理的延时。而有时候一时无法定位到卡死的原因,为了降低系统风险,我们就会希望有一个超时机制,当执行超时时强制中断该操作。下面就举个例子,ftp协议不稳定,当连接ftp上传下载数据时有时候会遇到不可知的因素会导致卡死,比如说主动被动切换,服务器连接数满等等,现在我们使用java提供的动态代理以及Future的超时机制来解决延时问题。代码如下:

Java代码  收藏代码
  1. public class FtpClientProxy implements InvocationHandler  {  
  2.     private static ExecutorService executor = Executors.newCachedThreadPool();  
  3.     private FtpClient target;  
  4.     private static String interceptorNames="uploadFile,chdir,listFiles,downloadFile,existDir,mkdir,rename";  
  5.     private static final  String THREAD_TIMEOUT_CONFIG="THREAD_TIMEOUT_CONFIG";  
  6.     private static final  String METHOD_INTERCEPTOR_CONFIG="METHOD_INTERCEPTOR_CONFIG";  
  7.     private static int threadTimeout=7200;  
  8.     private static final Logger logger=Logger.getLogger(FtpClientProxy.class);  
  9.       
  10.     /**     
  11.      * 创建一个新的实例 FtpClientProxy.       
  12.      */  
  13.     public FtpClientProxy() {  
  14.         try {  
  15.             String timeoutConfig=UspcUtil.getSysConfigValue(THREAD_TIMEOUT_CONFIG);  
  16.             if(StringUtils.isNotBlank(timeoutConfig)){  
  17.                 threadTimeout=Integer.parseInt(timeoutConfig);  
  18.             }  
  19.             interceptorNames=UspcUtil.getSysConfigValue(METHOD_INTERCEPTOR_CONFIG);  
  20.         } catch (Exception e) {  
  21.             logger.error("获取超时配置THREAD_TIMEOUT_CONFIG出错",e);  
  22.         }  
  23.          
  24.     }  
  25.       
  26.     /**   
  27.      * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])     
  28.      */  
  29.     @Override  
  30.     public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {  
  31.         Object result = null;  
  32.         String methodName=method.getName();  
  33.         if(StringUtils.isNotBlank(interceptorNames)&&interceptorNames.contains(methodName)){  
  34.   
  35.             Future<Object> future = executor.submit(new Callable<Object>() {  
  36.                   
  37.                 @Override  
  38.                 public Object call() throws Exception {  
  39.                     logger.debug(method.getName()+"代理方法执行开始");  
  40.                     return method.invoke(target, args);  
  41.                 }  
  42.             });  
  43.             try {  
  44.                 result = future.get(threadTimeout, TimeUnit.SECONDS);  
  45.                 logger.debug(methodName+"代理方法执行结束");  
  46.             } catch (TimeoutException e) {  
  47.                 logger.error("执行方法"+methodName+"超时",e);  
  48.                 future.cancel(true);  
  49.                 throw new Exception("执行方法"+methodName+"超时");  
  50.             } catch (Exception e) {  
  51.                 future.cancel(true);// 中断执行此任务的线程  
  52.                 throw new Exception(e);  
  53.             }  
  54.         }else{  
  55.             result=method.invoke(target, args);  
  56.         }  
  57.         return result;  
  58.     }  
  59.       
  60.     /** 
  61.      * 绑定委托对象并返回一个代理类 
  62.      *  
  63.      * @param target 
  64.      * @return 
  65.      */  
  66.     public FtpClient bind(FtpClient target) {  
  67.         this.target = target;  
  68.         // 取得代理对象  
  69.         return (FtpClient) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass()  
  70.                 .getInterfaces(), this);   
  71.     }  
  72. }  

 可以按照配置的时间来进行超时判断,也可以配置拦截的方法。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多