2010-09-14 8 views
5

के आधार पर एक विशिष्ट समय पर दैनिक कार्रवाई करें मेरे जावा एप्लिकेशन को प्रति दिन एक बार सभी उपयोगकर्ताओं को ईमेल भेजने की आवश्यकता है। मैं इसे प्रत्येक उपयोगकर्ता के स्थानीय समय के आधार पर लगभग 2AM पर वितरित करना चाहता हूं। तो न्यूयॉर्क में एक उपयोगकर्ता को 2AM अमेरिका/न्यू_यॉर्क समय पर संदेश मिलेगा। लॉस एंजिल्स में एक उपयोगकर्ता को 2AM अमेरिका/लॉस_एंजेलस समय पर संदेश मिलेगा। मेरी मेलिंग प्रक्रिया दिन के प्रत्येक घंटे में एक बार चलती है।उपयोगकर्ता के स्थानीय समय क्षेत्र

मैं साइन-अप के दौरान प्रत्येक उपयोगकर्ता के समय क्षेत्र को स्वचालित रूप से निर्धारित करने के लिए HTML5 भू-स्थान सुविधाओं या आईपी पते भू-पता लगाने का उपयोग करने की योजना बना रहा हूं। बेशक, उपयोगकर्ता मानदंड मैन्युअल रूप से संशोधित कर सकते हैं यदि ये मान गलत हैं। मैं टाइम ऑब्जेक्ट स्ट्रिंग, जैसे कि "अमेरिका/न्यू_यॉर्क" के रूप में उपयोगकर्ता ऑब्जेक्ट में चयनित टाइमज़ोन को स्टोर करना चाहता हूं। यह एक स्ट्रिंग के रूप में डेटाबेस के लिए जारी रहेगा, लेकिन यदि आवश्यक हो तो यह बदला जा सकता है।

विचारणीय बातें:

  • मैं, डेलाइट सेविंग टाइम के लिए खाते में करने की जरूरत है ताकि उपयोगकर्ता हमेशा 2:00 के आसपास ईमेल प्राप्त करता है। इसका मतलब है कि मैं उपयोगकर्ता ऑब्जेक्ट में जीएमटी -8 या इसी तरह के यूटीसी ऑफ़सेट स्टोर नहीं कर सकता। लॉस एंजिल्स का हिस्सा जीएमटी -7 में है, और अन्य हिस्सों में यह जीएमटी -8 में है।
  • Another SO question में ऐसे जवाब हैं जो ऑफ़सेट जानकारी संग्रहीत करने का सुझाव देते हैं, लेकिन मुझे नहीं लगता कि यह कैसे काम करेगा, क्योंकि विभिन्न स्थानों में समय पूरे वर्ष बदल सकता है। जब भी दुनिया में कहीं भी टाइमज़ोन परिवर्तन घटना होती है तो मैं अपने सभी उपयोगकर्ता ऑब्जेक्ट टाइमज़ोन को अपडेट नहीं कर रहा हूं।
  • मैं अपने आवेदन में जोडाटाइम का उपयोग कर रहा हूं, इसलिए यदि इससे मदद मिलेगी तो मैं इसका लाभ उठा सकता हूं।
  • मैं डेटाबेस क्वेरीज के लिए हाइबरनेट का उपयोग कर रहा हूं और जावा में सैकड़ों हजारों उपयोगकर्ता रिकॉर्ड को संसाधित करने की आवश्यकता के बिना एक हाइबरनेट क्वेरी में संभाला जा सकता है जो समाधान ढूंढना चाहता हूं।

मैं वसंत शेड्यूलिंग क्रॉन सुविधाओं (क्वार्ट्ज के माध्यम से) का उपयोग कर रहा हूं ताकि दिन के हर घंटे घंटे में 2 मिनट की दूरी पर एक विधि चल सके। अभी मेरे अधिकांश उपयोगकर्ता अमेरिका/लॉस_एंजेलस में हैं, इसलिए मैं मैन्युअल रूप से सभी मेल को 2:02 पूर्वाह्न प्रशांत समय पर भेजने के लिए मजबूर कर रहा हूं। निम्नलिखित विधि हर घंटे चलती है: 02 घंटे प्रति घंटे, लेकिन यह मैन्युअल रूप से समय की जांच करता है और केवल लॉस एंजिल्स में वर्तमान समय 2:00 घंटे में होता है। इसका मतलब है कि अन्य स्थानों के उपयोगकर्ताओं को 2AM से अलग समय पर ईमेल प्राप्त होगा।

@Scheduled(cron="0 2 * * * *") 
public void sendDailyReportEmail() { 
    DateTime now = new DateTime(DateTimeZone.forID("America/Los_Angeles")); 
    if (now.getHourOfDay() != 2) { 
     log.info("Not 2AM pacific, so skipping email reports"); 
     return; 
    } 
    // send email reports 
} 

तो, मैं क्या जरूरत है एक डेटाबेस क्वेरी मुझे 2:00 पूर्वाह्न घंटे में एक स्थानीय समय है कि सभी उपयोगकर्ताओं को अपने उपयोगकर्ता वस्तु में समय क्षेत्र के आधार दे देंगे कि प्रदर्शन करने के लिए है। इसे पूरा करने के तरीके पर कोई विचार?

