异步工具

异步工具类,方便记录日志

线程类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.concurrent.*;
 
/**
 * 线程相关工具类
 *
 * @Author szw
 * @Date 2020/2/13 18:06
 * @Version 1.0
 **/
public class Threads {
        private static final Logger logger = LoggerFactory.getLogger(Threads.class);
 
        /**
         * sleep等待,单位为毫秒
         */
        public static void sleep(long milliseconds) {
                try {
                        Thread.sleep(milliseconds);
                } catch (InterruptedException e) {
                        return;
                }
        }
 
        /**
         * 停止线程池
         * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
         * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
         * 如果仍人超時,則強制退出.
         * 另对在shutdown时线程本身被调用中断做了处理.
         */
        public static void shutdownAndAwaitTermination(ExecutorService pool) {
                if (pool != null && !pool.isShutdown()) {
                        pool.shutdown();
                        try {
                                if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
                                        pool.shutdownNow();
                                        if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
                                                logger.info("Pool did not terminate");
                                        }
                                }
                        } catch (InterruptedException ie) {
                                pool.shutdownNow();
                                Thread.currentThread().interrupt();
                        }
                }
        }
 
        /**
         * 打印线程异常信息
         */
        public static void printException(Runnable r, Throwable t) {
                if (t == null && r instanceof Future<?>) {
                        try {
                                Future<?> future = (Future<?>) r;
                                if (future.isDone()) {
                                        future.get();
                                }
                        } catch (CancellationException ce) {
                                t = ce;
                        } catch (ExecutionException ee) {
                                t = ee.getCause();
                        } catch (InterruptedException ie) {
                                Thread.currentThread().interrupt();
                        }
                }
                if (t != null) {
                        logger.error(t.getMessage(), t);
                }
        }
}

 

线程池配置

import com.jarvis.utils.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
 
/**
 * 线程池配置
 *
 * @Author szw
 * @Date 2020/2/13 18:06
 * @Version 1.0
 **/
@Configuration
public class ThreadPoolConfig {
    /**
     * 核心线程池大小
     */
    private final int CORE_POOL_SIZE = 50;
 
    /**
     * 最大可创建的线程数
     */
    private final int MAX_POOL_SIZE = 200;
 
    /**
     * 队列最大长度
     */
    private final int QUEUE_CAPACITY = 1000;
 
    /**
     * 线程池维护线程所允许的空闲时间
     */
    private final int KEEP_ALIVE_SECONDS = 300;
 
    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(CORE_POOL_SIZE);
        executor.setCorePoolSize(MAX_POOL_SIZE);
        executor.setQueueCapacity(QUEUE_CAPACITY);
        executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS);
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
 
    /**
     * 执行周期性或定时任务
     */
    @Bean(name = "scheduledExecutorService")
    protected ScheduledExecutorService scheduledExecutorService() {
        return new ScheduledThreadPoolExecutor(CORE_POOL_SIZE,
            new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                Threads.printException(r, t);
            }
        };
    }
}

异步任务管理器

import com.jarvis.utils.SpringContextHolder;
import com.jarvis.utils.Threads;
 
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
 
/**
 * 异步任务管理器
 *
 * @Author szw
 * @Date 2020/2/13 18:06
 * @Version 1.0
 **/
public class AsyncManager {
        /**
         * 操作延迟10毫秒
         */
        private final int OPERATE_DELAY_TIME = 10;
 
        /**
         * 异步操作任务调度线程池
         */
        private ScheduledExecutorService executor = SpringContextHolder.getBean("scheduledExecutorService");
 
        /**
         * 单例模式
         */
        private AsyncManager() {
        }
 
        private static AsyncManager me = new AsyncManager();
 
        public static AsyncManager me() {
                return me;
        }
 
        /**
         * 执行任务
         *
         * @param task 任务
         */
        public void execute(TimerTask task) {
                executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
        }
 
        /**
         * 停止任务线程池
         */
        public void shutdown() {
                Threads.shutdownAndAwaitTermination(executor);
        }
}

 

异步工厂类

import com.jarvis.api.observatory.entity.LoginInfor;
import com.jarvis.api.observatory.service.impl.LoginInforServiceImpl;
import com.jarvis.constants.Constants;
import com.jarvis.utils.*;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.slf4j.Slf4j;
 
import java.util.TimerTask;
 
/**
 * 异步工厂(产生任务用)
 *
 * @Author szw
 * @Date 2020/2/17 15:16
 * @Version 1.0
 **/
@Slf4j
public class AsyncFactory {
        /**
         * 记录登陆信息
         *
         * @param username 用户名
         * @param status   状态
         * @param message  消息
         * @param args     列表
         * @return 任务task
         */
        public static TimerTask recordLoginInfor(final String username, final String status, final String message, final Object... args) {
                final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent"));
                final String ip = HttpContextUtils.getHttpServletRequest().getRemoteAddr();
                return new TimerTask() {
                        @Override
                        public void run() {
                                String address = AddressUtils.getRealAddressByIP(ip);
                                StringBuilder s = new StringBuilder();
                                s.append(LogUtils.getBlock(ip));
                                s.append(address);
                                s.append(LogUtils.getBlock(username));
                                s.append(LogUtils.getBlock(status));
                                s.append(LogUtils.getBlock(message));
                                // 打印信息到日志
                                log.info(s.toString(), args);
                                // 获取客户端操作系统
                                String os = userAgent.getOperatingSystem().getName();
                                // 获取客户端浏览器
                                String browser = userAgent.getBrowser().getName();
                                // 封装对象
                                LoginInfor logininfor = new LoginInfor();
                                logininfor.setLoginName(username);
                                logininfor.setIpAddr(ip);
                                logininfor.setLoginLocation(address);
                                logininfor.setBrowser(browser);
                                logininfor.setOs(os);
                                logininfor.setMsg(message);
                                // 日志状态
                                if (Constants.LOGIN_SUCCESS.equals(status) || Constants.LOGOUT.equals(status)) {
                                        logininfor.setStatus(Constants.SUCCESS);
                                } else if (Constants.LOGIN_FAIL.equals(status)) {
                                        logininfor.setStatus(Constants.FAIL);
                                }
                                // 插入数据
                                SpringUtils.getBean(LoginInforServiceImpl.class).insertLoginInfor(logininfor);
                        }
                };
        }
}

使用

AsyncManager.me().execute(AsyncFactory.recordLoginInfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked")));

 

posted @ 2020-02-27 17:01  石智文的博客  阅读(640)  评论(0编辑  收藏  举报