วิธีที่ดีที่สุดในการทำงานตามกำหนดเวลา [ปิด]


229

วันนี้เราได้สร้างแอปพลิเคชั่นคอนโซลสำหรับเรียกใช้งานตามกำหนดเวลาสำหรับเว็บไซต์ ASP.NET ของเรา แต่ฉันคิดว่าวิธีนี้เป็นข้อผิดพลาดเล็กน้อยและยากที่จะรักษา คุณทำงานตามกำหนดเวลาของคุณได้อย่างไร (ในสภาพแวดล้อม windows / IIS / ASP.NET)

ปรับปรุง:

ตัวอย่างของงาน:

  • การส่งอีเมลจากคิวอีเมลในฐานข้อมูล
  • การลบวัตถุที่ล้าสมัยออกจากฐานข้อมูล
  • การดึงข้อมูลสถิติจาก Google AdWords และกรอกข้อมูลลงในฐานข้อมูล

ตัวอย่างของงานที่คุณกำลังทำอยู่คืออะไร?
JeffO

4
คุณต้องตรวจสอบatrigger.com
Kousha

หากคุณมี Plesk คุณสามารถเขียน vbs และโฆษณาไปที่ Task Scheduler: net24.co.nz/kb/article/AA-00213/13/Shared-Hosting/ASP-ASP.NET/…
HasanG

คำตอบ:


74

งานทั้งหมดของฉัน (ซึ่งจะต้องมีการกำหนด) สำหรับเว็บไซต์จะถูกเก็บไว้ในเว็บไซต์และเรียกจากหน้าพิเศษ จากนั้นฉันก็เขียนบริการ Windows ที่เรียบง่ายซึ่งเรียกหน้านี้บ่อย ๆ เมื่อเพจรันมันจะส่งคืนค่า หากฉันรู้ว่ามีงานที่ต้องทำมากกว่านี้ฉันรันหน้าอีกครั้งทันทีมิฉะนั้นฉันจะเรียกใช้ในเวลาไม่นาน สิ่งนี้ได้ผลดีมากสำหรับฉันและเก็บงานตรรกะทั้งหมดของฉันไว้กับรหัสเว็บ ก่อนที่จะเขียนบริการ Windows อย่างง่ายฉันใช้ตัวกำหนดตารางเวลาของ Windows เพื่อเรียกหน้าทุก ๆ x นาที

อีกวิธีที่สะดวกในการทำงานนี้คือการใช้บริการตรวจสอบเช่นPingdom ชี้การตรวจสอบ http ไปยังหน้าเว็บที่เรียกใช้รหัสบริการของคุณ มีผลการคืนหน้าซึ่งสามารถใช้เรียก Pingdom เพื่อส่งข้อความแจ้งเตือนเมื่อมีบางอย่างไม่ถูกต้อง


3
นี่คือทางออกที่ฉันได้ลงเอยด้วย แทนที่จะใช้บริการเว็บแบบกำหนดเองฉันใช้ windows scheduler + curl ประโยชน์ของการใช้บริการ windows คืออะไร
Niels Bosma

16
คุณดูที่เทคนิคการหมดอายุของรายการแคชหรือไม่ ฉันคิดว่าคุณจะพบว่ามันเป็นการนำเหมาะมากขึ้นในการให้บริการที่กำหนด: codeproject.com/KB/aspnet/ASPNETService.aspx
ริชาร์ดเคลย์ตัน

10
สิ่งที่จะหยุดผู้ใช้ที่เป็นอันตราย (หรือแมงมุมเครื่องมือค้นหา) เรียกหน้านี้และทำให้งานตามกำหนดของคุณทำงาน
UpTheCreek

8
คุณสามารถหยุดการโทรที่เป็นอันตรายได้โดยจัดเก็บการประทับเวลาแบบคงที่ในเว็บแอปและทำงานต่อเมื่อไม่ได้ตั้งค่าการประทับเวลา (การโทรครั้งแรก) หรือเวลาที่ถูกต้องหมดอายุตั้งแต่การโทรครั้งล่าสุด
Rob Kent

5
ฉันหยุดการโทรที่เป็นอันตรายไปยัง url ของฉันโดยตรวจสอบว่าที่อยู่ IP เป็นที่อยู่ภายในหรือไม่ มันไม่ส่งคืนสิ่งใดเลยและไม่ทำอะไรเลยหากไม่ได้อยู่ภายในองค์กรของเรา
user1408767

