การจัดการข้อยกเว้นในโปรแกรมที่ต้องการเรียกใช้ 24/7


14

ฉันได้อ่านแล้วว่าเราควรจะจับข้อยกเว้นที่สามารถจัดการได้ซึ่งทำให้การจับคลาสยกเว้นฐาน (C # ในกรณีนี้) เป็นความคิดที่ไม่ดี (ด้วยเหตุผลอื่น) ปัจจุบันฉันเป็นส่วนหนึ่งของโครงการที่ฉันยังไม่เห็นอะไรเลยนอกจากข้อยกเว้นพื้นฐานที่ถูกจับได้ ฉันบอกว่ามันถือว่าเป็นการปฏิบัติที่ไม่ดี แต่การตอบสนองคือ "บริการนี้ต้องทำงานตลอด 24/7 ดังนั้นนี่คือวิธีที่มันเป็น"

เนื่องจากฉันไม่ได้รับการตอบรับที่ดีสำหรับวิธีการจัดการข้อยกเว้นในโปรแกรมที่ต้องการเรียกใช้ 24/7 อย่างถูกต้องฉันจึงมาที่นี่ ฉันไม่ได้หาข้อมูล / คำแนะนำเกี่ยวกับวิธีจัดการกับการจัดการข้อยกเว้นในโปรแกรม / บริการ "วิกฤติ" ที่ต้องทำงานตลอดเวลา (และในกรณีนี้ฉันเชื่อว่ามันอาจใช้ได้ถ้าบริการหยุดทำงานเป็นเวลาหนึ่งนาที หรือสองจึงไม่สำคัญ) ฉันเข้าใจว่ามันขึ้นอยู่กับลักษณะที่แน่นอนของโปรแกรม ข้อกำหนดสำหรับโปรแกรมที่อาจทำให้เกิดปัญหาการคุกคามต่อชีวิตแตกต่างกันมากเมื่อเทียบกับเครื่องสแกนบันทึกสำหรับเกมออนไลน์

สองตัวอย่าง:

1: บริการพิมพ์ล่วงหน้าสำหรับลูกค้าของรถไฟ Brittish ใช้เมื่อค้นหาออนไลน์สำหรับสถานีรถไฟ

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

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


2
สแต็คคลี่คลายระหว่างการจัดการข้อยกเว้นในแอปแบบเรียลไทม์ (sic!) สามารถทำลายรถไฟได้
Deer Hunter

4
@DeerHunter การเข้ารหัสที่ไม่ดีโดยไม่มีข้อยกเว้นสามารถให้ผลลัพธ์เดียวกัน
BЈовић

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

1
หากแอปพลิเคชันต้องการเรียกใช้ 24/7 จะมีวงวนไม่สิ้นสุดที่ใดที่หนึ่งและวงวนไม่สิ้นสุดนี้จะถูกห่อหุ้มรอบโครงสร้างที่ดีกว่าเพื่อจับข้อยกเว้นที่ไม่สามารถจัดการได้ทั้งหมด หากไม่ใช่กรณีนี้ข้อยกเว้นที่ไม่สามารถจัดการได้จะส่งผ่านไปยังตัวจัดการ catch-all ที่มีอยู่แล้วที่อยู่นอกหลักและ kaboom! แอปพลิเคชั่น 24/7 สิ้นสุดลง
David Hammen

คำตอบ:


7

คุณสมบัติบางภาษาเช่น

  • เก็บขยะ
  • ระบบการยกเว้น
  • การประเมินผลขี้เกียจ

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


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

เพื่อสรุปสิ่งนี้: ในโปรแกรมที่ทนทานส่วนต่าง ๆ จะถูกแยกออกจากกันและสามารถเริ่มต้นใหม่หรือปรับขนาดได้อย่างอิสระ

ดังนั้นโดยพื้นฐานแล้วเราต้องการโค้ดที่เทียบเท่ากับสิ่งนี้:

while (true) {
  try {
    DoWork();
  }
  catch (Exception e) {
    log(e);
  }
}

บวกวิธีการยกเลิกการวนรอบ การวนซ้ำดังกล่าวจะทำให้แต่ละเธรดทำงาน


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

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


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

2

ในการตอบคำถามคุณต้องเข้าใจว่าข้อยกเว้นคืออะไรและทำงานอย่างไร

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

โปรแกรมจะหยุดการทำงานหากไม่มีตัวจัดการ catch อาจยอมรับได้ทั้งนี้ขึ้นอยู่กับการตั้งค่าและข้อกำหนดของคุณ

ในกรณีเฉพาะของคุณ:

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

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


1

ฉันยังไม่เห็นอะไรเลยนอกจากข้อยกเว้นพื้นฐานที่ถูกจับได้

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

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

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

ดังนั้นเมื่อฉันเข้าใจคำถามฉันขอแนะนำว่าในตัวอย่างแรกคุณควรจะเพิ่มการจัดการข้อยกเว้นที่เฉพาะเจาะจงมากกว่าเพื่อลบตัวจัดการชนิดข้อยกเว้นพื้นฐาน


0

สำหรับจุดที่ 2: อย่าใช้ C # ไม่ใช่ภาษาเรียลไทม์และคุณจะเจ็บถ้าคุณลองใช้มัน

สำหรับจุดที่ 1: คุณสามารถไปทาง erlang ได้: ปล่อยให้มันพังแล้วรีสตาร์ท


การใช้งาน C # และความเชี่ยวชาญของฉันไม่อยู่ที่จุด 2 (การเปลี่ยนแทร็กตามเวลาจริง) ฉันสงสัยว่าทำไม C # จึงไม่เหมาะกับงานดังกล่าว
Michael O'Neill

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

0

Dec Disclaimer: สิ่งเหล่านี้เป็นเพียงความคิดฉันไม่มีประสบการณ์

ฉันเดาว่าโปรแกรมที่ตอบสนองความต้องการของตัวอย่างที่สองควรเป็นแบบแยกส่วนมาก ดังนั้นโมดูลจะสามารถเริ่มต้นใหม่ได้โดยไม่ทำให้ระบบไม่เสถียร

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

จะทำให้เกิดความซ้ำซ้อน - ฮาร์ดแวร์และซอฟต์แวร์ซ้ำซ้อน อินสแตนซ์หนึ่งถูกต่อสายไปยังระบบควบคุมและอีกอินสแตนซ์ทำงานฟรี หากตรวจพบข้อผิดพลาดระบบจะถูกสลับ

ตัวอย่างคือกระบวนการสองกระบวนการในเครื่องเดียวกันซึ่งตรวจสอบอีกกระบวนการหนึ่งและหากกระบวนการหนึ่งถูกฆ่าตายอีกกระบวนการหนึ่งจะเกิดใหม่และแยกส่วน PID หลักออกจากตัวมันเอง

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