คุณจะสร้างเงื่อนไขข้อผิดพลาดและดูว่าเกิดอะไรขึ้นเมื่อแอปพลิเคชันดำเนินการอย่างไร
คุณเห็นภาพปฏิสัมพันธ์ระหว่างส่วนต่าง ๆ ที่เกิดขึ้นพร้อมกันของแอปพลิเคชันอย่างไร
จากประสบการณ์ของฉันคำตอบของทั้งสองด้านมีดังนี้:
การติดตามแบบกระจาย
การติดตามแบบกระจายคือเทคโนโลยีที่รวบรวมข้อมูลเวลาสำหรับแต่ละองค์ประกอบที่เกิดขึ้นพร้อมกันของระบบของคุณและนำเสนอให้คุณในรูปแบบกราฟิก การเป็นตัวแทนของการประมวลผลที่เกิดขึ้นพร้อมกันนั้นจะเป็นแบบ interleaved ทำให้คุณเห็นสิ่งที่กำลังทำงานแบบขนานและอะไรไม่ได้
การติดตามแบบกระจายมีต้นกำเนิดในระบบแบบกระจาย (แน่นอน) ซึ่งนิยามแบบอะซิงโครนัสและพร้อมกันสูง ระบบกระจายที่มีการติดตามแบบกระจายช่วยให้ผู้คนสามารถ:
a) ระบุปัญหาคอขวดที่สำคัญ b) รับการแสดงภาพของ 'แอพพลิเคชั่น' ในอุดมคติของแอพพลิเคชั่นของคุณและ c) แสดงทัศนวิสัยว่าพฤติกรรมใดที่เกิดขึ้นพร้อมกัน d) รับข้อมูลจังหวะเวลา ระบบ (สำคัญมากหากคุณมี SLA ที่แข็งแกร่ง)
อย่างไรก็ตามผลลัพธ์ของการติดตามแบบกระจายคือ:
มันเพิ่มค่าใช้จ่ายให้กับกระบวนการที่เกิดขึ้นพร้อมกันทั้งหมดของคุณเนื่องจากจะแปลเป็นรหัสเพิ่มเติมเพื่อดำเนินการและส่งผ่านเครือข่าย ในบางกรณีค่าโสหุ้ยนี้มีความสำคัญอย่างสูง - แม้ Google จะใช้ระบบติดตามของพวกเขาเท่านั้นในส่วนย่อยเล็ก ๆ ของคำขอทั้งหมดเพื่อไม่ให้ทำลายประสบการณ์การใช้งานของผู้ใช้
มีเครื่องมือต่าง ๆ มากมายซึ่งไม่สามารถใช้งานร่วมกันได้ทั้งหมด สิ่งนี้ค่อนข้างได้รับการแก้ไขตามมาตรฐานเช่น OpenTracing แต่ไม่สามารถแก้ไขได้ทั้งหมด
มันไม่ได้บอกอะไรคุณเกี่ยวกับทรัพยากรที่ใช้ร่วมกันและสถานะปัจจุบันของพวกเขา คุณอาจเดาได้ตามรหัสแอปพลิเคชันและกราฟที่คุณเห็นแสดงให้คุณเห็น แต่มันไม่ใช่เครื่องมือที่มีประโยชน์ในเรื่องนี้
เครื่องมือปัจจุบันถือว่าคุณมีหน่วยความจำและที่เก็บข้อมูลสำรอง การโฮสต์เซิร์ฟเวอร์ Timeseries อาจไม่ถูกขึ้นอยู่กับข้อ จำกัด ของคุณ
ซอฟต์แวร์ติดตามข้อผิดพลาด
ฉันเชื่อมโยงไปยัง Sentry ข้างต้นเป็นหลักเพราะเป็นเครื่องมือที่ใช้กันอย่างแพร่หลายและด้วยเหตุผลที่ดี - ซอฟต์แวร์การติดตามข้อผิดพลาดเช่นการดำเนินการ Sentry hijack runtime เพื่อส่งต่อสแต็กติดตามของข้อผิดพลาดที่พบกับเซิร์ฟเวอร์กลาง
ประโยชน์สุทธิของซอฟต์แวร์เฉพาะดังกล่าวในรหัสที่เกิดขึ้นพร้อมกัน:
- ข้อผิดพลาดที่ซ้ำกันจะไม่ซ้ำกัน กล่าวอีกนัยหนึ่งถ้าหนึ่งหรือมากกว่าหนึ่งระบบพร้อมกันพบข้อยกเว้นเดียวกันยามจะเพิ่มรายงานเหตุการณ์ที่เกิดขึ้น แต่ไม่ส่งสองชุดของเหตุการณ์
ซึ่งหมายความว่าคุณสามารถทราบได้ว่าระบบใดที่เกิดขึ้นพร้อมกันซึ่งเกิดข้อผิดพลาดชนิดใดโดยไม่ต้องรายงานข้อผิดพลาดพร้อมกันนับไม่ถ้วน หากคุณเคยประสบปัญหาสแปมอีเมลจากระบบกระจายคุณรู้ว่านรกรู้สึกอย่างไร
คุณสามารถ 'ติดแท็ก' แง่มุมที่แตกต่างกันของระบบที่เกิดขึ้นพร้อมกันของคุณ (แม้ว่ามันจะถือว่าคุณไม่ได้มีการทำงานร่วมกันในหนึ่งเธรดซึ่งเทคนิคไม่พร้อมกันต่อไปเนื่องจากเธรดกระโดดระหว่างงานอย่างมีประสิทธิภาพ แต่ต้องประมวลผลตัวจัดการเหตุการณ์ เพื่อเสร็จสิ้น) และดูรายละเอียดข้อผิดพลาดตามแท็ก
- คุณสามารถแก้ไขซอฟต์แวร์จัดการข้อผิดพลาดนี้เพื่อให้รายละเอียดเพิ่มเติมพร้อมกับข้อยกเว้นรันไทม์ของคุณ กระบวนการเปิดแหล่งข้อมูลใดบ้าง มีทรัพยากรที่ใช้ร่วมกันที่กระบวนการนี้ถืออยู่หรือไม่ ผู้ใช้รายใดประสบปัญหานี้
นอกเหนือจากการติดตามสแต็กอย่างพิถีพิถัน (และแมปแหล่งที่มาหากคุณต้องจัดเตรียมเวอร์ชันไฟล์ย่อของคุณ) ทำให้ง่ายต่อการพิจารณาว่าเกิดอะไรขึ้นเป็นส่วนใหญ่
- (ระบุเฉพาะยาม) คุณสามารถมีแดชบอร์ดการรายงาน Sentry แยกต่างหากสำหรับการทดสอบการทำงานของระบบช่วยให้คุณสามารถตรวจจับข้อผิดพลาดในการทดสอบ
ข้อเสียของซอฟต์แวร์ดังกล่าว ได้แก่ :
ชอบทุกอย่างพวกเขาเพิ่มจำนวนมาก คุณอาจไม่ต้องการระบบดังกล่าวบนฮาร์ดแวร์ฝังตัวเป็นต้น ฉันขอแนะนำให้ทำการทดลองใช้งานซอฟต์แวร์ดังกล่าวโดยเปรียบเทียบกับการดำเนินการอย่างง่าย ๆ ที่มีและไม่มีการสุ่มตัวอย่างมากกว่าสองร้อยรันบนเครื่องที่ไม่ได้ใช้งาน
ไม่รองรับทุกภาษาเท่า ๆ กันเนื่องจากระบบเหล่านี้ส่วนใหญ่ใช้ข้อยกเว้นโดยปริยายและไม่มีทุกภาษาที่มีข้อยกเว้นที่สมบูรณ์ ที่กล่าวว่ามีลูกค้าสำหรับระบบมากมาย
พวกเขาอาจถูกยกระดับเป็นความเสี่ยงด้านความปลอดภัยเนื่องจากระบบเหล่านี้ส่วนใหญ่เป็นระบบปิด ในกรณีเช่นนี้ให้ทำการตรวจสอบสถานะของคุณอย่างรอบคอบหรือทำการหมุนเอง
พวกเขาอาจไม่ให้ข้อมูลที่คุณต้องการเสมอไป นี่เป็นความเสี่ยงเมื่อพยายามเพิ่มการมองเห็น
บริการเหล่านี้ส่วนใหญ่ได้รับการออกแบบสำหรับเว็บแอพพลิเคชั่นพร้อมกันสูงดังนั้นเครื่องมือบางอย่างอาจไม่สมบูรณ์แบบสำหรับกรณีการใช้งานของคุณ
กล่าวโดยสรุป : การมีทัศนวิสัยเป็นส่วนที่สำคัญที่สุดของระบบใด ๆ ที่เกิดขึ้นพร้อมกัน สองวิธีที่ฉันอธิบายข้างต้นร่วมกับแดชบอร์ดเฉพาะเกี่ยวกับฮาร์ดแวร์และข้อมูลเพื่อให้ได้ภาพ holidtic ของระบบในเวลาใดก็ตามที่ใช้กันอย่างแพร่หลายในอุตสาหกรรมอย่างแม่นยำเพื่อที่อยู่ด้านนั้น
คำแนะนำเพิ่มเติมบางส่วน
ฉันใช้เวลามากกว่าที่ฉันใส่ใจในการแก้ไขโค้ดโดยผู้ที่พยายามแก้ไขปัญหาพร้อมกันในวิธีที่แย่มาก ทุกครั้งที่ฉันพบกรณีที่สิ่งต่าง ๆ ต่อไปนี้สามารถปรับปรุงประสบการณ์ของนักพัฒนาซอฟต์แวร์ได้ (ซึ่งสำคัญเท่ากับประสบการณ์ของผู้ใช้):
การทดสอบการเชื่อมโยงที่ดีจะตรวจสอบว่าเมื่อองค์ประกอบหนึ่งพูดถึงส่วนประกอบอื่นแยกข้อความที่ได้รับและข้อความที่ส่งเป็นแบบเดียวกับที่คุณคาดหวัง หากคุณมีส่วนประกอบสองรายการขึ้นไปที่ใช้บริการที่ใช้ร่วมกันในการสื่อสารหมุนพวกเขาทั้งหมดให้พวกเขาแลกเปลี่ยนข้อความผ่านบริการกลางและดูว่าพวกเขาทั้งหมดได้รับสิ่งที่คุณคาดหวังในท้ายที่สุด
การทำลายการทดสอบที่เกี่ยวข้องกับส่วนประกอบจำนวนมากในการทดสอบส่วนประกอบเองและการทดสอบว่าแต่ละองค์ประกอบสื่อสารกันอย่างไรให้ความมั่นใจในความถูกต้องของรหัสของคุณมากขึ้น การมีการทดสอบที่เข้มงวดเช่นนี้ช่วยให้คุณสามารถบังคับใช้สัญญาระหว่างบริการรวมทั้งตรวจจับข้อผิดพลาดที่ไม่คาดคิดที่เกิดขึ้นเมื่อทำงานพร้อมกัน
- ใช้อัลกอริทึมที่ถูกต้องเพื่อตรวจสอบสถานะแอปพลิเคชันของคุณ ฉันกำลังพูดถึงเรื่องง่าย ๆ เช่นเมื่อคุณมีกระบวนการหลักรอให้พนักงานทุกคนทำงานจนเสร็จและต้องการย้ายไปยังขั้นตอนต่อไปหากพนักงานทุกคนทำงานเต็มที่ - นี่เป็นตัวอย่างของการตรวจสอบทั่วโลก การสิ้นสุดซึ่งมีวิธีการที่รู้จักเช่นอัลกอริทึมของ Safra
เครื่องมือเหล่านี้บางตัวมาพร้อมกับภาษาเช่น Rust รับประกันว่ารหัสของคุณจะไม่มีสภาพการแข่งขันในเวลารวบรวมขณะที่ Go นำเสนอตัวตรวจจับการหยุดชะงักแบบ inbuilt ที่ทำงานในเวลารวบรวม หากคุณสามารถตรวจจับปัญหาก่อนที่จะถึงการผลิตมันจะเป็นชัยชนะเสมอ
กฎทั่วไปของหัวแม่มือ: การออกแบบสำหรับความล้มเหลวในระบบพร้อมกัน คาดว่าบริการทั่วไปจะพังหรือเสียหาย สิ่งนี้จะเป็นไปได้แม้กระทั่งรหัสที่ไม่ได้กระจายข้ามเครื่อง - รหัสที่เกิดขึ้นพร้อมกันในเครื่องเดียวสามารถพึ่งพาการพึ่งพาจากภายนอก (เช่นไฟล์บันทึกที่ใช้ร่วมกันเซิร์ฟเวอร์ Redis เซิร์ฟเวอร์ MySQL แช่ง) ที่อาจหายไปหรือถูกลบออกได้ตลอดเวลา .
วิธีที่ดีที่สุดในการทำเช่นนี้คือการตรวจสอบสถานะแอปพลิเคชั่นเป็นระยะ ๆ - ตรวจสุขภาพสำหรับแต่ละบริการ เครื่องมือตู้คอนเทนเนอร์ที่ทันสมัยเช่น Docker ทำได้ค่อนข้างดีและควรใช้กับสิ่งต่าง ๆ ในกล่องทราย
คุณคิดออกว่าสามารถทำอะไรพร้อมกันและสิ่งที่สามารถทำตามลำดับ?
หนึ่งในบทเรียนที่ยิ่งใหญ่ที่สุดที่ผมได้เรียนรู้การทำงานในระบบพร้อมกันสูงคือ: คุณไม่สามารถมีตัวชี้วัดที่เพียงพอ ตัวชี้วัดควรผลักดันทุกอย่างในแอปพลิเคชันของคุณ - คุณไม่ใช่วิศวกรถ้าคุณไม่ได้วัดทุกอย่าง
หากไม่มีการวัดคุณจะไม่สามารถทำสิ่งสำคัญสองสามประการ:
ประเมินความแตกต่างที่เกิดจากการเปลี่ยนแปลงระบบ หากคุณไม่ทราบว่าปุ่มปรับแต่ง A ที่ทำขึ้น B ตัวชี้วัดขึ้นและตัวชี้วัด C ลงไปคุณไม่ทราบวิธีการแก้ไขระบบของคุณเมื่อมีคนกดรหัสร้ายในระบบของคุณ (และพวกเขาจะผลักดันรหัสไปยังระบบของคุณ) .
ทำความเข้าใจกับสิ่งที่คุณต้องทำต่อไปเพื่อปรับปรุงสิ่งต่าง ๆ จนกว่าคุณจะรู้ว่าแอปพลิเคชั่นมีหน่วยความจำเหลือน้อยคุณจะไม่สามารถแยกแยะว่าคุณควรได้รับหน่วยความจำเพิ่มหรือซื้อดิสก์เพิ่มสำหรับเซิร์ฟเวอร์ของคุณ
ตัวชี้วัดมีความสำคัญและจำเป็นมากที่ฉันได้ใช้ความพยายามอย่างมีสติในการวางแผนสิ่งที่ฉันต้องการวัดผลก่อนที่ฉันจะคิดถึงสิ่งที่ระบบต้องการ ในความเป็นจริงการวัดมีความสำคัญมากจนฉันเชื่อว่ามันเป็นคำตอบที่ถูกต้องสำหรับคำถามนี้: คุณจะรู้ว่าสิ่งใดที่สามารถทำตามลำดับหรือพร้อมกันเมื่อคุณวัดว่าบิตในโปรแกรมของคุณกำลังทำอะไร การออกแบบที่เหมาะสมใช้ตัวเลขไม่ใช่การเดา
ที่ถูกกล่าวว่ามีกฎง่ายๆไม่กี่:
ลำดับหมายถึงการพึ่งพา กระบวนการสองกระบวนการควรเรียงตามลำดับหากกระบวนการหนึ่งขึ้นอยู่กับอีกกระบวนการหนึ่ง กระบวนการที่ไม่มีการขึ้นต่อกันควรจะเกิดขึ้นพร้อมกัน อย่างไรก็ตามวางแผนวิธีจัดการกับความล้มเหลวของสตรีมที่ไม่ได้ป้องกันกระบวนการดาวน์สตรีมจากการรออย่างไม่มีกำหนด
อย่าผสมภารกิจที่ผูกมัด I / O กับงานที่ผูกกับ CPU บนแกนหลักเดียวกัน อย่า (ตัวอย่าง) เขียนโปรแกรมรวบรวมข้อมูลเว็บที่เปิดใช้งานคำขอที่เกิดขึ้นพร้อมกันสิบรายการในเธรดเดียวกัน scones พวกเขาทันทีที่พวกเขาเข้ามาและคาดว่าจะเพิ่มเป็นห้าร้อย - คำขอ I / O ไปที่คิวพร้อมกัน แต่ CPU จะยังคงดำเนินต่อไปตามลำดับ (โมเดลเหตุการณ์ที่ขับเคลื่อนด้วยเธรดเดี่ยวนี้เป็นโมเดลที่ได้รับความนิยม แต่มีข้อ จำกัด เนื่องจากด้านนี้ - แทนที่จะเข้าใจสิ่งนี้ผู้คนเพียงแค่บีบมือแล้วบอกว่าโหนดไม่ได้ปรับขนาดเพื่อเป็นตัวอย่างให้กับคุณ)
เธรดเดียวสามารถทำงาน I / O ได้มาก แต่เพื่อที่จะใช้งานพร้อมกันอย่างเต็มที่ของฮาร์ดแวร์ของคุณใช้ threadpools ที่ร่วมกันครอบครองแกนทั้งหมด ในตัวอย่างข้างต้นการเปิดตัวกระบวนการ Python ห้ากระบวนการ (ซึ่งแต่ละกระบวนการสามารถใช้คอร์ในเครื่องหกคอร์) สำหรับการทำงานของ CPU และเธรด Python ที่หกสำหรับการทำงานของ I / O จะเร็วขึ้นกว่าที่คุณคิด
วิธีเดียวที่จะใช้ประโยชน์จากการทำงานพร้อมกันของ CPU คือการใช้เธรดพูล เธรดเดี่ยวมักจะดีพอสำหรับงาน I / O ที่ถูกผูกไว้จำนวนมาก นี่คือเหตุผลว่าทำไมเว็บเซิร์ฟเวอร์ที่ขับเคลื่อนด้วยเหตุการณ์เช่น Nginx ปรับขนาดได้ดีกว่า (พวกเขาทำงานที่ถูกผูกไว้กับ I / O อย่างแท้จริง) กว่า Apache (ซึ่งทำให้ I / O ถูกผูกไว้ทำงานกับสิ่งที่ต้องการ CPU และเปิดตัวกระบวนการต่อคำขอ) การคำนวณ GPU นับหมื่นที่ได้รับในแบบคู่ขนานเป็นความคิดที่แย่มาก