我有一个要求,我要从Outlook中读取传入的电子邮件,然后进行一些处理。我正在使用JavaMail API和IMAP协议来实现此目的。事件。
在单服务器环境中,使用以下代码可以很好地工作,但是当我将其部署到拥有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();
}
关于如何限制在多服务器环境中仅处理一次电子邮件的任何建议?
答案 0 :(得分:0)
也许最简单的解决方法是使用分布式锁。有很好的库。但是,如果要在javamail中回答,则有两种方法。
首先,您可以使用Flag并调用message.isSet()来检查另一台服务器是否设置了该标志,然后调用message.setFlags()进行锁定。不幸的是那场比赛。可以通过涉及一些另外两个标志或Java邮件显然不支持的an IMAP extension called condstore的一些不道德的黑客来解决此问题-setFlags()仅在以下情况下需要使用新的long
参数来设置标志自客户上次注意到以来,这些标记没有改变。
第二,您可以使用一系列邮箱,并通过它移动邮件。您需要四个邮箱,即收件箱和另外三个邮箱,分别称为“ processing-a”,“ processing-b”和“ processed”。服务器A处理“处理a”中的所有消息,然后将每个消息移至“已处理”,B处理“处理b”。当每个服务器都完成其“ processing- foo ”处理后,它将在收件箱中查找新消息,并调用moveMessages()将一个或几个消息原子地移动到其自己的邮箱中。 moveMessages()使用an IMAP extension called move原子地移动消息,大多数服务器都支持,但不是全部。