как обеспечить, чтобы электронная почта читалась только один раз одним сервером в многосерверной среде при использовании JavaMail API - PullRequest
0 голосов
/ 05 мая 2019

У меня есть требование, в рамках которого я хочу прочитать входящие электронные письма из outlook, а затем выполнить некоторую обработку. Я использую JavaMail API вместе с протоколом IMAP для реализации этого. Я написал класс Java, который читает электронную почту на messagesAdded событие.

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

Ниже приведен фрагмент кода, который я использую для подключения к почтовому ящику и чтения электронной почты:

 try {
    Properties props = System.getProperties();
    // Get a Session object
    Session session = Session.getInstance(props, null);
    // session.setDebug(true);

    // Get a Store object
    Store store = session.getStore("imap");

    // Connect
    store.connect(argv[0], argv[1], argv[2]);

    // Open a Folder
    Folder folder = store.getFolder(argv[3]);
    if (folder == null || !folder.exists()) {
    System.out.println("Invalid folder");
    System.exit(1);
    }

    folder.open(Folder.READ_WRITE);

    // Add messageCountListener to listen for new messages
    folder.addMessageCountListener(new MessageCountAdapter() {
    public void messagesAdded(MessageCountEvent ev) {
        Message[] msgs = ev.getMessages();
        System.out.println("Got " + msgs.length + " new messages");
        // Process incoming mail.

} catch (Exception ex) {
    ex.printStackTrace();
}

Какие-либо предложения о том, как ограничить обработку электронной почты только один раз в многосерверной среде?

1 Ответ

0 голосов
/ 06 мая 2019

Пожалуй, самый простой способ решить эту проблему - это распределенная блокировка;для этого есть хорошие библиотеки.Но если вы хотите получить ответ в javamail, то есть два способа.

Во-первых, вы можете использовать Flag и вызвать message.isSet () , чтобы проверить,другой сервер установил флаг и затем message.setFlags () для блокировки.К сожалению, это гонки.Гонка может быть исправлена ​​с помощью некоторого неуместного взлома, включающего либо еще два флага, либо расширение IMAP, называемое condstore , которое javamail, по-видимому, не поддерживает - setFlags () потребуется новый long аргумент для установки флага, только если флаги не изменились с тех пор, как клиент заметил в последний раз.

Во-вторых, вы можете использовать последовательность почтовых ящиков и перемещать сообщения через нее.Вам нужны четыре почтовых ящика, а именно входящие и три других, которые называются, возможно, «processing-a», «processing-b» и «processing».Сервер A обрабатывает все сообщения в «processing-a» и впоследствии перемещает каждое из них в «processing», B заботится о «processing-b».Когда каждый сервер завершает свою обработку « foo », он ищет новые сообщения в папке «Входящие» и вызывает moveMessages () для атомного перемещения одного или нескольких сообщений в свой почтовый ящик.,moveMessages () использует расширение IMAP, называемое move , для атомарного перемещения сообщений и поддерживается большинством серверов, но не всеми.

...