Spring IMAP poll在延迟数小时后读取电子邮件



我使用Spring Integration从使用3个适配器的3个邮箱轮询电子邮件。我使用customSearchTermStatregy在收到邮件10分钟后阅读。

此应用程序读取电子邮件并将这些电子邮件保存到本地目录为。eml文件.

现在的问题是,有些邮件在延迟4-5小时后才被读取

我也配置了一个线程池,但我怀疑spring轮询器没有得到线程分配马上要读邮件,因此耽误了阅读。

还请注意,这个应用程序是在tomcat下与其他10多个java应用程序一起运行的在同一个tomcat下运行

谁能指出一些可能的原因在这4-5小时的延误背后?

春Integration.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mail="http://www.springframework.org/schema/integration/mail"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:task="http://www.springframework.org/schema/task"       
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/integration/mail
http://www.springframework.org/schema/integration/mail/spring-integration-mail-5.2.xsd 
http://www.springframework.org/schema/util 
http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/task 
http://www.springframework.org/schema/task/spring-task-4.3.xsd">
<util:properties id="javaMailProperties">
<prop key="mail.imap.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
<prop key="mail.imap.socketFactory.fallback">false</prop>
<prop key="mail.store.protocol">imaps</prop>
<prop key="mail.debug">${imap.debug}</prop>
<prop key="mail.imaps.partialfetch">false</prop>
<prop key="mail.imaps.fetchsize">102400</prop>   <!-- 100KB, default is 16KB -->  
</util:properties>

<task:executor id="taskExecutor"  pool-size="15-50" queue-capacity="100"/>
<mail:inbound-channel-adapter id="imapAdapter1" 
store-uri="${imap.uri.mail}"                                     
channel="recieveEmailChannel"                                          
should-delete-messages="false"
should-mark-messages-as-read="true"                                      
auto-startup="true"
simple-content="true"
auto-close-folder="false"
search-term-strategy="mailSearchTermStrategy"
java-mail-properties="javaMailProperties">
<!-- <int:poller fixed-delay="${imap.polling.interval}" time-unit="SECONDS"/> -->
<int:poller cron="0 0/2 1-23 * * ?" max-messages-per-poll="1" task-executor="taskExecutor"/> <!-- every 2 mins, from 1AM to 11.59PM -->
</mail:inbound-channel-adapter>

<mail:inbound-channel-adapter id="imapAdapter2" 
store-uri="${imap.uri.fax}"                                     
channel="recieveEmailChannel"                                          
should-delete-messages="false"
should-mark-messages-as-read="true"                                      
auto-startup="true"
simple-content="true"
auto-close-folder="false"
search-term-strategy="faxSearchTermStrategy"
java-mail-properties="javaMailProperties">
<int:poller cron="0 0/2 1-23 * * ?" max-messages-per-poll="1" task-executor="taskExecutor"/> <!-- every 2 mins, from 1AM to 11.59PM -->
</mail:inbound-channel-adapter>

<mail:inbound-channel-adapter id="imapAdapter3" 
store-uri="${imap.uri.scan}"                                     
channel="recieveEmailChannel"                                          
should-delete-messages="false"
should-mark-messages-as-read="true"                                      
auto-startup="true"
simple-content="true"
auto-close-folder="false"
search-term-strategy="scanSearchTermStrategy"
java-mail-properties="javaMailProperties">
<int:poller cron="0 0/2 1-23 * * ?" max-messages-per-poll="1" task-executor="taskExecutor"/> <!-- every 2 mins, from 1AM to 11.59PM -->
</mail:inbound-channel-adapter>
<int:channel id="recieveEmailChannel">        
<int:interceptors>
<int:wire-tap channel="logger"/>
</int:interceptors>
</int:channel>
<int:logging-channel-adapter id="logger" level="DEBUG"/>
<int:service-activator input-channel="recieveEmailChannel" ref="emailReceiver" method="handleMessage"/>
<!-- <bean id="emailReceiver" class="com.abc.xyz.receiver.EmailReceiver">
</bean>  -->  
</beans>

CustomSearchTermStrategy:

@Service
public class CustomSearchTermStrategy implements SearchTermStrategy {

@Value("${email.delay.mins}")
int emailDelayMins; 

Logger logger = LoggerFactory.getLogger(CustomSearchTermStrategy.class);

@Override
public SearchTerm generateSearchTerm(Flags supportedFlags, Folder folder) {

SearchTerm customSentDateTerm = new SearchTerm(){           
private static final long serialVersionUID = 4583016738325920713L;
public boolean match(Message message) {
try {
ZoneId zoneId = ZoneId.of("America/Los_Angeles");                  
ZonedDateTime sendDtInPST =  message.getSentDate().toInstant().atZone(zoneId);              
ZonedDateTime currentZdt = ZonedDateTime.now(zoneId);                  
ZonedDateTime currentTimeMinus10Mins = currentZdt.minusMinutes(emailDelayMins);
Flags flags = message.getFlags();

if(currentTimeMinus10Mins.isAfter(sendDtInPST)) {                       
if(!flags.contains(Flags.Flag.SEEN)) {
logger.info("CurrentTimeMinus"+emailDelayMins+"MinsInPST is AFTER sendDtInPST, so this email picked for read, subject:{}", message.getSubject());
return true;   
}
}   
} catch (Exception ex) {
ex.printStackTrace();
}
return false;
}
};
return customSentDateTerm;
}
}

在我们的示例中,从IMAP服务器轮询大型电子邮件的延迟是因为我们使用了属性mail.imap的默认值。Fetchsize =16kb和mail.imap.partialfetch=true.

这使得电子邮件的大小为16kb,这导致轮询的时间很长。我们设置mail。imap。Partialfetch =false,以确保邮件在一定时间内被获取

有关IMAP

中的进一步属性设置,请参阅此https://javaee.github.io/javamail/docs/api/com/sun/mail/imap/package-summary.html

目前您显示了3个将同时运行的轮询器。默认情况下,所有这些轮询器都是由TaskScheduler触发的(不要与TaskExecutor混合),它基于10个线程池。所以,现在我看到3个并发线程被你的电子邮件通道适配器占用。在您的应用程序中有一些其他轮询器可能并不奇怪。它们都有相同的TaskScheduler

您可以修改所有的轮询器,将实际工作转移到特定的执行器中,或者您可以考虑增加TaskScheduler线程池:https://docs.spring.io/spring-integration/docs/current/reference/html/configuration.html#namespace-taskscheduler

您还可以执行线程转储来分析哪些线程繁忙以及为什么繁忙。

最新更新