Browse Source

定时监控实时更新情况,发现异常,发送警告短信

sunyj 9 years ago
parent
commit
f623a9baf4
14 changed files with 192 additions and 33 deletions
  1. 22 8
      search-console-b2b/src/main/java/com/uas/search/console/b2b/Application.java
  2. 3 1
      search-console-b2b/src/main/java/com/uas/search/console/b2b/controller/IndexController.java
  3. 5 2
      search-console-b2b/src/main/java/com/uas/search/console/b2b/controller/ScheduleController.java
  4. 9 0
      search-console-b2b/src/main/java/com/uas/search/console/b2b/controller/SearchController.java
  5. 1 1
      search-console-b2b/src/main/java/com/uas/search/console/b2b/dao/LuceneQueueMessageDao.java
  6. 16 0
      search-console-b2b/src/main/java/com/uas/search/console/b2b/model/LuceneQueueMessage.java
  7. 2 1
      search-console-b2b/src/main/java/com/uas/search/console/b2b/schedule/model/TaskLog.java
  8. 1 2
      search-console-b2b/src/main/java/com/uas/search/console/b2b/schedule/service/impl/TaskServiceImpl.java
  9. 19 0
      search-console-b2b/src/main/java/com/uas/search/console/b2b/service/RealTimeUpdateMonitorService.java
  10. 3 7
      search-console-b2b/src/main/java/com/uas/search/console/b2b/service/UpdateVirtualColumnService.java
  11. 107 0
      search-console-b2b/src/main/java/com/uas/search/console/b2b/service/impl/RealTimeUpdateMonitorServiceImpl.java
  12. 2 1
      search-console-b2b/src/main/java/com/uas/search/console/b2b/service/impl/SearchServiceImpl.java
  13. 1 9
      search-console-b2b/src/main/java/com/uas/search/console/b2b/service/impl/UpdateVirtualColumnServiceImpl.java
  14. 1 1
      search-console-b2b/src/main/webapp/resources/js/listenDetails/app.js

+ 22 - 8
search-console-b2b/src/main/java/com/uas/search/console/b2b/Application.java

@@ -9,6 +9,8 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc;
 import com.uas.search.console.b2b.core.util.ContextUtils;
 import com.uas.search.console.b2b.core.util.ContextUtils;
 import com.uas.search.console.b2b.model.PurchaseInquiryItemSimpleInfo;
 import com.uas.search.console.b2b.model.PurchaseInquiryItemSimpleInfo;
 import com.uas.search.console.b2b.model.PurchaseInquiryMouldSimpleInfo;
 import com.uas.search.console.b2b.model.PurchaseInquiryMouldSimpleInfo;
+import com.uas.search.console.b2b.schedule.service.TaskService;
+import com.uas.search.console.b2b.service.RealTimeUpdateMonitorService;
 import com.uas.search.console.b2b.service.UpdateVirtualColumnService;
 import com.uas.search.console.b2b.service.UpdateVirtualColumnService;
 
 
 @EnableTransactionManagement
 @EnableTransactionManagement
@@ -20,26 +22,38 @@ public class Application {
 		SpringApplication application = new SpringApplication(Application.class);
 		SpringApplication application = new SpringApplication(Application.class);
 		application.addListeners(new ContextUtils());
 		application.addListeners(new ContextUtils());
 		application.run(args);
 		application.run(args);
-		startUpdateOverdueDailyTask();
+
+		startTask();
 	}
 	}
 
 
 	/**
 	/**
-	 * 自动开启更新虚拟列索引的定时任务
+	 * 创建定时任务
 	 */
 	 */
