专栏首页服务化进程quartz执行卡死--强制中断线程

quartz执行卡死--强制中断线程

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

public class FtpClientProxy implements InvocationHandler  {
    private static ExecutorService executor = Executors.newCachedThreadPool();
    private FtpClient target;
    private static String interceptorNames="uploadFile,chdir,listFiles,downloadFile,existDir,mkdir,rename";
    private static final  String THREAD_TIMEOUT_CONFIG="THREAD_TIMEOUT_CONFIG";
    private static final  String METHOD_INTERCEPTOR_CONFIG="METHOD_INTERCEPTOR_CONFIG";
    private static int threadTimeout=7200;
    private static final Logger logger=Logger.getLogger(FtpClientProxy.class);
    
    /**    
     * 创建一个新的实例 FtpClientProxy.      
     */
    public FtpClientProxy() {
        try {
            String timeoutConfig=UspcUtil.getSysConfigValue(THREAD_TIMEOUT_CONFIG);
            if(StringUtils.isNotBlank(timeoutConfig)){
                threadTimeout=Integer.parseInt(timeoutConfig);
            }
            interceptorNames=UspcUtil.getSysConfigValue(METHOD_INTERCEPTOR_CONFIG);
        } catch (Exception e) {
            logger.error("获取超时配置THREAD_TIMEOUT_CONFIG出错",e);
        }
       
    }
    
    /**  
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])    
     */
    @Override
    public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
        Object result = null;
        String methodName=method.getName();
        if(StringUtils.isNotBlank(interceptorNames)&&interceptorNames.contains(methodName)){

            Future<Object> future = executor.submit(new Callable<Object>() {
                
                @Override
                public Object call() throws Exception {
                    logger.debug(method.getName()+"代理方法执行开始");
                    return method.invoke(target, args);
                }
            });
            try {
                result = future.get(threadTimeout, TimeUnit.SECONDS);
                logger.debug(methodName+"代理方法执行结束");
            } catch (TimeoutException e) {
                logger.error("执行方法"+methodName+"超时",e);
                future.cancel(true);
                throw new Exception("执行方法"+methodName+"超时");
            } catch (Exception e) {
                future.cancel(true);// 中断执行此任务的线程
                throw new Exception(e);
            }
        }else{
            result=method.invoke(target, args);
        }
        return result;
    }
    
    /**
     * 绑定委托对象并返回一个代理类
     * 
     * @param target
     * @return
     */
    public FtpClient bind(FtpClient target) {
        this.target = target;
        // 取得代理对象
        return (FtpClient) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass()
                .getInterfaces(), this); 
    }
}

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • springcloud线上发布超时之grpc

    > 上一章我们说到了 springcloud线上发布超时之feign(ribbon饥饿加载) 在本章我们说说grpc的饥饿加载,grpc连接也是一样的问题,发布...

    一笠风雨任生平
  • 通过JMX监控weblogic服务

      JMX是一种JAVA的正式规范,它主要目的是让程序有被管理的功能,那么怎么理解所谓的“被管理”呢?试想你开发了一个软件(如WEB网站),它是在24小时不间断...

    一笠风雨任生平
  • java如何保证一个方法只能执行一次

    我们经常会遇到一些情况需要某一个方法或者操作只执行一次,比如说配置信息加载,如果配置信息需要动态刷新,这个不在适用范围。下面列举几种方式

    一笠风雨任生平
  • Python读取Excel文件并写入数据库

    <pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: bre...

    Python之道
  • JDK源码分析-DelayQueue

    DelayQueue 也是一种队列,它内部的元素有“延迟”,也就是当从队列中获取元素时,如果它的延迟时间未到,则无法取出。

    WriteOnRead
  • Bytom Kit开发辅助工具介绍

    Bytom Kit是一款为了帮助开发者更简单地理解Bytom的开发辅助工具,集合了校验、标注、解码、测试水龙头等功能。

    比原链Bytom
  • 光场立体镜,享受虚拟现实体验远离眩晕

    镁客网
  • Python面向对象编程

    面向对象最重要的概念就是类(Class)和实例(Instance),Java比较熟了,下面贴代码注释

    听着music睡
  • Go vet composite literal uses unkeyed fields

    在使用go vet进行语法检查时, 报了这么个错composite literal uses unkeyed fields

    许杨淼淼
  • SpringCloud 注册中心 Eureka 集群是怎么保持数据一致的?

    服务注册中心不可能是单点的,一定会有一个集群,那么集群中的服务注册信息如何在集群中保持一致的呢?

    dys

扫码关注云+社区

领取腾讯云代金券