当前位置: 首页 > 知识库问答 >
问题:

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

文喜
2023-03-14

我有一个要求,作为其中的一部分,我想阅读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个答案

漆雕宏浚
2023-03-14

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

首先,您可以使用标志并调用message.isSet()来检查其他服务器是否设置了标志,然后message.set标志()来锁定。不幸的是,这会导致冲突。竞争可以通过一些不漂亮的黑客行为来修复,这些黑客行为涉及另外两个标志或一个名为condstore的IMAP扩展,而javamail显然不支持-setFlags()需要一个新的long参数来设置标志,只有当标志自客户端上次注意到以来没有改变时。

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

 类似资料:
  • 我有一个在线表格,允许用户通过电子邮件向公司投诉。为了测试它,我使用了gmail smtp作为我的主机。当发件人也是gmail时,我没有问题地将消息接收到指定的电子邮件帐户,但我希望“发件人”不仅仅限于gmail帐户。看来smtp只适用于从同一台服务器发送电子邮件? 如有任何帮助,将不胜感激。如果需要,我也可以提供我的代码。

  • 我试图发送电子邮件使用gmail smtp使用javax.mail.下面是我的代码 代码工作正常当我在本地服务器上运行它时,但当我尝试在Elastic beanstek上运行它时(我的服务器在AWS EBS上运行),身份验证失败异常即将到来注意:我已打开从Google A/c设置访问不太安全的应用程序,但我仍然收到此错误 javax.mail.身份验证失败异常:534-5.7.14请通过您的网络浏

  • 我是新来的角度。我已经在aws中的docker容器中部署了一个角度应用程序。应用程序需要连接到aws s3 bucket。我不需要硬编码aws键,所以我在docker中设置了一个环境变量。angular被部署为ngbuild中的dist文件夹由nginx docker容器提供服务。 一旦dist文件夹中的内容被送达服务器,是否可以通过角度读取服务器环境变量?就像php和nodejs中的env函数一

  • 我有一个服务器与静态IP在我的家里,我服务我自己的网页与一个域和所有工作良好。 在我的网页,你可以通过电子邮件和密码注册。当您注册一个名为nodemailer的节点模块,从google帐户发送电子邮件时,问题是google帐户有一个发送电子邮件的限制。 所以我需要将nodemailer模块连接到我自己家里的服务器上。 我在谷歌上搜索,但没有类似的答案。 如何在NodeJS中使用后缀?? http:

  • 问题内容: 我从服务器使用IMAP协议就像是接收电子邮件描述了这里。这工作得很好,我可以将电子邮件和附件存储在磁盘上。 问题: 当客户端尝试接收所有电子邮件时,是否可以从服务器删除文件,以使它们不再可用? 如果是这样,请告诉我如何。 问题答案: 您应该能够通过标准API来执行此操作。 首先,您需要获取Message要删除的(或消息)的引用-如果您成功阅读它们,那么您已经可以做到 这一点。现在,没有

  • 但还是没用。有什么帮助吗