暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

高并发超时丢弃缓解队列堆积

老李说架构之道 2021-06-24
157
场景:前端大量任务请求,后台线程积压导致阻塞,通常的方法增加线程,提高任务的处理速度,随着请求量的大量增加,增加线程的方式也无法满足。尤其在面临高并发的场景下,例如:秒杀、答题有奖、营销活动等,而采取一种超时丢弃的策略,以保证系统的正常访问。具体处理逻辑如下图所示:


具体代码案例:
    
    /**
    * 执行异步任务
    * 超时时间
    * 超过此时间,则打印任务在队列中的时间
    * @param group 任务队列类型
    * @param handler 任务handler
    */
    public void run(Group group, IAsyncHandler handler) {
    AsyncTask task = new AsyncTask(taskTimeout, handler);
    balance(group, task);
    }


    /**
    * 构造异步任务
    * @param timeout 超时时间(单位:豪秒)
    * @param handler 执行句柄
    */
    public AsyncTask(int timeout, IAsyncHandler handler) {
    super();
    if (timeout < 0) {
    timeout = 1000;
    }
    this.timeout = timeout;
    this.handler = handler;
    this.addTime = System.currentTimeMillis();
    }
    /**
    * 任务执行
    **/
    public void run() {
    while (!isStop) {
    AsyncTask task = null;
    try {
    task = taskQueue.poll(1500, TimeUnit.MILLISECONDS);
    if (null != task) {
    //重点执行语句:执行超时丢弃的任务队列
    execTimeoutTask(task);
    }
    } catch (InterruptedException ie) {
    logger.error("has error !", ie);
    } catch (Throwable ex) {
    if (task != null) {
    task.getHandler().exceptionCaught(ex);
    }
    }
    }
    }


    /**
    * @任务超时处理
    * @param task
    * @throws Throwable
    */
    private void execTimeoutTask(AsyncTask task) throws Throwable {
    if ((System.currentTimeMillis() - task.getAddTime()) > task.getQtimeout()) {
    task.getHandler().exceptionCaught(new TimeoutException(threadFactoryName + "async task timeout!"));
    return;
    } else {
    Object obj = task.getHandler().run();
    task.getHandler().messageReceived(obj);
    }
    }





    文章转载自老李说架构之道,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论