128

เทคนิคนี้โดย Jeff Atwood สำหรับ Stackoverflowเป็นวิธีที่ง่ายที่สุดที่ฉันเคยเจอ มันขึ้นอยู่กับกลไกการเรียกกลับ "ลบรายการแคช" ที่สร้างในระบบแคชของ ASP.NET

อัปเดต: Stackoverflow เกินวิธีนี้ ใช้งานได้เฉพาะในขณะที่เว็บไซต์กำลังทำงาน แต่เป็นเทคนิคง่าย ๆ ที่มีประโยชน์สำหรับคนจำนวนมาก

นอกจากนี้ตรวจสอบQuartz.NET


12
ดังนั้นจะเกิดอะไรขึ้นหากแอปพลิเคชันไม่ทำงาน แต่งานที่กำหนดไว้จะต้องเกิดขึ้น
MichaelGG

2
สิ่งนี้อาจทำให้ประสบการณ์ผู้ใช้ช้าลงหากงานใช้เวลาสักครู่ในการรันในเวลานี้ ฉันไม่ต้องการให้ผู้ใช้ทำการบำรุงรักษา / งานให้ฉัน
Brettski

5
มันน่ากลัวเหมือนนรก! สิ่งใดที่อาจทำให้แอปพลิเคชันหยุดทำงานและอาจเป็นเพียงการรีสตาร์ทตามคำขอของผู้ใช้ครั้งต่อไปเท่านั้น ในช่วงเวลาเหล่านั้นงานของคุณจะไม่ทำงาน!
teedyay

43
บางสิ่งที่ฉันสังเกตเห็นในวันนี้ในความคิดเห็นที่โพสต์บล็อกเดิม: No, we’ve switched to a dedicated task. We definitely outgrew this technique. I do think it’s fine for small sites though!- Jeff Atwood
Joel Coehoorn

3
-1 มีข้อบกพร่องขนาดใหญ่ด้วยวิธีนี้ เมื่อใดก็ตามที่แอปพลิเคชันถูกนำกลับมาใช้ใหม่เหตุการณ์ 'CacheItemRemoved' จะเริ่มทำงาน ในสถานที่ผลิตอาจเกิดขึ้นได้สองสามครั้งต่อวัน ไม่ค่อยดีนักถ้าคุณต้องการให้งานรันทุกสัปดาห์
Steven de Salas

30

สร้างที่กำหนดเองบริการของ Windows

ฉันมีภารกิจที่สำคัญในการตั้งค่าเป็นแอปคอนโซลตามกำหนดเวลาและพบว่างานเหล่านั้นยากต่อการบำรุงรักษา ฉันสร้างบริการ Windows ด้วย 'heartbeat' ที่จะตรวจสอบตารางเวลาในฐานข้อมูลของฉันทุกสองสามนาที มันทำงานได้ดีจริงๆ

ต้องบอกว่าฉันยังคงใช้แอพคอนโซลตามกำหนดการสำหรับงานบำรุงรักษาที่ไม่สำคัญของฉันส่วนใหญ่ หากยังไม่พังอย่าแก้ไข


7
FYI ลิงค์นี้ตายแล้ว
Charles Burns

1
@CharlesBurns คุณสามารถเรียกดูลิงก์ที่ตายแล้วได้ด้วย archive.org: web.archive.org/web/20090919131944/http://www.dotheweb.net/…
Nikolay Kostov

17

ฉันพบว่ามันง่ายสำหรับทุกคนที่เกี่ยวข้อง:

  • สร้างวิธีการบริการเว็บเช่น DoSuchAndSuchProcess
  • สร้างแอปคอนโซลที่เรียกใช้เว็บเมธอดนี้
  • กำหนดเวลาแอปคอนโซลในตัวกำหนดเวลางาน

การใช้วิธีการนี้มีตรรกะทางธุรกิจทั้งหมดอยู่ในเว็บแอพของคุณ แต่คุณมีความน่าเชื่อถือของตัวจัดการงาน windows หรือตัวจัดการงานเชิงพาณิชย์อื่น ๆ ที่จะเตะมันออกมาและบันทึกข้อมูลการส่งคืนเช่นรายงานการดำเนินการ การใช้บริการเว็บแทนการโพสต์ไปยังหน้าเว็บมีข้อได้เปรียบเล็กน้อยเนื่องจากการรับข้อมูลส่งคืนจากเว็บเซอร์นั้นง่ายกว่า