-	public static void startUpdateOverdueDailyTask() {
+	public static void startTask() {
 		SystemProperties systemProperties = ContextUtils.getBean(SystemProperties.class);
 		SystemProperties systemProperties = ContextUtils.getBean(SystemProperties.class);
 		if (systemProperties.isDailyTaskAutoStart()) {
 		if (systemProperties.isDailyTaskAutoStart()) {
 			UpdateVirtualColumnService updateVirtualColumnService = ContextUtils
 			UpdateVirtualColumnService updateVirtualColumnService = ContextUtils
 					.getBean(UpdateVirtualColumnService.class);
 					.getBean(UpdateVirtualColumnService.class);
-			// 模具询价单
-			updateVirtualColumnService.createUpdateOverdueDailyTask(PurchaseInquiryMouldSimpleInfo.class,
+			// 定时更新模具询价单虚拟列索引
+			updateVirtualColumnService.newUpdateOverdueDailyTask(PurchaseInquiryMouldSimpleInfo.class,
 					systemProperties.getDailyTaskHour(), systemProperties.getDailyTaskMinute(),
 					systemProperties.getDailyTaskHour(), systemProperties.getDailyTaskMinute(),
 					systemProperties.getDailyTaskSecond());
 					systemProperties.getDailyTaskSecond());
-			// 采购询价单明细
-			updateVirtualColumnService.createUpdateOverdueDailyTask(PurchaseInquiryItemSimpleInfo.class,
+			// 定时更新采购询价单明细虚拟列索引
+			updateVirtualColumnService.newUpdateOverdueDailyTask(PurchaseInquiryItemSimpleInfo.class,
 					systemProperties.getDailyTaskHour(), systemProperties.getDailyTaskMinute(),
 					systemProperties.getDailyTaskHour(), systemProperties.getDailyTaskMinute(),
 					systemProperties.getDailyTaskSecond());
 					systemProperties.getDailyTaskSecond());
-			updateVirtualColumnService.start();
 		}
 		}
+
+		// 监控实时更新异常情况
+		RealTimeUpdateMonitorService realTimeUpdateMonitorService = ContextUtils
+				.getBean(RealTimeUpdateMonitorService.class);
+		realTimeUpdateMonitorService.newTask();
+
+		// 开启定时任务
+		TaskService taskService = ContextUtils.getBean(TaskService.class);
+		if (!taskService.isStopped()) {
+			taskService.stop();
+		}
+		taskService.start();
 	}
 	}
 }
 }

+ 3 - 1
search-console-b2b/src/main/java/com/uas/search/console/b2b/controller/IndexController.java

@@ -79,7 +79,9 @@ public class IndexController {
 	@RequestMapping("/listen/restart")
 	@RequestMapping("/listen/restart")
 	@ResponseBody
 	@ResponseBody
 	public String restartListen(Long waitInterval) {
 	public String restartListen(Long waitInterval) {
-		aqListener.stop();
+		if (aqListener.isRunning()) {
+			aqListener.stop();
+		}
 		return aqListener.start(waitInterval);
 		return aqListener.start(waitInterval);
 	}
 	}
 
 

+ 5 - 2
search-console-b2b/src/main/java/com/uas/search/console/b2b/controller/ScheduleController.java

@@ -34,8 +34,11 @@ public class ScheduleController {
 			return "不支持更新虚拟列overdue索引:" + tableName;
 			return "不支持更新虚拟列overdue索引:" + tableName;
 		}
 		}
 		String message = "已开启:" + updateVirtualColumnService
 		String message = "已开启:" + updateVirtualColumnService
-				.createUpdateOverdueDailyTask(ClassAndTableNameUtils.toClass(table), hour, minute, second);
-		updateVirtualColumnService.start();
+				.newUpdateOverdueDailyTask(ClassAndTableNameUtils.toClass(table), hour, minute, second);
+		if (!taskService.isStopped()) {
+			taskService.stop();
+		}
+		taskService.start();
 		return message;
 		return message;
 	}
 	}
 
 

+ 9 - 0
search-console-b2b/src/main/java/com/uas/search/console/b2b/controller/SearchController.java

@@ -20,6 +20,7 @@ import com.uas.search.b2b.service.SearchService;
 import com.uas.search.b2b.service.SearchService.Table_name;
 import com.uas.search.b2b.service.SearchService.Table_name;
 import com.uas.search.b2b.util.SearchConstants;
 import com.uas.search.b2b.util.SearchConstants;
 import com.uas.search.console.b2b.core.util.ContextUtils;
 import com.uas.search.console.b2b.core.util.ContextUtils;
