【问题标题】:java imap, performance issues, fetching all mailsjava imap,性能问题,获取所有邮件
【发布时间】:2015-07-20 17:50:18
【问题描述】:

我将使用 java mail api 来处理雷鸟等邮件。我必须获取包含 1000 条消息的邮件。我的设计将是:当用户对文件夹执行同步时,我将获取文件夹中消息的所有 uid:

Message[] msgs = ufolder.getMessagesByUID(1, UIDFolder.LASTUID);
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS); 

然后我会将 uid 列表与存储在我的数据库中的列表进行比较。 对于已删除的,例如一条消息不在文件夹中但在数据库中,我会将其标记为已删除。 对于新的,例如一条消息在文件夹中但不在数据库中,我将标记为可能是新的。但是,因为 messageuid 不安全(在某些情况下可以由邮件服务器更改),对于新邮件,我将使用额外的自定义散列值,从标头中的消息 id + 主题 + receivedate 构建并构建 md5 散列。仅对于可能的新邮件,我将使用此哈希并捕获新邮件。 对于被移动的消息,由于它们的uid在新文件夹中会发生变化,它会在第一个被标记为已删除,并且将是新文件夹中的新消息,但是由于消息头中的消息ID,该消息将具有相同的自定义哈希值移动期间其他属性将保持不变。

关于性能问题的问题:在每次点击文件夹(文件夹同步)时,我都会将文件夹中的所有 uid 与存储在数据库中的本地 uid 列表进行比较操作,以了解已删除的.我找不到另一种更好的方法来实现这一点。如您所知,即使文件夹很大并且已删除的邮件很旧(5 年),Thunderbird 也会立即捕获已删除的邮件而无需重新登录。我认为 Thunderbird 还会将该文件夹中的所有消息 uid 与本地存储的列表进行比较。

如何实现更好的同步机制以获得更好的性能?雷鸟是否采用不同的方法?雷鸟怎么可能 这么快就完成了?

如果我们只对新消息感兴趣,我可以保留最后存储的 uid 并且只比较晚于新消息,但对于已删除的消息,我已经必须比较完整文件夹。此外,我的邮件服务器中的 UIDNEXT 值始终为 -1,如果设置正确,再次删除将无济于事,我认为必须进行完整比较,我错了吗?

注意:我不能不使用或添加消息监听器,因为应用程序是基于服务器客户端的,邮件处理任务在服务器端,我们不支持线程监听器等。事件应该从客户端触发,请求正在服务器上处理并返回响应,客户端在 gui 上处理响应。

【问题讨论】:

    标签: email jakarta-mail imap fetch uid


    【解决方案1】:

    您想要的称为 condstore 或快速重新同步,在这两种情况下都是 RFC7162。这就是 Thunderbird 的用途。

    这是一对扩展支持命令,例如“给我自上次连接以来更改的所有 UID”、“告诉我删除了什么”等等。

    【讨论】:

    • 是的,但它说它没有得到广泛的支持,整个结构不应该建立在它上面:stackoverflow.com/questions/23176247/… 我认为我应该保留最后存储的 uid 并仅比较新邮件的 uid。还是应该使用 getNextUID()?但是在邮件服务器上它总是-1。另一方面,假设我存储 10.mail 的 uid 为 100,并且我保留了这个值。在 nexy fetch 上,我说 fetch 以 UID 100 和更高版本开头的邮件。但是在我取之前,带有uid的邮件已经被删除了? imap 是否支持获取大于 x 的 uid(uid 是否会增加?)
    • 只要邮箱的 uidvalidity 值保持不变,IMAP UID 总是会增加。这是完全正确的,它没有得到广泛的支持。但是如果你想做你想做的事情,这是最广泛支持的方式(实际上也是唯一的方式)。各种服务器不支持它,例如 mail.ru,这实际上意味着如果俄罗斯最终用户是您目标市场的重要组成部分,那么您想要的功能实际上是无法实现的。
    【解决方案2】:

    如果您不能使用线程来侦听来自邮件服务器的这些事件,那么您的选择将非常有限。您可以做的最好的事情可能是将重新同步限制为客户端可见的消息。

    【讨论】:

    • 邮件客户端(例如 tbird)是否注册侦听器并在删除邮件时收到通知,或者当用户触发刷新或同步时,它们是否会执行完整的 uid 检查并与当前文件夹本地存储的 uid 列表进行比较?
    • 好吧,他们不使用 JavaMail,所以谁知道他们是如何真正处理这个问题的,但我相信他们会监视使用 JavaMail 中的侦听器通知的相同事件。
    • 但是,在初始阶段,当第一次登录时,他们必须以某种方式获取一个列表并与本地进行比较。另一方面,我们不能总是依赖监听器,imap-idle 支持离线工作。发生了什么,我们连接到邮件服务器并收听,收到邮件但我们的网络在短时间内断开连接,邮件服务器通知我们但我们没有收到。当我们重新连接时会发生什么?邮件服务器是否再次发送事件?它是否等待我们的确认,如果没有收到,它会再次发送事件吗?
    • 这很复杂。要查看 Thunderbird 的功能,请启用 session logging。您需要仔细阅读IMAP RFC。您还会发现 RFC 1733RFC 4549 很有帮助。还有很多 IMAP 扩展(例如,CONDSTORE、QRESYNC)会有所帮助,但是服务器对扩展的支持是不一致的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 1970-01-01
    • 2017-06-02
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多