10

ทำไมต้องบูรณาการล้อให้ใช้คลาส Threading และ Timer

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }

7
คุณไม่จำเป็นต้องวางไข่เพื่อเริ่มจับเวลา ...
Zyo

4
ฉันก็ไม่คิดว่ามันเป็นทางออกที่ดี
Idan Shechter

12
@IdanShechter มันจะดีที่จะบอกเหตุผลว่าทำไมคุณพิจารณานี้ไม่ได้เป็นทางออกที่ดี
Omu

2
เธรดอาจเป็นปัญหาได้เนื่องจากไม่ใช่ HttpRequest ข้อมูลบางอย่างที่เกี่ยวข้องกับ HttpRequest อาจเป็นโมฆะ ตัวอย่างเช่น HttpRequest .ApplicationPath หากงานถูกเขียนอย่างถูกต้องมันจะทำงาน ปัญหาอีกประการคือการเริ่มพูลโปรแกรมใหม่ หากพูลเริ่มการทำงานใหม่บ่อยเกินไป (หน่วยความจำรั่ว ... ) ผู้ปฏิบัติงานจะไม่ทำงาน
Tomas Kubes

2
ในกรณีที่คุณมีอินสแตนซ์หลายตัวกำลังทำงานอยู่ (เช่นโหลดบาลานซ์) - บางทีคุณอาจไม่ต้องการโซลูชันนี้ (มีหลายงานที่ทำแบบเดียวกัน)
Illidan

8

ใช้ Windows Scheduler เพื่อเรียกใช้เว็บเพจ

เพื่อป้องกันผู้ใช้ที่เป็นอันตรายหรือสไปเดอร์เอ็นจินการค้นหาให้เรียกใช้เมื่อคุณตั้งค่าภารกิจที่กำหนดไว้เพียงโทรไปที่หน้าเว็บด้วยการสอบถาม: mypage.aspx? from = schedtask

