सवाल सर्वलेट आधारित वेब एप्लिकेशन में पृष्ठभूमि कार्य कैसे चलाएं?


मैं जावा का उपयोग कर रहा हूं और मैं अपने आवेदन में एक सर्वलेट लगातार चलाना चाहता हूं, लेकिन मुझे यह नहीं मिल रहा है कि इसे कैसे किया जाए। मेरे सर्वलेट में एक विधि है जो उपयोगकर्ता के दैनिक आधार पर डेटाबेस के साथ-साथ पूरे डेटाबेस से उपयोगकर्ताओं की कुल गणना देता है। तो मैं उस के लिए लगातार चलने वाली सर्वलेट रखना चाहता हूं।


76
2018-01-14 12:39


मूल


आपका क्या मतलब है, "लगातार चल रहा है"? - skaffman
लगातार चलकर आपका क्या मतलब है? यह तब तक चलता रहेगा जब तक आपका ऐप सर्वर चलता है - fmucar
मुझे समझ में नहीं आता है कि इसे लगातार क्यों चलाना है ... अगर कोई 'उपयोगकर्ता गिनती' चाहता है तो वे आपकी सर्वलेट विधि को कॉल करते हैं और आप उन्हें देते हैं? - trojanfoe
@trojanfoe दरअसल मैं उपयोगकर्ता आधार पर दैनिक आधार चाहता हूं, इसलिए इसके लिए मुझे मैन्युअल रूप से सर्वलेट चलाने की ज़रूरत होगी, इसलिए ऐसा करने के बजाय मैं सर्वलेट को नियमित रूप से चलाने के लिए चाहता हूं। इसलिए मुझे हर रोज सर्वलेट चलाने की आवश्यकता नहीं है। - pritsag
@pritsag Servlets इस समस्या को हल करने का तरीका नहीं हैं - यदि आप पूरे दिन एकत्रित 'आंकड़े' चाहते हैं तो कुछ अन्य तकनीक का उपयोग करें। - trojanfoe


जवाब:


आपकी समस्या यह है कि आप के उद्देश्य को गलत समझते हैं सर्वलेट। HTTP अनुरोधों पर कार्य करने का इरादा है, और कुछ भी नहीं। आप केवल एक पृष्ठभूमि कार्य चाहते हैं जो दैनिक आधार पर एक बार चलता है।

ईजेबी उपलब्ध है? उपयोग @Schedule

यदि आपका पर्यावरण ईजेबी का समर्थन करता है (उदाहरण के लिए वाइल्डफली, जेबॉस एएस / ईएपी, टॉमईई, ग्लासफ़िश, आदि), तो उपयोग करें @Schedule बजाय।

@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // Do your job here which should run every start of day.
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // Do your job here which should run every hour of day.
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // Do your job here which should run every 15 minute of hour.
    }

} 

हाँ, यह वास्तव में सब कुछ है। कंटेनर स्वचालित रूप से पिकअप और इसे प्रबंधित करेगा।

ईजेबी अनुपलब्ध है? उपयोग ScheduledExecutorService

यदि आपका पर्यावरण ईजेबी का समर्थन नहीं करता है (यानी असली जावा ईई सर्वर नहीं है, उदाहरण के लिए टोमकैट, जेट्टी, आदि), उपयोग करें ScheduledExecutorService। इसे एक द्वारा शुरू किया जा सकता है ServletContextListener। यहां एक किकऑफ उदाहरण है:

@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}

जहां नौकरी कक्षाएं इस तरह दिखती हैं:

public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

}
public class SomeQuarterlyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}

कभी भी उपयोग करने के बारे में मत सोचो java.util.Timer/java.lang.Thread जावा ईई में

सीधे उपयोग न करें java.util.Timer और / या java.lang.Thread जावा ईई में। यह मुसीबत के लिए नुस्खा है। एक ही प्रश्न पर इस जेएसएफ से संबंधित उत्तर में एक विस्तृत स्पष्टीकरण पाया जा सकता है: टाइमर का उपयोग करके शेड्यूल किए गए कार्यों के लिए जेएसएफ प्रबंधित बीन में स्प्रेडिंग थ्रेड