+import com.uas.search.console.b2b.core.util.PathUtils;
 import com.uas.search.console.b2b.service.InnerSearchService;
 import com.uas.search.console.b2b.service.InnerSearchService;
 import com.uas.search.console.b2b.util.ClassAndTableNameUtils;
 import com.uas.search.console.b2b.util.ClassAndTableNameUtils;
 
 
@@ -97,4 +98,12 @@ public class SearchController {
 		return innerSearchService.getAllObjects(ClassAndTableNameUtils.toClass(tbName), page == null ? 0 : page,
 		return innerSearchService.getAllObjects(ClassAndTableNameUtils.toClass(tbName), page == null ? 0 : page,
 				size == null ? 0 : size);
 				size == null ? 0 : size);
 	}
 	}
+	
+	@RequestMapping("/test")
+	@ResponseBody
+	public void test() {
+		System.out.println("appPath: "+PathUtils.getAppPath());
+		System.out.println("classPath: "+PathUtils.getClassPath());
+		System.out.println("filePath: "+PathUtils.getFilePath());
+	}
 }
 }

+ 1 - 1
search-console-b2b/src/main/java/com/uas/search/console/b2b/dao/LuceneQueueMessageDao.java

@@ -108,7 +108,7 @@ public class LuceneQueueMessageDao {
 			// enq_time为GMT时间,转为本地时间,需加上8小时
 			// enq_time为GMT时间,转为本地时间,需加上8小时
 			sql = "select msgid, to_char(enq_time+8/24,'yyyy-mm-dd hh24:mi:ss'),user_data from (select tt.*,rownum r from (select * from "
 			sql = "select msgid, to_char(enq_time+8/24,'yyyy-mm-dd hh24:mi:ss'),user_data from (select tt.*,rownum r from (select * from "
 					+ SearchConstants.LUCENE_QUEUE_TABLE_NAME + " t where upper(t.user_data.message) like upper('%"
 					+ SearchConstants.LUCENE_QUEUE_TABLE_NAME + " t where upper(t.user_data.message) like upper('%"
-					+ searchContent + "%') order by enq_time) tt where rownum<=?) ttt where ttt.r >=?";
+					+ searchContent + "%') order by enq_time desc) tt where rownum<=?) ttt where ttt.r >=?";
 			List<LuceneQueueMessage> luceneQueueMessages = new ArrayList<>();
 			List<LuceneQueueMessage> luceneQueueMessages = new ArrayList<>();
 			preparedStatement = connection.prepareStatement(sql);
 			preparedStatement = connection.prepareStatement(sql);
 			preparedStatement.setInt(1, maxRownum);
 			preparedStatement.setInt(1, maxRownum);

+ 16 - 0
search-console-b2b/src/main/java/com/uas/search/console/b2b/model/LuceneQueueMessage.java

@@ -1,5 +1,7 @@
 package com.uas.search.console.b2b.model;
 package com.uas.search.console.b2b.model;
 
 
+import java.util.Objects;
+
 /**
 /**
  * 各个表的数据改动信息(为了实时更新索引,关于各个表的数据更改记录存储在AQ消息队列中)
  * 各个表的数据改动信息(为了实时更新索引,关于各个表的数据更改记录存储在AQ消息队列中)
  * 
  * 
@@ -73,6 +75,20 @@ public class LuceneQueueMessage {
 		this.modifyTime = modifyTime;
 		this.modifyTime = modifyTime;
 	}
 	}
 
 
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null || getClass() != obj.getClass() || !(obj instanceof LuceneQueueMessage)) {
+			return false;
+		}
+		LuceneQueueMessage other = (LuceneQueueMessage) obj;
+		return Objects.equals(messageId, other.getMessageId()) && Objects.equals(tableName, other.getTableName())
+				&& Objects.equals(ids, other.getIds()) && Objects.equals(method, other.getMethod())
+				&& Objects.equals(modifyTime, other.getModifyTime());
+	}
+
 	@Override
 	@Override
 	public String toString() {
 	public String toString() {
 		return "LuceneQueueMessage [messageId=" + messageId + ", tableName=" + tableName + ", ids=" + ids + ", method="
 		return "LuceneQueueMessage [messageId=" + messageId + ", tableName=" + tableName + ", ids=" + ids + ", method="

+ 2 - 1
search-console-b2b/src/main/java/com/uas/search/console/b2b/schedule/model/TaskLog.java

@@ -1,5 +1,6 @@
 package com.uas.search.console.b2b.schedule.model;
 package com.uas.search.console.b2b.schedule.model;
 
 
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Date;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
@@ -60,7 +61,7 @@ public class TaskLog {
 
 
 	public String toJSONString() {
 	public String toJSONString() {
 		return "{'taskInformation': " + JSON.toJSONString(taskInformation) + ", 'executeTime': '"
 		return "{'taskInformation': " + JSON.toJSONString(taskInformation) + ", 'executeTime': '"
-				+ executeTime.toString() + "', 'log': " + log + "}";
+				+ new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(executeTime) + "', 'log': " + log + "}";
 	}
 	}
 
 
 	@Override
 	@Override

+ 1 - 2
search-console-b2b/src/main/java/com/uas/search/console/b2b/schedule/service/impl/TaskServiceImpl.java

@@ -15,7 +15,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.util.StringUtils;
 
 
-import com.alibaba.fastjson.JSONObject;
 import com.uas.search.b2b.exception.SearchException;
 import com.uas.search.b2b.exception.SearchException;
 import com.uas.search.console.b2b.core.util.PathUtils;
 import com.uas.search.console.b2b.core.util.PathUtils;
 import com.uas.search.console.b2b.schedule.model.Executable;
 import com.uas.search.console.b2b.schedule.model.Executable;
@@ -89,7 +88,7 @@ public class TaskServiceImpl implements TaskService {
 			fileWriter = new FileWriter(PathUtils.getAppPath() + "task-log.log", true);
 			fileWriter = new FileWriter(PathUtils.getAppPath() + "task-log.log", true);
 			fileWriter.write(log.toJSONString() + "\n");
 			fileWriter.write(log.toJSONString() + "\n");
 			fileWriter.flush();
 			fileWriter.flush();
-			logger.info("Saved task log:" + JSONObject.toJSONString(log) + "\n");
+			logger.info("Saved task log:" + log.toJSONString() + "\n");
 		} catch (IOException e) {
 		} catch (IOException e) {
 			e.printStackTrace();
 			e.printStackTrace();
 		} finally {
 		} finally {

+ 19 - 0
search-console-b2b/src/main/java/com/uas/search/console/b2b/service/RealTimeUpdateMonitorService.java

@@ -0,0 +1,19 @@
+package com.uas.search.console.b2b.service;
+
+import com.uas.search.console.b2b.schedule.model.TaskInformation;
+
+/**
+ * 定时监控实时更新异常情况
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 下午3:29:20
+ */
+public interface RealTimeUpdateMonitorService {
+
+	/**
+	 * 创建定时任务,监控实时更新异常情况
+	 * 
+	 * @return
+	 */
+	public TaskInformation newTask();
+}

+ 3 - 7
search-console-b2b/src/main/java/com/uas/search/console/b2b/service/UpdateVirtualColumnService.java

@@ -3,6 +3,8 @@ package com.uas.search.console.b2b.service;
 import com.uas.search.console.b2b.schedule.model.DailyTaskInformation;
 import com.uas.search.console.b2b.schedule.model.DailyTaskInformation;
 
 
 /**
 /**
+ * 每天定时更新虚拟列索引
+ * 
  * @author sunyj
  * @author sunyj
  * @since 2016年12月16日 上午11:42:25
  * @since 2016年12月16日 上午11:42:25
  */
  */
@@ -23,13 +25,7 @@ public interface UpdateVirtualColumnService {
 	 *            任务时间:秒
 	 *            任务时间:秒
 	 * @return
 	 * @return
 	 */
 	 */
-	public <T> DailyTaskInformation createUpdateOverdueDailyTask(Class<T> clazz, Integer hour, Integer minute,
+	public <T> DailyTaskInformation newUpdateOverdueDailyTask(Class<T> clazz, Integer hour, Integer minute,
 			Integer second);
 			Integer second);
 
 
-	/**
-	 * 开启定时任务
-	 * 
-	 * @return 返回的结果
-	 */
-	public String start();
 }
 }