จากนั้นในการโหลดหน้าเว็บให้ใช้เงื่อนไข: if (Request.Querystring ["จาก"] == "schedtask") {// executetask}

วิธีนี้ไม่มีแมงมุมเครื่องมือค้นหาหรือผู้ใช้ที่เป็นอันตรายจะสามารถดำเนินการตามกำหนดเวลาของคุณได้


5
ยังดีกว่าใช้อัลกอริทึมคร่ำเครียดคร่ำเครียดที่จริงการตรวจสอบการสืบค้นด้วยความปลอดภัยน้อยกว่าวลีมายากล ความต้องการจะเป็นเช่น mypage.aspx? salt = foo & hash = 1223523jbhdgu13t1 คุณเพียงแค่ต้องมีอัลกอริทึมการแฮชเดียวกันบนทั้งเซิร์ฟเวอร์และไคลเอนต์ เพิ่มขีด จำกัด ฮาร์ดบนเซิร์ฟเวอร์ บันทึกเมื่อมีการดำเนินการและป้องกันไม่ให้ดำเนินการเร็วเกินไป ฉันอาจจะหวาดระแวงแม้ว่า
Nenotlep

14
ยิ่งปลอดภัยยิ่งขึ้นให้ใช้ Windows Scheduler เพื่อเรียกใช้เว็บเพจที่ตรวจสอบว่าคำขอมาจากเซิร์ฟเวอร์หรือไม่: Request.IsLocal>> เฉพาะเซิร์ฟเวอร์เท่านั้นที่สามารถเรียกใช้งานที่กำหนดเวลาไว้ได้
กบฏ

คุณมีประสบการณ์มากขึ้นจากวิธีการของคุณ? ฉันจะพัฒนาบริการประเภทเดียวกันของแอพของเราและตอนนี้ฉันไม่สามารถตัดสินใจได้ว่าจะเรียกเพจที่มีภารกิจหรือ cron ดีกว่าหรือดีกว่าถ้าจะใช้ระบบแคช
เจดีพาร์ท


3

นอกจากนี้หากแอปพลิเคชันของคุณใช้ SQL SERVER คุณสามารถใช้ SQL Agent เพื่อกำหนดเวลางานของคุณ นี่คือที่ที่เรามักจะใส่รหัสที่เกิดขึ้นใหม่ซึ่งเป็นข้อมูลขับเคลื่อน (การแจ้งเตือนทางอีเมล คุณลักษณะที่ยอดเยี่ยมที่สร้างขึ้นด้วย SQL Agent คือตัวเลือกการแจ้งเตือนความล้มเหลวซึ่งสามารถแจ้งเตือนคุณหากงานสำคัญล้มเหลว


2

ฉันไม่แน่ใจว่าคุณหมายถึงงานที่กำหนดเวลาไว้ประเภทใด หากคุณหมายถึงสิ่งต่างๆเช่นงานพิมพ์ "ทุกชั่วโมงรีเฟรช foo.xml" จากนั้นใช้ระบบงาน Windows Scheduled Tasks (คำสั่ง "at" หรือผ่านทางคอนโทรลเลอร์) ให้เรียกใช้แอพคอนโซลหรือขอหน้าพิเศษที่เริ่มกระบวนการ

แก้ไข: ฉันควรเพิ่มนี่เป็นวิธีที่ดีในการทำให้แอป IIS ของคุณทำงานตามจุดที่กำหนด ดังนั้นสมมติว่าคุณต้องการตรวจสอบ DB ของคุณทุก ๆ 30 นาทีและส่งอีเมลเตือนถึงผู้ใช้เกี่ยวกับข้อมูลบางอย่างคุณสามารถใช้งานที่กำหนดเวลาไว้เพื่อร้องขอหน้านี้และรับการประมวลผล IIS

หากความต้องการของคุณซับซ้อนมากขึ้นคุณอาจลองสร้างบริการ Windows ขึ้นมาและให้มันวนซ้ำเพื่อทำสิ่งที่คุณต้องการ สิ่งนี้ยังมีประโยชน์ในการแยกรหัสเพื่อวัตถุประสงค์ในการปรับขนาดหรือการจัดการ ข้อเสียคุณต้องจัดการกับบริการ Windows


2

หากคุณเป็นเจ้าของเซิร์ฟเวอร์คุณควรใช้ windows task scheduler ใช้ AT /? จากบรรทัดคำสั่งเพื่อดูตัวเลือก

ไม่เช่นนั้นจากสภาพแวดล้อมบนเว็บคุณอาจต้องทำสิ่งที่น่ารังเกียจเช่นตั้งค่าเครื่องอื่นเพื่อขอไปยังหน้าบางหน้าในช่วงเวลาที่กำหนด


2

ฉันใช้Abidarสำเร็จในโครงการ ASP.NET (นี่คือข้อมูลพื้นฐานบางอย่าง )

ปัญหาเดียวของวิธีนี้คืองานจะไม่ทำงานหากแอปพลิเคชันเว็บ ASP.NET ถูกยกเลิกการโหลดจากหน่วยความจำ (เช่นเนื่องจากการใช้งานต่ำ) สิ่งหนึ่งที่ฉันพยายามคือสร้างงานตีเว็บแอปพลิเคชันทุก ๆ 5 นาทีทำให้มีชีวิตอยู่ แต่สิ่งนี้ดูเหมือนจะไม่ได้ทำงานได้อย่างน่าเชื่อถือดังนั้นตอนนี้ฉันใช้ตัวกำหนดตารางเวลาของ Windows และแอปพลิเคชันคอนโซลขั้นพื้นฐานแทน

ทางออกที่ดีที่สุดคือการสร้างบริการ Windows แม้ว่าอาจไม่สามารถทำได้ (เช่นหากคุณใช้สภาพแวดล้อมการโฮสต์แบบแชร์) นอกจากนี้ยังทำให้สิ่งต่าง ๆ ง่ายขึ้นเล็กน้อยจากมุมมองการบำรุงรักษาเพื่อเก็บสิ่งต่าง ๆ ในเว็บแอปพลิเคชัน


1

นี่คือวิธีอื่น:

1) สร้างสคริปต์เว็บ "heartbeat" ที่รับผิดชอบในการเปิดใช้งานหากพวกเขาเป็นเพราะหรือเกินกำหนดที่จะเปิดตัว

2) สร้างกระบวนการที่กำหนดเวลาไว้ที่ใดที่หนึ่ง (ดีกว่าบนเว็บเซิร์ฟเวอร์เดียวกัน) ที่เข้าชม webscript และบังคับให้มันทำงานในช่วงเวลาปกติ (เช่นหน้าต่างกำหนดเวลางานที่เปิดตัวสคริปต์ heatbeat อย่างเงียบ ๆ โดยใช้ IE หรือ whathaveyou)

ความจริงที่ว่ารหัสงานนั้นมีอยู่ในเว็บสคริปต์นั้นมีจุดประสงค์เพื่อรักษารหัสไว้ภายในในโค้ดแอปพลิเคชันบนเว็บ (สมมุติว่าทั้งสองนั้นขึ้นอยู่กับซึ่งกันและกัน) ซึ่งจะง่ายขึ้นสำหรับนักพัฒนาเว็บในการจัดการ .

แนวทางอื่นคือการสร้างสคริปต์ / โปรแกรมของเซิร์ฟเวอร์ที่สามารถทำงานได้ตามกำหนดเวลาทั้งหมดและทำงานได้เองตามภารกิจที่กำหนดไว้ สิ่งนี้สามารถอนุญาตให้ decoupling พื้นฐานระหว่างเว็บแอ็พพลิเคชันและภารกิจที่กำหนดเวลาไว้ ดังนั้นหากคุณต้องการให้งานตามกำหนดเวลาของคุณทำงานแม้กระทั่งว่าแอปพลิเคชัน / ฐานข้อมูลเว็บอาจไม่ทำงานหรือไม่สามารถเข้าถึงได้คุณควรใช้วิธีนี้


1
@Matias ทำไมไม่เพียง แต่กระบวนการที่กำหนดไว้ทำงานจริงแทน?
ลุค

1

คุณสามารถสร้างบริการ Windows ที่เรียกใช้รหัสตามช่วงเวลาได้อย่างง่ายดายโดยใช้วิธีการ 'ThreadPool.RegisterWaitForSingleObject' มันเรียบและง่ายต่อการติดตั้ง วิธีนี้เป็นวิธีที่มีความคล่องตัวมากขึ้นแล้วใช้ตัวจับเวลาใด ๆ ในกรอบงาน

ดูที่ลิงค์ด้านล่างสำหรับข้อมูลเพิ่มเติม:

เรียกใช้กระบวนการเป็นระยะใน. NET โดยใช้บริการ Windows:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html


0

เราใช้แอปพลิเคชั่นคอนโซลด้วย หากคุณใช้เครื่องมือบันทึกเช่น Log4net คุณสามารถตรวจสอบการทำงานได้อย่างถูกต้อง นอกจากนี้ฉันไม่แน่ใจว่าพวกเขาจะรักษายากกว่าเว็บเพจได้อย่างไรเนื่องจากคุณอาจแชร์ไลบรารีโค้ดเดียวกันระหว่างสองถ้ามันถูกออกแบบมาอย่างถูกต้อง

หากคุณไม่ให้งานเหล่านั้นทำงานตามกำหนดเวลาคุณอาจมีหน้าเว็บในส่วนการดูแลระบบของเว็บไซต์ที่ทำหน้าที่เป็นคิว ผู้ใช้ทำการร้องขอเพื่อเรียกใช้งานมันจะแทรกเร็กคอร์ด datestamp เปล่าบนตาราง MyProcessQueue และงานที่กำหนดเวลาไว้ของคุณกำลังตรวจสอบทุก ๆ X นาทีเพื่อดูเร็กคอร์ดใหม่ใน MyProcessQueue ด้วยวิธีนี้จะทำงานเฉพาะเมื่อลูกค้าต้องการให้ทำงาน

หวังว่าคำแนะนำเหล่านั้นจะช่วยได้


0

ทางเลือกหนึ่งคือการตั้งค่าบริการ windows และเรียกใช้งานตามกำหนดเวลาของคุณ

ใน winforms ฉันใช้ตัวจับเวลาไม่คิดว่ามันจะทำงานได้ดีใน ASP.NET


-1

ไลบรารีคลาส Task Scheduler ใหม่สำหรับ. NET

หมายเหตุ: เนื่องจากไลบรารีนี้ถูกสร้างขึ้น Microsoft ได้แนะนำตัวกำหนดตารางงานใหม่ (Task Scheduler 2.0) สำหรับ Windows Vista ไลบรารีนี้เป็น wrapper สำหรับอินเทอร์เฟซ Task Scheduler 1.0 ซึ่งยังคงมีอยู่ใน Vista และเข้ากันได้กับ Windows XP, Windows Server 2003 และ Windows 2000

http://www.codeproject.com/KB/cs/tsnewlib.aspx


กรุณาลบ ได้รับคำตอบด้านล่าง ทำซ้ำ
Fandango68
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.