在上一篇文章中,跟大家介绍了队列的使用,在基于数据库的队列的是实现中,提到了可以使用事件处理机制类进行队列数据的处理。今天就来简单看看事件处理机制是怎么使用的。
首先我们需要一个事件的实体类:Event
import java.util.concurrent.atomic.AtomicInteger; /** * 消息实体类 */ public class Event implements java.io.Serializable { //消息体 private Object data; //消息类型 private Integer eventType; //重试次数 private AtomicInteger tryCount = new AtomicInteger(0); //消息等待发送时间 private long waitTime; //消息标识 private String UUID; public Object getData() { return data; } public void setData(Object data) { this.data = data; } public Integer getEventType() { return eventType; } public void setEventType(Integer eventType) { this.eventType = eventType; } public AtomicInteger getTryCount() { return tryCount; } public void setTryCount(AtomicInteger tryCount) { this.tryCount = tryCount; } public long getWaitTime() { return waitTime; } public void setWaitTime(long waitTime) { this.waitTime = waitTime; } public String getUUID() { return UUID; } public void setUUID(String uUID) { UUID = uUID; } }
接着是事件处理结果类:EventResult
import java.io.Serializable; /** * 消息处理结果 */ public class EventResult implements Serializable { private static final long serialVersionUID = 560051808572760660L; //是否成功 private boolean isSuccess; //结果信息 private String resultMsg; public boolean isSuccess() { return isSuccess; } public void setSuccess(boolean isSuccess) { this.isSuccess = isSuccess; } public String getResultMsg() { return resultMsg; } public void setResultMsg(String resultMsg) { this.resultMsg = resultMsg; } }
对于事件来说,不同的事件类型可以有不同的事件处理类:基类:EventHandler,实现类:OneEventHandler
/** * 处理队列中的各种事件 */ public interface EventHandler { /** * 处理事件,返回处理结果 * @param event */ public EventResult handleEvent(final Event event); } import com.demo.event.Event; import com.demo.event.EventHandler; import com.demo.event.EventResult; /** * 具体的事件处理类,根据不同的事件类型,可以有多种处理类 */ public class OneEventHandler implements EventHandler { public EventResult handleEvent(Event event) { return null; } }
下面,我们需要一个类来执行事件任务:EventWorker
import java.util.concurrent.Callable; /** * 用于执行事件任务 * @author lizhiyang * */ public class EventWorker implements Callable<EventResult> { //要处理的事件 private Event event; //使用的事件处理器 private EventHandler eventHandler; public EventWorker(Event event, EventHandler eventHandler) { this.event = event; this.eventHandler = eventHandler; } /** * 调用事件处理器处理事件 */ public EventResult call() throws Exception { if(event == null) { return null; } if(eventHandler == null) { return null; } EventResult eventResult = null; try { eventResult = eventHandler.handleEvent(event); } catch (Exception e) { e.printStackTrace(); } return eventResult; } }
在事件处理的时候,需要有一个管理类,去添加事件:EventManager
import com.demo.event.Event; public interface EventManager { /** * 添加异步处理事件 * @param event */ public void addEvent(final Event event); /** * 添加同步处理事件 * @param event */ public void addEventSyn(Event event); }
分为两种,同时处理事件和异步处理事件,在第一次添加的时候都使用同步处理事件,如果时间处理失败或出现其他原因时,可以再次添加异步事件进行再次处理。
同步处理在EventMangerImpl中:
import java.util.Calendar; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import com.demo.event.Event; import com.demo.event.EventHandler; import com.demo.event.EventResult; import com.demo.event.EventScheduled; import com.demo.event.EventWorker; import com.demo.event.handler.OneEventHandler; public class EventManagerImpl implements EventManager { private final static Logger logger = LoggerFactory.getLogger(EventManagerImpl.class); /** 开启队列调度线程 */ private EventScheduled eventScheduled; /** 线程池管理 */ /** * spring 中的配置: * <bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="25" /> <!-- 最大线程数,默认为Integer.MAX_VALUE --> <property name="maxPoolSize" value="400" /> <!-- 队列最大长度 --> <property name="queueCapacity" value="1000" /> <!-- 线程池维护线程所允许的空闲时间--> <property name="keepAliveSeconds" value="200" /> <!-- 线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy、CallerRunsPolicy;默认为后者 --> <property name="rejectedExecutionHandler"> <!-- CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度 --> <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" /> </property> </bean> */ private ThreadPoolTaskExecutor threadPoolTaskExecutor; /** * 初始化异步调度线程 */ public void init(){ //构造调度任务 eventScheduled = new EventScheduled(); //启动调度线程 eventScheduled.start(); } /** * 添加新的事件到队列中 * @param event */ public void addEvent(final Event event){ if(!validateEvent(event)){ if(logger.isDebugEnabled()){ logger.debug("addEvent event is illega"); } return; } eventScheduled.addEvent(event); } public void addEventSyn(Event event) { if(!validateEvent(event)){ if(logger.isDebugEnabled()){ logger.debug("addEventSyn event is illega"); } return; } EventHandler eventHandle = new OneEventHandler(); Future<EventResult> future = null; try { future = threadPoolTaskExecutor.getThreadPoolExecutor().submit(new EventWorker(event,eventHandle)); if(future != null) { EventResult eventResult = future.get(); if(eventResult == null){ if(logger.isDebugEnabled()){ logger.debug("submit eventResult return null"); } return; } if(logger.isDebugEnabled()) { logger.debug("event submit :" + eventResult.toString()); } //没有发送成功等待下次发送 if(!eventResult.isSuccess()){ // 暂时不用线程调度,因为缓存的问题 /* int tryCount = event.getTryCount().intValue(); event.setWaitTime(QueueRuleUtil.getNextConsumeSecond(tryCount,0)); addEvent(event);*/ } else { // 发送成功但是可能数据操作没有成功,或者是其他原因,对于这些数据采取线程调度处理,不需要马上处理 event.setEventType(0); //一分钟后处理 Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MINUTE, 1); event.setWaitTime(calendar.getTime().getTime()); addEvent(event); } } } catch (InterruptedException e) { logger.error(this.getClass() + "event submit Interrupted exception :",e); future.cancel(true);// 中断执行此任务的线程 } catch (ExecutionException e) { logger.error(this.getClass() + "event submit Execution exception:" ,e); future.cancel(true);// 中断执行此任务的线程 } } /** * 验证事件是否有效 * * @param event * @return boolean */ private boolean validateEvent(Event event) { if (event == null) { if (logger.isDebugEnabled()) { logger.debug("addEventSyn is must not be null"); } return false; } if (StringUtils.isBlank(event.getUUID()) || event.getData() == null || event.getEventType() == null) { if (logger.isDebugEnabled()) { logger.debug("event request params is must not be null"); } return false; } return true; } public void setThreadPoolTaskExecutor( ThreadPoolTaskExecutor threadPoolTaskExecutor) { this.threadPoolTaskExecutor = threadPoolTaskExecutor; } }
异步处理时,需要有调度器进行处理:EventScheduled
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.demo.event.handler.OneEventHandler; /** * 消息调度线程,主要用于消息的定时发送 * * 消息的异步处理过程 * */ public class EventScheduled { private Logger logger = LoggerFactory.getLogger(EventScheduled.class); /** * 调度线程池,用于重发数据 */ private ScheduledExecutorService scheduledExecutorService; /** 采用无界队列 */ private final static ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); /** * 单个cpu的线程数 */ private final int POOL_SIZE = 5; /** 队列监听等待时间 */ private long waitTime = 200; /** * 添加异步事件 * @param event */ public void addEvent(Event event){ if (event != null) { eventQueue.add(event); } } /** * 构造带不带缓存的客户端 */ public EventScheduled(){ //初始化ScheduledExecutorService 服务 scheduledExecutorService = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE); } /** * 阻塞监听线程,只负责执行需要调度的消息 */ public void start(){ logger.info("EventScheduled start"); new Thread() { public void run() { while(true){ try{ CountDownLatch latch = new CountDownLatch(1); latch.await(waitTime,TimeUnit.MILLISECONDS); Event event=eventQueue.poll();//线程安全 if(event==null){ continue; } //根据消息类型构造不同的事件处理类 EventHandler eventHandle = new OneEventHandler(); Future<EventResult> future = null; try { future = scheduledExecutorService.schedule(new EventWorker(event,eventHandle), event.getWaitTime(), TimeUnit.SECONDS); if(future != null) { EventResult result = future.get(); if(result == null){ if(logger.isDebugEnabled()){ logger.debug("event scheduled return null"); } return; } if(logger.isDebugEnabled()) { logger.debug("event scheduled :" + result.toString()); } } } catch (InterruptedException e) { logger.error("event scheduled Interrupted exception :",e); future.cancel(true);// 中断执行此任务的线程 } catch (ExecutionException e) { logger.error("event scheduled Execution exception:" ,e); future.cancel(true);// 中断执行此任务的线程 } }catch(Throwable e){ logger.error("scheduled Exception:",e); } } } }.start(); } }
以上就是事件处理机制的代码部分。对于事件处理机制来说,我本人的理解并不是特别的透彻,这里就不进行详细说明了,只是把示例代码贴出,仅供大家参考。
版权声明:本文为博主原创文章,未经博主允许不得转载。