173
2018-01-14 13:45



@ बाल्कस धन्यवाद श्रीमान, आपके समाधान ने मेरी मदद की और मैंने शेड्यूल्डएक्ससेलर सेवा के बारे में सीखा जो मेरे लिए नया था क्योंकि मैं जावा के लिए नया हूँ। एक बार फिर धन्यवाद। - pritsag
शानदार स्पष्टीकरण और कोड। - London guy
@Ashwin web.xml एक है तैनाती वर्णनकर्ता। कक्षा UpdateCount तैनाती से संबंधित नहीं है, इसलिए इसे अंदर नहीं रखना है web.xml - informatik01
ए के साथ एक महत्वपूर्ण मुद्दा ScheduledExecutorService: के लिए सुनिश्चित हो कब्जा सब अपवाद आपके निष्पादक में। यदि कोई अपवाद आपके से निकलता है run विधि, निष्पादक चुपचाप निष्पादन बंद कर देता है। यह एक सुविधा नहीं है एक बग। डॉक्टर को पढ़ें और कुछ googling के साथ अध्ययन करें। - Basil Bourque
@ एजीआई: अगर ऐसा होगा scheduler.shutdownNow() उदाहरण के अनुसार सही ढंग से लागू नहीं किया गया है। यदि इसे लागू नहीं किया जाता है, तो शेड्यूल थ्रेड वास्तव में चल रहा है। - BalusC


मैं नियमित अंतराल पर कार्य चलाने के लिए क्वार्ट्ज जैसी लाइब्रेरी का उपयोग करने का सुझाव दूंगा। सर्वलेट वास्तव में क्या करता है? यह आपको एक रिपोर्ट भेजता है?


3
2018-01-14 13:08



हां, यह मुझे प्रति दिन बनाए गए उपयोगकर्ता की गिनती देता है और मेरे डेटाबेस में कुल उपयोगकर्ताओं की गिनती भी देता है। - pritsag
किस रूप में? मेल? - Twister
huuu? क्या आप अपने सिस्टम के पूर्ण वास्तुकला का वर्णन कर सकते हैं। मैं हार गया हूं। - Twister
@ ट्वीस्टर मैं जावा के लिए नया और सीखने के चरण सर में हूं और वास्तव में servlets के बारे में बहुत कुछ नहीं जानता। - pritsag
समस्या सर्वलेट के बारे में नहीं है। आप किस एप्लिकेशन के बारे में बात कर रहे हैं? (पीएस: आपकी टिप्पणियों को हटाना एक बुरा विचार है, विशेष रूप से टिप्पणियों का मैंने जवाब दिया) - Twister


आप cron4j का उपयोग कर सकते हैं। http://www.sauronsoftware.it/projects/cron4j/manual.php


1
2017-12-22 08:13





दो वर्गों को लागू करें और कॉल करें startTask() में main

public void startTask()
{
    // Create a Runnable
    Runnable task = new Runnable() {
        public void run() {
            while (true) {
                runTask();
            }
        }
    };

    // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
}

public void runTask()
{
    try {
        // do something...         
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

1
2018-03-05 17:49



यह निश्चित रूप से वेब एप्लिकेशन में ऐसा करने का तरीका नहीं है - इसके बजाय @ बालुससी द्वारा दिए गए उत्तर को देखें - वह यहां सही है और मैं कहूंगा कि आप उसके सभी उत्तरों पर भरोसा कर सकते हैं। - Yoshiya


एक उत्पादन प्रणाली में जिसमें कई गैर-जी कंटेनर चल सकते हैं। क्वार्ट्ज शेड्यूलर जैसे एनोट एंटरप्राइज़ शेड्यूलर का उपयोग करें जिसे टास्क मैमगेमेट के लिए डेटाबेस का उपयोग करने के लिए कॉन्फ़िगर किया जा सकता है।


0
2018-02-21 15:31