2015-05-13 13 views
11

मैं स्प्रिंग के कार्य ढांचे का उपयोग पूरी तरह से कोड कॉन्फ़िगरेशन में करने के लिए XML कॉन्फ़िगरेशन को परिवर्तित करने का प्रयास कर रहा हूं। मैं कार्यक्षमता को पुन: पेश करने में सक्षम हूं लेकिन जब भी मैं टॉमकैट सर्वर पर युद्ध बंद करता हूं तो कार्य शेड्यूलर रहता है, यह लटकता है (यह एक्सएमएल कॉन्फ़िगरेशन के साथ लटका नहीं है)। मैंने शेड्यूलर और निष्पादक के उदाहरणों का निरीक्षण करने के लिए डीबग किया है लेकिन मुझे कोई फर्क नहीं दिख रहा है इसलिए मुझे यकीन नहीं है कि इसे लटकाए जाने के कारण क्या हो सकता है।कोड कॉन्फ़िगरेशन में स्प्रिंग कार्य XML कॉन्फ़िगरेशन को परिवर्तित करना

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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.1.xsd 
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd"> 

    <task:executor id="com.work.gwx.pix.executor" 
     pool-size="${pix.job.executor.pool.size:1-40}" 
     queue-capacity="${pix.job.executor.queue.capacity:0}" 
     rejection-policy="CALLER_RUNS"/> 

    <task:scheduler id="com.work.gwx.pix.scheduler" pool-size="${pix.job.scheduler.pool.size:4}" /> 

    <task:annotation-driven executor="com.work.gwx.pix.executor" scheduler="com.work.gwx.pix.scheduler" /> 

    <bean id='queueProcessor' class="com.work.gwx.queueing.QueueProcessor" /> 

</beans> 

यहाँ कोड विन्यास है:

यहाँ एक्सएमएल विन्यास कि काम करता है

@EnableAsync 
@EnableScheduling 
@Configuration 
public class TaskConfiguration implements AsyncConfigurer, SchedulingConfigurer { 

    @Value("${pix.job.executor.max.pool.size:1}") 
    private int executorMaxPoolSize; 

    @Value("${pix.job.executor.queue.capacity:0}") 
    private int executorQueueCapacity; 

    @Value("${pix.job.scheduler.pool.size:4}") 
    private int schedulerPoolSize; 

    @Bean(destroyMethod = "shutdown") 
    public Executor pixTaskScheduler() { 
     final ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(schedulerPoolSize, new ThreadPoolTaskExecutor()); 
     // ex.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); 
     return ex; 
    } 

    @Bean 
    public Executor pixExecutor() { 
     final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
     executor.setCorePoolSize(executorMaxPoolSize); 
     executor.setQueueCapacity(executorQueueCapacity); 
     executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 
     executor.setThreadFactory(new ThreadPoolTaskExecutor()); 
     executor.initialize(); 
     return executor; 
    } 

    @Override 
    public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) { 
     taskRegistrar.setScheduler(pixTaskScheduler()); 

    } 

    @Override 
    public Executor getAsyncExecutor() { 
     return pixExecutor(); 
    } 

    @Override 
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 
     return new SimpleAsyncUncaughtExceptionHandler(); 
    } 
} 

जब मैं कोड विन्यास में setExecuteExistingDelayedTasksAfterShutdownPolicy(false) का उपयोग इसे बंद है, लेकिन मुझे लगता है कि हो सकता है चिंतित हूँ प्रतिकूल प्रभाव पड़ता है क्योंकि एक्सएमएल कॉन्फ़िगरेशन के माध्यम से किए जाने पर यह सत्य पर सेट होता है। साथ ही, मुझे ध्यान रखना चाहिए, क्यूईप्रोसेसर क्लास वह काम कर रहा है जो मुझे चाहिए और मुझे कोई फर्क नहीं पड़ता कि देरी से निष्पादन रद्द हो गया है - मैं बस वर्तमान में धागे को निरस्त रूप से रद्द नहीं करना चाहता हूं।

यह संदेश मुझे मिलता है जब यह लटकी हुई है:

गंभीर: वेब एप्लिकेशन [/ pix-कतार प्रोसेसर] [ThreadPoolTaskExecutor -1] नाम का एक धागा शुरू कर दिया है करने के लिए प्रकट होता है, लेकिन में नाकाम रही है इसे रोकें। इस बात की संभावना है कि इससे स्मृति रिसाव पैदा होगा।

फांसी के कारण क्या हो सकता है पर कोई विचार? या, उस टिप्पणी की विधि का उपयोग करने से मैं जो चाहता हूं वह कर सकता हूं (एक चल रहे कार्य को मार नहीं देगा लेकिन देरी वाले कार्यों को रद्द कर देगा)?

