Как обработать электронную почту с почтового сервера только один раз из кластерной среды Java - PullRequest
0 голосов
/ 08 апреля 2020

Я перемещаю существующий почтовый сервер в IPWorks IMail. Код Java, который подключается к серверу, работает как кластер JBoss с двумя членами домена и тремя серверами на участника (всего 6 развертываний приложений). Каждый узел запускает следующий код в потоке, который создается при запуске в сервлете:

public void run() {
  long count = 0;
  do {
    Store store = null;
    Folder folder = null;
    try {
      store = connectToStore();
      folder = store.getFolder("INBOX");
      folder.open(Folder.READ_WRITE);
      count = folder.getMessageCount();
      Message[] msgs = folder.getMessages();

      if (count > 0) {

        for (int i = 0; i < count; i++) {
          Message msg = msgs[i];
          long result = SUCCESS;

          try {
            String subj = msg.getSubject();
            String buf = (String) msg.getContent();

            InternetAddress ia = (InternetAddress) msg.getRecipients(Message.RecipientType.TO)[0];
            String to = ia.getAddress();
            ia = (InternetAddress) msg.getFrom()[0];
            String from = ia.getAddress();

            result = create(from, to, subj, buf);
            if (SUCCESS != result) {
              processResponse(subj, buf, to, servletContext);
            }
          } catch (Exception eind) {
            log.error(this.getClass().getName(), eind);
          }

          try {
            msg.setFlag(Flags.Flag.DELETED, true);
          } catch (Exception edel) {
            log.error(this.getClass().getName(), edel);
          }
        }
      }
      Thread.sleep(delay);
    } catch (AuthenticationFailedException afe) {
      log.info("AuthenticationFailedException: ", afe);
    } catch (Exception e) {
      log.error(this.getClass().getName(), e);
      try {
        Thread.sleep(delay * 5);
      } catch (InterruptedException ie) {
        log.error(this.getClass().getName(), ie);
      }
    }
    try {
      if (folder != null) {
        folder.close(true);
      }
      if (store != null) {
        store.close();
      }
    } catch (Exception e) {
      log.error(this.getClass().getName(), e);
    }
  } while (!stop);
}

Это приводит к тому, что входящие электронные письма обрабатываются 6 раз с IMail POP3S, но только один раз на предыдущем linux размещенном POP3 сервер.

Я изначально пытался использовать IMAP вместо POP3. Когда я обнаружил эту проблему, я вернулся к POP3, потому что POP3 должен позволять только одному клиенту подключаться к входящей почте, согласно википедии. Я предположил, что IMAP был причиной обработки нескольких сообщений.

Вопрос: Каков рекомендуемый подход к получению электронной почты с сервера входящей почты в кластерной среде?

Уточнение вопроса: Есть ли что-то, что можно сделать из кода (javaEE-speci c, синхронизация потоков между узлами в кластере и т. Д. c.)? Следует ли ограничивать обработку сообщения одним клиентом на стороне IMail или я должен использовать другой подход, такой как жесткое кодирование имени сервера в потоке, чтобы только один конкретный экземпляр мог подключиться к входящей почте?

Очевидно, что все узлы подключаются к входящей почте и каждый получает сообщение (каждый помечает его для удаления), и я хочу, чтобы сообщение было обработано только один раз.

...