+ 107 - 0
search-console-b2b/src/main/java/com/uas/search/console/b2b/service/impl/RealTimeUpdateMonitorServiceImpl.java

@@ -0,0 +1,107 @@
+package com.uas.search.console.b2b.service.impl;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.uas.message.sms.service.SmsService;
+import com.uas.search.b2b.model.SPage;
+import com.uas.search.console.b2b.SystemProperties;
+import com.uas.search.console.b2b.dao.LuceneQueueMessageDao;
+import com.uas.search.console.b2b.jms.AQListener;
+import com.uas.search.console.b2b.model.LuceneQueueMessage;
+import com.uas.search.console.b2b.schedule.model.Executable;
+import com.uas.search.console.b2b.schedule.model.TaskInformation;
+import com.uas.search.console.b2b.schedule.service.TaskService;
+import com.uas.search.console.b2b.service.RealTimeUpdateMonitorService;
+
+/**
+ * 创建定时任务,监控实时更新异常情况
+ * 
+ * @author sunyj
+ * @since 2016年12月19日 下午3:40:03
+ */
+@Service
+public class RealTimeUpdateMonitorServiceImpl implements RealTimeUpdateMonitorService {
+
+	@Autowired
+	private TaskService taskService;
+
+	@Autowired
+	private LuceneQueueMessageDao luceneQueueMessageDao;
+
+	@Autowired
+	private SmsService smsService;
+
+	@Autowired
+	private SystemProperties systemProperties;
+
+	/**
+	 * 上次查询时最旧的消息
+	 */
+	private LuceneQueueMessage oldestMessage;
+
+	@Autowired
+	private AQListener aqListener;
+
+	/**
+	 * 两次任务之间的等待时间间隔为10分钟
+	 */
+	private static final long PERIOD = 10 * 60 * 1000;
+
+	private Logger logger = Logger.getLogger(getClass());
+
+	@Override
+	public TaskInformation newTask() {
+		String title = "监控实时更新异常情况";
+		Executable command = new Executable() {
+			@Override
+			public void execute() {
+				// 如果实时更新未正常运行,发送警告短信并自动重启实时更新服务
+				if (!workWell()) {
+					logger.error("实时更新未正常运行");
+					sendWarnSms();
+					if (aqListener.isRunning()) {
+						aqListener.stop();
+					}
+					aqListener.start(null);
+				}
+			}
+		};
+		TaskInformation taskInformation = new TaskInformation(title, command, 0, PERIOD);
+		taskService.newTask(taskInformation);
+		return taskInformation;
+	}
+
+	/**
+	 * 实时更新服务是否运行良好
+	 * 
+	 * @return true 如果运行良好
+	 */
+	private boolean workWell() {
+		SPage<LuceneQueueMessage> sPage = luceneQueueMessageDao.findAll(1, 1, null);
+		// 如果消息队列中没有消息,说明没有等待更新的消息
+		if (sPage.getTotalElement() == 0) {
+			return true;
+		}
+		LuceneQueueMessage luceneQueueMessage = sPage.getContent().get(0);
+		if (oldestMessage == null) {
+			oldestMessage = luceneQueueMessage;
+			return true;
+		}
+		// 比较上次与本次查询的最旧的消息,如果两者相同,说明实时更新服务出现了问题
+		if (oldestMessage.equals(luceneQueueMessage)) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * 发送警告短信
+	 */
+	private void sendWarnSms() {
+		smsService.sendAll(systemProperties.getSmsTemplateId(), systemProperties.getSmsReceivers(),
+				new Object[] { "B2B实时更新服务出现问题,已经自动重启实时更新服务" });
+	}
+
+}

+ 2 - 1
search-console-b2b/src/main/java/com/uas/search/console/b2b/service/impl/SearchServiceImpl.java

@@ -70,6 +70,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 				content.add(Long.valueOf(document.get(ClassAndTableNameUtils.getIdField(tableName))));
 				content.add(Long.valueOf(document.get(ClassAndTableNameUtils.getIdField(tableName))));
 			}
 			}
 			sPage.setContent(content);
 			sPage.setContent(content);
