为什么迭代所有 java 邮件用户的文件夹非常慢?
Why iterating over all java mail user's folders very slow?
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();
}
我对所有连接使用相同的存储,根据 在 dovecot 中更改 service_count
以提高 imap-dovecot 性能,但我只看到第一次迭代,然后代码挂起或长时间后执行下一个 system.out。
实际上,我需要获取所有用户的所有旧邮件 + 计算所有未读邮件,因为我想从纯 Java 邮件迁移到某种自定义格式。我什至没有设法为每个用户迭代所有用户和文件夹,因为即使是简单的 store.connect 在第一次迭代后也会挂起!
我个人认为瓶颈是我的 dovecot 配置,但它使用默认限制(1000 个连接)看起来不错。
我以某种方式改进了我的 dovecot 或只为所有用户连接我的商店一次,或者以其他方式以某种方式获取所有用户的所有消息和所有用户的 unreadMessagesCount?
PS。编程方式的唯一替代方法是 maildir 中的一些 bash 脚本,它将从文件系统中读取每条消息并将其传递给其他转换为我的自定义格式的消息)但它比 Java 难得多难以解析 smptp,从文件名解析 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
}
}
- 看起来它的连接速度比 java mailapi 快,因为它可能
连接一次主机,然后每个用户登录。我可以在 Java 邮件 API 中重复这种行为吗?
- 如何使用 apache commons 客户端抓取消息?所有方法 return 布尔值或 void,所以它看起来只是服务器检查库,对吗?是否有可能以某种方式从 imapclient 获取有用的信息?
终于通过简单的遍历文件系统解决了我的问题(我有 maildir 格式)。
我猜 Java Mail API 为 store.connect
中的每个用户创建新的 dovecot 身份验证,而它应该只连接一次(使用 dovecot 身份验证)然后再连接为每个用户登录(使用 dovecot imap-login)。 这就是我每次迭代等待 1 分钟的原因 - 它在 dovecot 配置中的身份验证进程处于标准空闲状态。我不确定,但看起来是这样。
Apache 库 但它只是测试库 用于 ping 服务器、检查连接和其他 imap 操作。它 returns 关于操作的布尔结果,但不是有用的信息(
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
以提高 imap-dovecot 性能,但我只看到第一次迭代,然后代码挂起或长时间后执行下一个 system.out。
实际上,我需要获取所有用户的所有旧邮件 + 计算所有未读邮件,因为我想从纯 Java 邮件迁移到某种自定义格式。我什至没有设法为每个用户迭代所有用户和文件夹,因为即使是简单的 store.connect 在第一次迭代后也会挂起!
我个人认为瓶颈是我的 dovecot 配置,但它使用默认限制(1000 个连接)看起来不错。
我以某种方式改进了我的 dovecot 或只为所有用户连接我的商店一次,或者以其他方式以某种方式获取所有用户的所有消息和所有用户的 unreadMessagesCount?
PS。编程方式的唯一替代方法是 maildir 中的一些 bash 脚本,它将从文件系统中读取每条消息并将其传递给其他转换为我的自定义格式的消息)但它比 Java 难得多难以解析 smptp,从文件名解析 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
}
}
- 看起来它的连接速度比 java mailapi 快,因为它可能 连接一次主机,然后每个用户登录。我可以在 Java 邮件 API 中重复这种行为吗?
- 如何使用 apache commons 客户端抓取消息?所有方法 return 布尔值或 void,所以它看起来只是服务器检查库,对吗?是否有可能以某种方式从 imapclient 获取有用的信息?
终于通过简单的遍历文件系统解决了我的问题(我有 maildir 格式)。
我猜 Java Mail API 为 store.connect
中的每个用户创建新的 dovecot 身份验证,而它应该只连接一次(使用 dovecot 身份验证)然后再连接为每个用户登录(使用 dovecot imap-login)。 这就是我每次迭代等待 1 分钟的原因 - 它在 dovecot 配置中的身份验证进程处于标准空闲状态。我不确定,但看起来是这样。
Apache 库