Почему перебор всех папок пользователя java почты очень медленный?

   Properties props = System.getProperties();
   props.put("mail.imap.connectiontimeout",5000);
   Session session = Session.getInstance(props);
   Store store = session.getStore("imap");
   for(50K users){

        //login,password changed in loop  
        String[] folders = {"inbox", "f1", "f2", "f3", "spam"};
        store.connect(serverAddress, login + emailSuffix, password);
        for (int i = 0; i < folders.length; i++) {
                    Folder x = store.getFolder(folders[i]);
                    x.open(Folder.READ_ONLY);
                    System.out.println("folder " + folders[i] + " of " + login);
                    x.getUnreadMessageCount();
                    x.close(false);
        }
        store.close();
    }

Я использую один и тот же магазин для всех подключений, изменил service_count в dovecot согласно этому ответу, чтобы улучшить производительность imap-dovecot, но я вижу только первую итерацию, и после этого код зависает или делает следующий system.out после долгого времени.

На самом деле мне нужно захватить все старые сообщения всех пользователей + подсчитать все непрочитанные сообщения, так как я хочу перейти с чистого Java Mail в какой-то другой пользовательский формат. Мне не удалось даже просто перебрать всех пользователей и папки для каждого пользователя, потому что даже простой store.connect зависает после 1-й итерации!

Лично я считаю, что узким местом является моя конфигурация dovecot, но она использует ограничения по умолчанию (1000 соединений), что выглядит неплохо.

Я как-то улучшаю свой dovecot, или подключаю свой магазин только один раз для всех пользователей, или как-то извлекаю все сообщения всех пользователей и unreadMessagesCount всех пользователей другим способом?

PS. Единственная альтернатива программируемому способу - это некоторый bash-скрипт в maildir, который будет читать каждое сообщение из файловой системы и передавать его в некоторый отдых, который конвертируется в мой пользовательский формат), но это намного сложнее, чем Java, слишком сложно разобрать smptp, parse seen Флаги из имени файла и так далее.

ОБНОВИТЬ

Я нашел apache commons net imapclient, который работает очень быстро.

<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.3</version>
</dependency>

Мой код следующий

IMAPClient client = new IMAPClient();
client.connect("localhost");
for(50K users){
    client.login(login + emailSuffix, password);
    for (int i = 0; i < folders.length; i++) {
        System.out.println(client.select("INBOX"); //prints true, it's ok
    }
}
  1. Похоже, он подключается быстрее, чем java mailapi, потому что он можетподключиться один раз к хосту и после этого входа для каждого пользователя. Могу ли я как-нибудь повторить такое поведение в JavaMail API?
  2. Как я могу получить сообщения с помощью клиента Apache Commons? Все методы возвращают логическое значение или значение void, так что похоже, что это просто библиотека проверки сервера, я прав? Можно ли как-нибудь получить полезную информацию от imapclient?

1 ответ

Решение

Наконец, решил мою проблему, просто перебрав файловую систему (у меня есть формат maildir).

Я предполагаю, что Java Mail API делает новую аутентификацию dovecot для каждого пользователя в store.connect в то время как он должен просто подключиться один раз (использовать dovecot auth) и после этого войти в систему для каждого пользователя (использовать dovecot imap-login). Вот почему я ждал 1 минуту для каждой итерации - это стандартный процесс авторизации в конфигурации dovecot. Я не уверен, но выглядит так.

Apache lib работает быстро, но это всего лишь тестовая библиотека для проверки связи с сервером, проверки соединения и других операций imap. Возвращает логический результат об операциях, но не полезную информацию (

Другие вопросы по тегам