繁体   English   中英

如何确保在使用JavaMail API时,多服务器环境中的某个服务器只读取一次电子邮件

[英]how to ensure that an email is read only once by one of the server in multiserver environment while using JavaMail API

我有一个要求作为其中一部分,我想从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();
}

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

也许最简单的解决方法是使用分布式锁; 有很好的图书馆。 但是如果你想在javamail中找到答案,那么有两种方法。

首先,您可以使用Flag并调用message.isSet()来检查其他服务器是否已设置标志,然后将message.setFlags()锁定。 不幸的是那场比赛。 可以通过一些不合适的hackery来修复竞争,这些hackery涉及另外两个标志或者一个名为condstore的IMAP扩展 ,javamail显然不支持 - 只有当标志没有改变时, setFlags()需要一个新的long参数来设置标志自从客户最后注意到。

其次,您可以使用邮箱的进度并通过它移动邮件。 您需要四个邮箱,即收件箱和另外三个称为“processing-a”,“processing-b”和“processed”的邮箱。 服务器A处理“处理-a”中的所有消息,然后将每个消息移动到“已处理”,B处理“处理-b”。 当每个服务器完成其“processing- foo ”时,它会在收件箱中查找新消息,并调用moveMessages()将一个或几个消息原子地移动到它自己的邮箱。 moveMessages()使用名为move的IMAP扩展以原子方式移动消息,并且大多数服务器都支持,但不是全部。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM