appliction-frame.xml配置
<!-- 应用服务器启动时,启动相应的线程 --> <bean id="appThreadStart" class="com.shareinfo.commons.thread.AppThreadStart"> <!-- 可在多台服务器上同时运行的后台线程 --> <property name="multipleThreadObjects"> <list> <value>com.shareinfo.commons.thread.multiple.MultipleCheckOnlineUser</value> <value>com.shareinfo.commons.thread.multiple.MultipleInitProperties</value> <value>com.shareinfo.commons.thread.multiple.MultipleLogOperation</value> <value>com.shareinfo.commons.thread.multiple.MultipleLogUserLogin</value> <value>com.shareinfo.commons.thread.multiple.MultipleCheckFixedScanOverdue</value> </list> </property> <!-- 只能在单台服务器上运行的后台线程 --> <property name="singleThreadObjects"> <list> <!-- <value>com.shareinfo.commons.thread.single.services.SingleSmsClient</value> <value>com.shareinfo.commons.thread.single.services.SingleEmailClient</value> --> </list> </property> <!-- 只能在单台服务器上运行的后台线程,在IP地址为这个的服务器上运行 --> <property name="singleIpAddress" value="192.168.1.163" /> </bean>
后台主线程,用于启动其他线程,这里使用Spring的InitializingBean的afterPropertiesSet()方法来初始化后台主线程,即web容器启动,取初始启动后台主线程
// 后台主线程,用于启动其他线程 @Log4j public class AppThreadStart implements InitializingBean { // 可在多台服务器上同时运行的后台线程 @Setter private List multipleThreadObjects; // 只能在单台服务器上运行的后台线程 @Setter private List singleThreadObjects; // 只能在单台服务器上运行的后台线程,在IP地址为这个的服务器上运行 @Setter private String singleIpAddress; public void afterPropertiesSet() throws Exception { if (CollectionUtils.isNotEmpty(multipleThreadObjects)) { Iterator iterator = multipleThreadObjects.iterator(); while (iterator.hasNext()) { Object object = iterator.next(); start(object); } } String localHostAddress = NetworkUtils.localHostAddress(); StringBuffer message = new StringBuffer(); message.append("LocalHostAddress: " + localHostAddress); message.append(", SingleMachineIpAddress: " + singleIpAddress); log.info(message.toString()); if (!StringUtils.equals(localHostAddress, singleIpAddress)) return; if (CollectionUtils.isNotEmpty(singleThreadObjects)) { Iterator iterator = singleThreadObjects.iterator(); while (iterator.hasNext()) { Object object = iterator.next(); start(object); } } } private void start(Object object) { if (object == null) return; if (!(object instanceof String)) return; String clazzName = (String)object; if (StringUtils.isEmpty(clazzName)) return; try { Object thread = Class.forName(clazzName).newInstance(); if (!(thread instanceof Runnable)) return; new Thread((Runnable)thread).start(); log.info("Thread [" + clazzName + "] is starting..."); } catch (ClassNotFoundException e) { log.warn(clazzName + " isn't fund !!"); } catch (InstantiationException e) { log.warn("InstantiationException: [" + clazzName + "] " + e.getMessage()); } catch (IllegalAccessException e) { log.warn("IllegalAccessException: [" + clazzName + "] " + e.getMessage()); } catch (Exception e) { log.warn("Exception: [" + clazzName + "] " + e.getMessage()); } } }
线程抽象类:
public abstract class AbstractThread implements Runnable { public abstract boolean isNullServiceBean(); /** * 休眠时间,以秒为单位 */ protected void sleepSeconds(long l) { sleep(1000 * l); } /** * 休眠时间,以分钟为单位 */ protected void sleepMinuts(long l) { sleep(1000 * 60 * l); } /** * 休眠时间,以毫秒为单位 */ private void sleep(long l) { try { Thread.sleep(l); } catch (Exception e) { } } }
逾期定时扫描(多台服务器可运行):
/** * 定时检查逾期定时器是否执行成功 * @ClassName: MultipleCheckFixedScanOverdue * @Description: TODO * @author xiaoqun.yi [email protected] * @date 2015-9-1 下午02:36:37 * @version V1.0 */ public class MultipleCheckFixedScanOverdue extends AbstractThread { private ITaskExecutionService taskExecutionService; private ISequenceService sequenceService; private NoticeTempToolProxy noticeTempToolProxy; public void run() { while (isNullServiceBean()) { try { if (taskExecutionService == null) taskExecutionService = (ITaskExecutionService) SpringUtils.getBean("taskExecutionService"); if (sequenceService == null) sequenceService = (ISequenceService) SpringUtils.getBean("sequenceService"); if (noticeTempToolProxy == null) noticeTempToolProxy = (NoticeTempToolProxy) SpringUtils.getBean("noticeTempToolProxy"); } catch (Exception e) { e.printStackTrace(); } finally { sleepSeconds(10); } } while (true) { try { TaskExecutionQuery taskExecutionQuery= new TaskExecutionQuery(); taskExecutionQuery.setTaskType(TaskExecution.TaskType.overdueScan); taskExecutionQuery.setStatus("SUCCESS"); taskExecutionQuery.setSmsFlag("N"); taskExecutionQuery.setEmailFlag("N"); Calendar cal=Calendar.getInstance(); int hour=cal.get(Calendar.HOUR_OF_DAY); /**每天凌晨1点以后开始检查逾期定时器是否执行成功*/ if(hour>=1){ boolean overdueScanFlag=taskExecutionService.isExecutedDayTask(taskExecutionQuery); if(!overdueScanFlag){ /**任务类型为逾期扫描检查*/ taskExecutionQuery.setTaskType(TaskExecution.TaskType.overdueScanCheck); /**判断当天是否已经发送短信或者邮件*/ taskExecutionQuery.setSmsFlag("Y"); taskExecutionQuery.setEmailFlag("N"); boolean smsFlag=taskExecutionService.isExecutedDayTask(taskExecutionQuery); taskExecutionQuery.setSmsFlag("N"); taskExecutionQuery.setEmailFlag("Y"); boolean emailFlag= taskExecutionService.isExecutedDayTask(taskExecutionQuery); /**如果没有发送短信或邮件*/ if(!smsFlag||!emailFlag){ TaskExecution taskExecution=new TaskExecution(); taskExecution.setTaskType(TaskExecution.TaskType.overdueScanCheck); taskExecution.setTaskName("逾期定时扫描检查执行情况"); taskExecution.setInsertBy("sys");//系统 if(!smsFlag){ /**发送短信*/ Map<String,Object> param=new HashMap<String, Object>(); Map<String,Object> result=new HashMap<String, Object>(); param.put("mobile", "18684894397"); param.put("smsContent", "当天逾期定时器未成功执行,请手动执行并检查原因."); result=noticeTempToolProxy.sendSms(param); if(null!=result){ Map<String,Object> statusResult=(Map<String, Object>) result.get("data"); if(null!=statusResult&&statusResult.get("status").toString().equals("1")){ taskExecution.setId(sequenceService.nextval(Sequence.SEQ_TASK_EXECUTION)); taskExecution.setStatus("SUCCESS"); taskExecution.setSmsFlag("Y"); taskExecution.setEmailFlag("N"); taskExecutionService.insert(taskExecution); } } } if(!emailFlag){ /**发送邮件*/ Map<String,Object> param=new HashMap<String, Object>(); Map<String,Object> result=new HashMap<String, Object>(); param.put("email", "[email protected]"); param.put("emailContent", "当天逾期定时器未成功执行,请手动执行并检查原因."); result=noticeTempToolProxy.sendEmail(param); if(null!=result){ Map<String,Object> statusResult=(Map<String, Object>) result.get("data"); if(null!=statusResult&&statusResult.get("status").toString().equals("1")){ taskExecution.setId(sequenceService.nextval(Sequence.SEQ_TASK_EXECUTION)); taskExecution.setStatus("SUCCESS"); taskExecution.setSmsFlag("N"); taskExecution.setEmailFlag("Y"); taskExecutionService.insert(taskExecution); } } } } } } } catch (Exception e) { e.printStackTrace(); } finally { sleepMinuts(10); } } } /** * 检查Service Bean是否加载完毕 */ public boolean isNullServiceBean() { if (taskExecutionService == null) return true; if (sequenceService == null) return true; if (noticeTempToolProxy == null) return true; return false; } }
邮件发送客户端(单台服务器运行纯种):
public class SingleEmailClient extends AbstractThread { private ILogEmailService logEmailService = null; public void run() { while (isNullServiceBean()) { try { if (logEmailService == null) logEmailService = (ILogEmailService)SpringUtils.getBean("logEmailService"); } catch (Exception e) { e.printStackTrace(); } finally { sleepSeconds(10); } } // 查询短信列表中的进行发送 while (true) { try { send(); } catch (Exception e) { e.printStackTrace(); } finally { sleepMinuts(1); } } } /** * 检查Service Bean是否加载完毕 */ public boolean isNullServiceBean() { if (logEmailService == null) return true; return false; } /** * 检查待发送的邮件,并发送 */ private void send() { LogEmailQuery query = new LogEmailQuery(); query.setExpectSendTimeTo(DateUtils.currentTime("yyyy-MM-dd HH:mm:ss")); List<LogEmail> emailList = logEmailService.selectList(query, new Page(1, 200)); if (CollectionUtils.isEmpty(emailList)) return; List<String> successIdList = new ArrayList<String>(); List<String> failIdList = new ArrayList<String>(); for (LogEmail email : emailList) { if (NumberUtils.defaultInt(email.getSendTimes(), 0) >= 3) { List<String> list = Arrays.asList(new String[] { String.valueOf(email.getId()) }); logEmailService.insertHis(list, IConstants.FAIL); continue; } String to = email.getMailTo(); String subject = email.getSubject(); String message = email.getMessage(); String smtp = email.getSmtp(); String user = email.getAuthUser(); String password = email.getAuthPassword(); String nick = email.getNick(); String from = email.getMailFrom(); EmailService emailService = new EmailService(smtp, user, password, nick, from, to); boolean isSuccess = emailService.send(subject, message); if (isSuccess) successIdList.add(String.valueOf(email.getId())); else failIdList.add(String.valueOf(email.getId())); } if (CollectionUtils.isNotEmpty(successIdList)) logEmailService.insertHis(successIdList, IConstants.SUCCESS); if (CollectionUtils.isNotEmpty(failIdList)) logEmailService.updateList(failIdList, IConstants.FAIL); } }