उत्तर

2

मैंने यह और विचार दिया है और एक संभावित समाधान है। मैंने अभी तक इसे लागू नहीं किया है, लेकिन मुझे लगता है कि इसे काम करना चाहिए। असल में, यह निम्न क्वेरी प्रदर्शन करना शामिल है (नोट: इस MySQL विशिष्ट है):

    :

    select * from members where hour(convert_tz(now(),'UTC',timezone)) = 3; 
    

    इस क्वेरी निम्न कार्य करके सभी सदस्यों 3:00 और 3:59 बजे के बीच एक वर्तमान स्थानीय समय है का चयन करता है

  1. यह now() का उपयोग कर वर्तमान सर्वर समय प्राप्त करता है, जो कि यूटीसी समय के लिए डेटाबेस सर्वर कॉन्फ़िगर किया गया है, जो यूटीसी में एक समय है।
  2. तब यह उस समय को convert_tz() फ़ंक्शन के साथ सदस्य तालिका के timezone कॉलम में निर्दिष्ट सदस्य के टाइमज़ोन में परिवर्तित करता है। ध्यान दें कि सदस्य वर्ग में "अमेरिका/लॉस_एंजेलस" प्रारूप में टाइमज़ोन फ़ील्ड शामिल है।
  3. अगला, यह hour() फ़ंक्शन के साथ यह देखने के लिए कितना घंटा है कि यह है, 3AM के लिए।
  4. क्वेरी फिर उन सभी सदस्यों को लौटाती है जो इन आवश्यकताओं को पूरा करते हैं और उनमें से प्रत्येक को ईमेल भेजते हैं।

मैं इस टाइमज़ोन रूपांतरण और हर घंटे सिस्टम में प्रत्येक सदस्य के लिए गणना करने के बारे में थोड़ा चिंतित हूं। मुझे यह देखने के लिए चीजों का परीक्षण करना होगा कि यह डेटाबेस पर किस तरह का भार डालता है, लेकिन शायद यह लाखों या यहां तक ​​कि 10k उपयोगकर्ताओं के साथ भी चकित होगा।

एक वैकल्पिक कि काफी बोझ हल्का करना चाहिए, लेकिन के रूप में काफी सुंदर नहीं है निम्न करने के लिए है (ध्यान दें कि यह कोड untested है!):

    :

    @Scheduled(cron="0 2 * * * *") 
    public void sendDailyReportEmail() { 
    
        Query query = session.createQuery(
         "select distinct m.timezone from Member m"); 
        List<String> timezones = query.list(); 
    
        for (String timezone : timezones) { 
         DateTime now = new DateTime(DateTimeZone.forID(timezone)); 
         if (now.getHourOfDay() == 3) { 
          Query query2 = session.createQuery(
           "from Member where timezone = :zone"); 
          query2.setParameter("zone", timezone); 
          List<Member> members = query2.list(); 
          // send email reports 
         } 
        } 
    } 
    

    इस कोड को ऐसा करता है

  1. घंटे के 2 मिनट में विधि का निष्पादन करें, प्रत्येक दिन के हर घंटे
  2. सदस्य तालिका में सभी अद्वितीय टाइमज़ोन की सूची के लिए डेटाबेस क्वेरी करें।
  3. प्रत्येक टाइमज़ोन के लिए, यह निर्धारित करें कि यह वर्तमान में 3AM घंटे में है या नहीं।
  4. यदि टाइममोन 3AM घंटे में है, तो उस टाइमज़ोन के सभी सदस्यों का चयन करें और उन्हें ईमेल भेजें।

यह प्रत्येक घंटे की शुरुआत में थोड़ा अतिरिक्त ओवरहेड जोड़ता है, लेकिन प्रति उपयोगकर्ता टाइमज़ोन प्रोसेसिंग की आवश्यकता नहीं होती है। संभावना है कि सिस्टम द्वारा वास्तव में उपयोग किए जाने वाले कुछ दर्जन अद्वितीय समय क्षेत्र होंगे। यह बहुत ही असंभव है कि मेरे पास सभी 500+ टाइमज़ोन में सदस्य होंगे।

एक आखिरी बात। 2AM घंटे के दौरान ईमेल भेजने के बजाय, मैंने इसे 3AM पर ले जाया। ऐसा इसलिए है क्योंकि जब वसंत ऋतु में डेलाइट बचत समय बदलता है, तो समय 2AM से 3AM तक बदल जाता है। तो 2:02 पूर्वाह्न जैसी कोई चीज़ नहीं है, जिसका अर्थ है कि उस दिन ईमेल नहीं भेजे जाएंगे। इसके अलावा, गिरावट में, सिस्टम प्रति उपयोगकर्ता 2 ईमेल भेज सकता है क्योंकि एक घंटा खुद को दोहराता है। मुझे यह पता लगाने की ज़रूरत है कि गैर-यूएसए टाइमज़ोन अलग-अलग समय में समय बदलते हैं, क्योंकि 3AM घंटे कहीं और समस्या हो सकती है।