spring imap轮询器在延迟数小时后读取电子邮件

llycmphe  于 2021-07-24  发布在  Java
关注(0)|答案(1)|浏览(343)

我正在使用SpringIntegration使用3个适配器来轮询来自3个邮箱的电子邮件。我使用customsearchtermstatregy在收到10分钟后阅读电子邮件。
此应用程序读取电子邮件并将这些电子邮件作为.eml文件保存到本地目录中。
现在的问题是,有些邮件是经过4-5个小时的延迟后被投票人阅读的。
我还配置了一个线程池,但我怀疑spring poller没有立即分配线程来读取电子邮件,因此导致读取延迟。
另外请注意,这个应用程序是在tomcat下运行的,其他10+个java应用程序也是在同一个tomcat下运行的。
有人能指出这4-5个小时延误背后的一些可能的原因吗?
spring集成.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>

CustomSearchTerm策略:

@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;
    }
}
41zrol4v

41zrol4v1#

目前,你显示了3个民调将在同一时间运行。默认情况下,所有这些轮询器都由 TaskScheduler (不要把它和 TaskExecutor ),它基于10个线程池。所以,即使是现在,我看到3个并发线程采取了您的电子邮件通道适配器。在应用程序中有其他轮询器可能并不奇怪。所有的人都有相同的想法 TaskScheduler .
你可以修改你所有的投票人,把真正的工作转移到特定的执行者身上,或者你可以考虑增加投票人数 TaskScheduler 线程池:https://docs.spring.io/spring-integration/docs/current/reference/html/configuration.html#namespace-任务调度器
您还可以执行线程转储,以分析哪些线程正忙以及忙什么。

相关问题