JavaMail、IMAP、大量文件夹的性能

JavaMail, IMAP, performance with large number of folders

我们正在为 IMAP 帐户开发基于 java 的邮件客户端,并使用最新的 java 邮件 api (1.5.6)。我们的客户拥有包含 400 多个文件夹的邮件帐户。用户对文件夹执行检查邮件并迭代每个文件夹并获取新邮件,例如

folder.getMessagesByUid(lastStoredUID, UIDFolder.LastUID)

或者获取未读邮件的数量需要太多时间,因为文件夹数量巨大。 (我们必须迭代 400 个文件夹)

为了提高性能,我们在线程中使用了并行工作连接,我们有一个 SESSION 实例,但每个线程(连接)都有自己的 STORE 实例。当我们必须获取新消息时,我们会动态生成 10 个线程及其 STORE 实例,connect/login 它们分开,在该 STORE 上获取文件夹实例,打开文件夹,执行文件夹操作,关闭文件夹,然后关闭 SESSION .但对我来说不清楚,我是否必须保留文件夹实例,而且我也不清楚 文件夹是否应该保持打开状态,或者我们应该明确地在后面关闭,还是我们可以保留所有打开(将关闭操作留给邮件服务器)。

在我目前的实施中,

new Thread() {
    public void run() {
        //Get a new store instance
        Store tempStore = MySingleSession.getStore("imap");
        tempStore.connect(..);

        //Get a folder for example inbox
        Folder inbox = tempStore.get("INBOX");

        inbox.open(Folder.READ);

        // Perform get new messages
        inbox.getMessagesByUd(lastUID, UIDFolder.MaxUID);

        inbox.close();

        tempStore.close();
        ..

检查性能时,我发现 opening/closing 文件夹需要很长时间,尤其是在包含超过 100.000 封邮件的文件夹上。而且我看到,即使我关闭文件夹的存储,文件夹仍保持打开状态,如果我们没有明确关闭该文件夹,我们可以对其进行操作。如果我更改我的实现并且不显式关闭文件夹并保持它们打开,那么这种机制有什么缺点?

IMAPFolder f = folderCache.get("INBOX"); // 假设已经放入 hashtable folderCache

IMAPFolder f = tempStore.getFolder("INBOX");

我按需生成 Store 实例,然后关闭它们,以免在邮件服务器上占用大量资源。但是再次打开文件夹而不是手动关闭不是一个好方法,因为它仍然使用资源?或者使用这种方式是可以接受的,因为邮件服务器可能会在需要时关闭它,我们只需要检查是否

一个 post 的问题太多了。让我尝试回答其中的一些...

关闭文件夹后,不应使用文件夹中的任何消息对象,因此只有在使用完消息后才关闭文件夹。

如果单个用户有 400 个文件夹,您可以使用单个应用商店连接,因为每个打开的文件夹都会获得自己的连接。

如果您频繁打开和关闭文件夹,增加连接池大小会有所帮助,因为关闭的文件夹的连接将添加到池中并在您打开新文件夹时重新使用,而无需创建新连接。

关闭商店应该关闭该商店的所有文件夹,但如果涉及多个线程,则存在固有的竞争条件。关闭商店是一种在您使用完后清除所有连接的方法,而不是防止其他线程重新打开文件夹的方法。

为关闭的文件夹缓存文件夹对象不太可能比每次调用 getFolder 有很大优势。