+			logger.info(sPage + "\n");
 			return sPage;
 			return sPage;
 		} catch (NumberFormatException | IOException e) {
 		} catch (NumberFormatException | IOException e) {
 			throw new SearchException(e).setDetailedMessage(e);
 			throw new SearchException(e).setDetailedMessage(e);
@@ -275,7 +276,6 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 		}
 		}
 
 
 		sPage.setContent(Arrays.asList(topDocs.scoreDocs));
 		sPage.setContent(Arrays.asList(topDocs.scoreDocs));
-		logger.info(sPage + "\n");
 		return sPage;
 		return sPage;
 	}
 	}
 
 
@@ -314,6 +314,7 @@ public class SearchServiceImpl implements SearchService, InnerSearchService {
 				content.add(DocumentToObjectUtils.toObject(document, clazz));
 				content.add(DocumentToObjectUtils.toObject(document, clazz));
 			}
 			}
 			sPage.setContent(content);
 			sPage.setContent(content);
+			logger.info(sPage + "\n");
 			return sPage;
 			return sPage;
 		} catch (NumberFormatException | IOException e) {
 		} catch (NumberFormatException | IOException e) {
 			throw new SearchException(e).setDetailedMessage(e);
 			throw new SearchException(e).setDetailedMessage(e);

+ 1 - 9
search-console-b2b/src/main/java/com/uas/search/console/b2b/service/impl/UpdateVirtualColumnServiceImpl.java

@@ -128,7 +128,7 @@ public class UpdateVirtualColumnServiceImpl implements UpdateVirtualColumnServic
 	}
 	}
 
 
 	@Override
 	@Override