+0

समस्याओं मैं देख रहा हूँ में से एक है कि आप 'थ्रेडपूल टास्क एक्सक्लूसर' को 'थ्रेडफैक्टरी' के रूप में सेट कर रहे हैं? क्यों? अब आपके पास मूल रूप से 2 कार्य निष्पादक हैं जहां एक नियंत्रित है और दूसरा वास्तव में नहीं है। –

+0

एक और चीज यह है कि आप अपने 'टास्क एक्स्प्लेक्टर' को क्यों नहीं तारित कर रहे हैं 'टास्कशेड्यूलर'? वह प्रयोग कर रहा है, फिर भी एक और अप्रबंधित 'टास्क एक्स्सेलर'। –

उत्तर

4

आपकी जावा आधारित कॉन्फ़िगरेशन वास्तव में XML कॉन्फ़िगरेशन का प्रतिनिधित्व नहीं है। कम से कम 2 चीजें हैं जो अलग हैं।

  1. आपका TaskExecutor एक और TaskExecutor इस XML में ऐसा नहीं है और यह भी एक और TaskExecutor शुरू होता है एक ThreadFactory के रूप में वायर्ड है।
  2. आपका TaskScheduler एक नया TaskExecutor का उपयोग करता है जबकि xml कॉन्फ़िगरेशन कॉन्फ़िगर किए गए एक का उपयोग करता है।

जिनमें आप कार्य शटडाउन होने पर समाप्त हो गया आप true तो किसी भी लंबित कार्य पूरा हो जाएगा करने के लिए TaskExecutor पर waitForTasksToCompleteOnShutdown संपत्ति सेट कर सकते हैं और कोई नया कार्य को स्वीकार किया जाएगा है।

इसके अलावा initialize करने के लिए कॉल afterPropertiesSet पद्धति के रूप में की जरूरत नहीं किया जाना चाहिए स्प्रिंग है जो बदले में कॉल initialize द्वारा बुलाया जाएगा।

निम्नलिखित 2 सेम परिभाषाओं एक्सएमएल विन्यास के साथ लाइन में और अधिक कर रहे हैं (और अब आप 3 के बजाय एक ही TaskExecutor है और यह पहले बंद से पहले कार्य खत्म हो जाएगा।

@Bean(destroyMethod = "shutdown") 
public Executor pixTaskScheduler() { 
    final ScheduledThreadPoolExecutor ex = new ScheduledThreadPoolExecutor(schedulerPoolSize, pixExecutor()); 
    // ex.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); 
    return ex; 
} 

@Bean 
public Executor pixExecutor() { 
    final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
    executor.setCorePoolSize(executorMaxPoolSize); 
    executor.setQueueCapacity(executorQueueCapacity); 
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 
    executor.setWaitForTasksToCompleteOnShutdown(true); 
    return executor; 
} 
+0

क्षमा करें मैंने अभी तक इसका जवाब नहीं दिया है क्योंकि मैं शहर से बाहर था। आशाजनक लग रहा है और जल्द ही इसका परीक्षण करने में सक्षम होना चाहिए। यह समझ में आता है कि आप क्या कह रहे हैं। – AHungerArtist

+0

यह काम करता प्रतीत होता है लेकिन एक और सवाल: एक्सएमएल में, मैं निष्पादक और शेड्यूलर दोनों को नाम/आईडी देने में सक्षम हूं। मैं कोड के माध्यम से ऐसा कैसे कर सकता हूं? लगता है कि ThreadPoolTaskExecutor में एक विधि है लेकिन अनुसूचित नहीं है। यह वास्तव में यह पहचानने में मदद करेगा कि डीबगिंग के दौरान से कौन से धागे आ रहे हैं। – AHungerArtist

+0

नहीं, ऐसा नहीं होगा क्योंकि केवल एक ही धागा पूल है। 'ThreadPoolTaskExecutor' के लिए आप उपसर्ग जोड़ने के लिए' threadNamePrefix' का उपयोग कर सकते हैं। लेकिन शेड्यूलर केवल एक शेड्यूलर है जो कार्यों को लॉन्च करने के लिए एकल 'थ्रेडपूल टास्क एक्स्सेलर' का उपयोग करता है। यदि आप नहीं चाहते हैं कि आपको एक और कार्य निष्पादक जोड़ने की आवश्यकता है, लेकिन यह आपके xml कॉन्फ़िगरेशन में आपके पास नहीं है (या था)। –

संबंधित मुद्दे