|
|
@@ -0,0 +1,203 @@
|
|
|
+package com.uas.search.jms;
|
|
|
+
|
|
|
+import com.uas.search.constant.model.SPage;
|
|
|
+import com.uas.search.model.LuceneMessage;
|
|
|
+import com.uas.search.model.ParsedQueueMessage;
|
|
|
+import com.uas.search.schedule.model.TaskInformation;
|
|
|
+import com.uas.search.schedule.service.Executable;
|
|
|
+import com.uas.search.schedule.service.TaskService;
|
|
|
+import com.uas.search.service.IndexService;
|
|
|
+import com.uas.search.service.LuceneMessageService;
|
|
|
+import com.uas.search.util.CollectionUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**对数据库的消息队列进行实时监听
|
|
|
+ * @author sunyj
|
|
|
+ * @since 2017/10/11 16:20
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class JmsListener {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 第一次执行的延迟时间间隔为1秒
|
|
|
+ */
|
|
|
+ private static final long INITIAL_DELAY = 1000;
|
|
|
+ /**
|
|
|
+ * 两次任务之间的等待时间间隔为 1 秒钟
|
|
|
+ */
|
|
|
+ private static final long PERIOD = 1000;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IndexService indexService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private TaskService taskService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private LuceneMessageService luceneMessageService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private QueueMessageParser queueMessageParser;
|
|
|
+
|
|
|
+ private TaskInformation taskInformation;
|
|
|
+
|
|
|
+ private Logger logger = LoggerFactory.getLogger(getClass());
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 开启实时更新索引
|
|
|
+ *
|
|
|
+ * @param period
|
|
|
+ * 每次接收到jms消息后等待的时间(秒)
|
|
|
+ * @return 开启成功与否的提示信息
|
|
|
+ */
|
|
|
+ public String start(Long period) {
|
|
|
+ if(period == null){
|
|
|
+ period = PERIOD;
|
|
|
+ }else{
|
|
|
+ period *= 1000;
|
|
|
+ }
|
|
|
+ if(period <= 0){
|
|
|
+ throw new IllegalArgumentException("period 不合法:" + period);
|
|
|
+ }
|
|
|
+
|
|
|
+ String message = "";
|
|
|
+ if (isRunning()) {
|
|
|
+ message = "已存在运行的索引实时更新服务";
|
|
|
+ logger.warn(message);
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+// QueueConnectionFactory queueConnectionFactory = AQjmsFactory.getQueueConnectionFactory(dataSource.getUrl(),
|
|
|
+// new Properties());
|
|
|
+// QueueConnection connection = queueConnectionFactory.createQueueConnection(dataSource.getUsername(),
|
|
|
+// dataSource.getPassword());
|
|
|
+// AQjmsSession session = (AQjmsSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
|
|
+// Queue queue = session.getQueue(dataSource.getUsername(), SearchConstants.LUCENE_QUEUE_NAME);
|
|
|
+// consumer = session.createConsumer(queue, null, QueueMessageTypeFactory.getFactory(), null, false);
|
|
|
+ String title = "实时更新";
|
|
|
+ Executable command = new Executable() {
|
|
|
+ @Override
|
|
|
+ public String execute() {
|
|
|
+ SPage<LuceneMessage> sPage = luceneMessageService.findAll(1, 100);
|
|
|
+ List<LuceneMessage> luceneMessages = sPage.getContent();
|
|
|
+ if (CollectionUtils.isEmpty(luceneMessages)) {
|
|
|
+ return "无消息";
|
|
|
+ }
|
|
|
+ for(LuceneMessage luceneMessage : luceneMessages){
|
|
|
+ try {
|
|
|
+ process(luceneMessage);
|
|
|
+ } catch (Throwable e) {
|
|
|
+ logger.error("", e);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 如果消息不止一页,立即消费下一页
|
|
|
+ if(sPage.getPage() > 1){
|
|
|
+ execute();
|
|
|
+ }
|
|
|
+ return "正常";
|
|
|
+ }
|
|
|
+ };
|
|
|
+ taskInformation = new TaskInformation(title, command, INITIAL_DELAY, period);
|
|
|
+ taskService.newTask(taskInformation);
|
|
|
+ if (!taskService.isStopped()) {
|
|
|
+ taskService.stop();
|
|
|
+ }
|
|
|
+ taskService.start();
|
|
|
+//
|
|
|
+// // 添加监听器,队列中一旦有消息入队,就会接受该消息(并不是真的实时,一般会有10秒以内的延迟)
|
|
|
+// consumer.setMessageListener(new MessageListener() {
|
|
|
+// @Override
|
|
|
+// public void onMessage(Message message) {
|
|
|
+// try {
|
|
|
+// if (period != null) {
|
|
|
+// // 等待waitInterval秒,为了等待数据表变动的事务提交
|
|
|
+// // 如果时间过短,事务可能还未提交
|
|
|
+// // 如果时间过长,实时更新速度很慢
|
|
|
+// Thread.sleep(period * 1000);
|
|
|
+// }
|
|
|
+// } catch (InterruptedException e) {
|
|
|
+// logger.error("", e);
|
|
|
+// }
|
|
|
+// AQjmsAdtMessage adtMessage = (AQjmsAdtMessage) message;
|
|
|
+// try {
|
|
|
+// QueueMessageTypeFactory payload = (QueueMessageTypeFactory) adtMessage.getAdtPayload();
|
|
|
+// // 对出队的消息进行解析、处理
|
|
|
+// process(payload.getMessage());
|
|
|
+// } catch (Throwable e) {
|
|
|
+// logger.error("", e);
|
|
|
+// }
|
|
|
+// }
|
|
|
+// });
|
|
|
+// connection.start();
|
|
|
+ message = "索引实时更新服务成功开启";
|
|
|
+ logger.info(message);
|
|
|
+ } catch (Throwable e) {
|
|
|
+ message = "索引实时更新服务开启失败";
|
|
|
+ logger.error(message, e);
|
|
|
+ if (taskInformation != null) {
|
|
|
+// try {
|
|
|
+// consumer.close();
|
|
|
+// } catch (JMSException e1) {
|
|
|
+// logger.error("", e1);
|
|
|
+// }
|
|
|
+ taskInformation = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭实时更新索引服务
|
|
|
+ *
|
|
|
+ * @return 关闭成功与否的提示信息
|
|
|
+ */
|
|
|
+ public String stop() {
|
|
|
+ String message = "";
|
|
|
+ if (!isRunning()) {
|
|
|
+ message = "索引实时更新服务未开启或已关闭";
|
|
|
+ logger.warn(message);
|
|
|
+ } else {
|
|
|
+// try {
|
|
|
+// consumer.close();
|
|
|
+// message = "索引实时更新服务成功关闭";
|
|
|
+// logger.info(message);
|
|
|
+// } catch (JMSException e) {
|
|
|
+// message = "索引实时更新服务关闭失败";
|
|
|
+// logger.error(message, e);
|
|
|
+// }
|
|
|
+ taskService.remove(taskInformation.getCode());
|
|
|
+ taskInformation = null;
|
|
|
+ if (!taskService.isStopped()) {
|
|
|
+ taskService.stop();
|
|
|
+ }
|
|
|
+ taskService.start();
|
|
|
+ }
|
|
|
+ return message;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return 索引实时更新服务是否正在运行
|
|
|
+ */
|
|
|
+ public boolean isRunning() {
|
|
|
+ return taskInformation != null && taskService.exist(taskInformation.getCode());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对得到的队列消息进行解析,之后根据解析出来的对象,对lucene索引进行添加、更新或删除操作
|
|
|
+ *
|
|
|
+ * @param luceneMessage
|
|
|
+ */
|
|
|
+ private void process(LuceneMessage luceneMessage) {
|
|
|
+ logger.info(luceneMessage.toString());
|
|
|
+ ParsedQueueMessage parsedQueueMessage = queueMessageParser.parse(luceneMessage.getTableName(), luceneMessage.getDataId(), luceneMessage.getMethodType(), luceneMessage.getData());
|
|
|
+ indexService.maintainIndexes(parsedQueueMessage);
|
|
|
+ luceneMessageService.dequeueLuceneMessage(luceneMessage.getId());
|
|
|
+ }
|
|
|
+}
|