-	public <T> DailyTaskInformation createUpdateOverdueDailyTask(final Class<T> clazz, Integer hour, Integer minute,
+	public <T> DailyTaskInformation newUpdateOverdueDailyTask(final Class<T> clazz, Integer hour, Integer minute,
 			Integer second) {
 			Integer second) {
 		if (hour == null || minute == null || second == null) {
 		if (hour == null || minute == null || second == null) {
 			throw new NullPointerException();
 			throw new NullPointerException();
@@ -146,12 +146,4 @@ public class UpdateVirtualColumnServiceImpl implements UpdateVirtualColumnServic
 		return dailyTaskInformation;
 		return dailyTaskInformation;
 	}
 	}
 
 
-	@Override
-	public String start() {
-		if (!taskService.isStopped()) {
-			taskService.stop();
-		}
-		return taskService.start();
-	}
-
 }
 }

+ 1 - 1
search-console-b2b/src/main/webapp/resources/js/listenDetails/app.js

@@ -118,7 +118,7 @@ function listenDetails(page, size, searchContent) {
 function addList(i, tableName, ids, method, modifyTime, messageId) {
 function addList(i, tableName, ids, method, modifyTime, messageId) {
 	var listItemDiv = $("<div class='listItem'></div>");
 	var listItemDiv = $("<div class='listItem'></div>");
 	var noDiv = $("<div class='minWidthColumn floatLeft overflowHidden'><span>"
 	var noDiv = $("<div class='minWidthColumn floatLeft overflowHidden'><span>"
-			+ ((page - 1) * size + i + 1) + "</span></div>");
+			+ (totalElement - i - (page - 1) * size) + "</span></div>");
 	var tableNameDiv = $("<div class='mediumWidthColumn floatLeft overflowHidden'><span>"
 	var tableNameDiv = $("<div class='mediumWidthColumn floatLeft overflowHidden'><span>"
 			+ tableName + "</span></div>");
 			+ tableName + "</span></div>");
 	var idsDiv = $("<div class='maxWidthColumn floatLeft overflowHidden'><span>"
 	var idsDiv = $("<div class='maxWidthColumn floatLeft overflowHidden'><span>"