java - 使用 JavaMail API 时,如何确保多服务器环境中的一台服务器仅读取电子邮件一次

标签 java jakarta-mail imap multiserver

我有一个要求,其中我想读取来自 Outlook 的传入电子邮件,然后进行一些处理。我正在使用 JavaMail API 和 IMAP 协议(protocol)来实现此目的。我编写了一个 java 类,可以读取 messagesAdded 上的电子邮件事件。

它在单服务器环境中与以下代码完美配合,但是当我将其部署到我们有两台服务器的生产中时,我最终会处理每封电子邮件两次,因为两台服务器上都部署了相同的代码,两台服务器都尝试读取电子邮件一旦在邮箱中收到。

下面是我用来连接邮箱和阅读电子邮件的代码片段:

 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();
}

关于如何限制电子邮件在多服务器环境中仅处理一次有什么建议吗?

最佳答案

也许解决这个问题最简单的方法是使用分布式锁;有一些很好的库可以做到这一点。但如果您想在 javamail 中得到答案,那么有两种方法。

首先,您可以使用Flag并调用message.isSet()检查其他服务器是否已设置标志,然后 message.setFlags()锁定。不幸的是,比赛。比赛可以通过一些不漂亮的黑客行为来解决,涉及两个以上的标志或或 an IMAP extension called condstore javamail 显然不支持 — setFlags()仅当自客户端上次注意到以来标志未发生更改时,才需要一个新的 long 参数来设置标志。

其次,您可以使用一系列邮箱并通过其中移动邮件。您需要四个邮箱,即收件箱和其他三个邮箱,可能称为“处理-a”、“处理-b”和“已处理”。服务器 A 处理“processing-a”中的所有消息,然后将每条消息移至“processed”,B 负责“processing-b”。当每个服务器完成其“processing-foo”时,它会在收件箱中查找新消息并调用 moveMessages()将一封或多封邮件自动移至其自己的邮箱。 moveMessages() 使用 an IMAP extension called move以原子方式移动消息,大多数服务器都支持,但不是全部。

关于java - 使用 JavaMail API 时,如何确保多服务器环境中的一台服务器仅读取电子邮件一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55990466/

相关文章:

java - Selenium 2.53.0 Firefox 漏洞

wordpress - Quercus + WordPress 电子邮件配置

php - 无法使用 IMAP 获取纯文本邮件内容

go - 如何将消息标记为已读 ,\Seen on IMAP ( Go )

java - 连接池的MySQL实现

Java 合并两个映射

java - 不同操作系统下 JavaMail 中 part.getContent 的类型是什么?

ssl - Javamail、Weblogic、IMAP、SSL 和 Exchange 2010

node.js - 使用 node-imap 与 Gmail 的非 SSL 连接

java - 选择并迭代具有相同名称的元素和子元素(Jsoup)