วันหยุดสิ้นสุดลงแล้ว และเรากลับมาพร้อมกับโพสต์ที่สองในซีรีส์ Istio Service Mesh
หัวข้อของวันนี้คือ Circuit Breaker ซึ่งแปลเป็นภาษารัสเซียว่า "เซอร์กิตเบรกเกอร์" ซึ่งแปลเป็นภาษารัสเซียว่า "เซอร์กิตเบรกเกอร์" หรือที่เรียกกันทั่วไปว่า "เซอร์กิตเบรกเกอร์" เฉพาะใน Istio เครื่องนี้จะไม่ตัดการเชื่อมต่อวงจรที่ลัดวงจรหรือโอเวอร์โหลด แต่เป็นคอนเทนเนอร์ที่ผิดพลาด
วิธีนี้จะทำงานได้ดีที่สุด
เมื่อไมโครเซอร์วิสได้รับการจัดการโดย Kubernetes เช่น ภายในแพลตฟอร์ม OpenShift ไมโครเซอร์วิสจะปรับขนาดขึ้นและลงโดยอัตโนมัติขึ้นอยู่กับโหลด เนื่องจากไมโครเซอร์วิสทำงานในพ็อด จึงสามารถมีอินสแตนซ์ของไมโครเซอร์วิสแบบคอนเทนเนอร์ได้หลายอินสแตนซ์บนปลายทางเดียว และ Kubernetes จะกำหนดเส้นทางคำขอและความสมดุลของโหลดระหว่างกัน และตามหลักการแล้ว ทั้งหมดนี้ควรจะทำงานได้อย่างสมบูรณ์แบบ
เราจำได้ว่าไมโครเซอร์วิสนั้นมีขนาดเล็กและเกิดขึ้นเพียงชั่วคราว ความชั่วคราว ซึ่งในที่นี้หมายถึงความปรากฏและหายไปได้ง่าย มักถูกประเมินต่ำเกินไป การเกิดและการตายของอินสแตนซ์อื่นของไมโครเซอร์วิสในพ็อดเป็นสิ่งที่ค่อนข้างคาดหวัง OpenShift และ Kubernetes จัดการเรื่องนี้ได้ดี และทุกอย่างทำงานได้ดี - แต่ในทางทฤษฎีอีกครั้ง
มันทำงานอย่างไรจริงๆ
ทีนี้ลองจินตนาการว่าอินสแตนซ์เฉพาะของไมโครเซอร์วิส ซึ่งก็คือคอนเทนเนอร์ใช้งานไม่ได้: มันไม่ตอบสนอง (ข้อผิดพลาด 503) หรือสิ่งที่ไม่พึงประสงค์กว่านั้นคือตอบสนอง แต่ช้าเกินไป กล่าวอีกนัยหนึ่ง ข้อผิดพลาดหรือไม่ตอบสนองต่อคำขอ แต่จะไม่ถูกลบออกจากพูลโดยอัตโนมัติ ในกรณีนี้ควรทำอย่างไร? หากต้องการลองอีกครั้ง? ฉันควรลบออกจากโครงร่างการกำหนดเส้นทางหรือไม่ และคำว่า "ช้าเกินไป" หมายความว่าอย่างไร - มีตัวเลขเท่าไร และใครเป็นคนกำหนด? อาจจะแค่หยุดพักแล้วลองอีกครั้งในภายหลัง? ถ้าเป็นเช่นนั้นอีกนานแค่ไหน?
Pool Ejection ใน Istio คืออะไร
และที่นี่ Istio ได้เข้ามาช่วยเหลือด้วยเครื่องป้องกัน Circuit Breaker ซึ่งจะลบคอนเทนเนอร์ที่ผิดพลาดออกจากพูลทรัพยากรการกำหนดเส้นทางและการทำโหลดบาลานซ์เป็นการชั่วคราว โดยใช้ขั้นตอนการดีดพูลออก
ด้วยการใช้กลยุทธ์การตรวจจับค่าผิดปกติ Istio จะตรวจจับพ็อดโค้งที่ไม่อยู่ในแนวและนำออกจากพูลทรัพยากรตามระยะเวลาที่กำหนด ซึ่งเรียกว่าหน้าต่างสลีป
เพื่อแสดงให้เห็นว่าสิ่งนี้ทำงานอย่างไรใน Kubernetes บนแพลตฟอร์ม OpenShift เรามาเริ่มต้นด้วยภาพหน้าจอของไมโครเซอร์วิสที่ทำงานตามปกติจากตัวอย่างในพื้นที่เก็บข้อมูล
เตรียมพร้อมรับอุบัติเหตุ
ก่อนที่จะทำการ Pool Ejection คุณต้องสร้างกฎการกำหนดเส้นทาง Istio ก่อน สมมติว่าเราต้องการกระจายคำขอระหว่างพ็อดในอัตราส่วน 50/50 นอกจากนี้ เราจะเพิ่มจำนวนคอนเทนเนอร์ v2 จากหนึ่งเป็นสอง เช่นนี้:
oc scale deployment recommendation-v2 --replicas=2 -n tutorial
ตอนนี้เราได้ตั้งกฎการกำหนดเส้นทางเพื่อให้การรับส่งข้อมูลมีการกระจายระหว่างพ็อดในอัตราส่วน 50/50
ผลลัพธ์ของกฎนี้มีลักษณะดังนี้:
คุณสามารถพบข้อผิดพลาดได้เนื่องจากหน้าจอนี้ไม่ใช่ 50/50 แต่เป็น 14:9 แต่สถานการณ์จะดีขึ้นเมื่อเวลาผ่านไป
ทำให้เกิดข้อผิดพลาด
ตอนนี้เรามาปิดการใช้งานหนึ่งในสองคอนเทนเนอร์ v2 เพื่อให้เรามีคอนเทนเนอร์ v1 ที่ดีหนึ่งคอนเทนเนอร์ v2 คอนเทนเนอร์ที่ดีหนึ่งรายการ และคอนเทนเนอร์ v2 ที่ผิดพลาดหนึ่งรายการ:
แก้ไขข้อผิดพลาด
ดังนั้นเราจึงมีคอนเทนเนอร์ที่ชำรุด และถึงเวลาสำหรับการดีดพูลออก เมื่อใช้การกำหนดค่าที่ง่ายมาก เราจะแยกคอนเทนเนอร์ที่ล้มเหลวนี้ออกจากโครงร่างการกำหนดเส้นทางใดๆ เป็นเวลา 15 วินาที ด้วยความหวังว่าจะกลับสู่สถานะที่สมบูรณ์ (ไม่ว่าจะรีสตาร์ทหรือคืนค่าประสิทธิภาพ) นี่คือลักษณะของการกำหนดค่านี้และผลลัพธ์ของการทำงาน:
อย่างที่คุณเห็น คอนเทนเนอร์ v2 ที่ล้มเหลวจะไม่ถูกใช้สำหรับคำขอการกำหนดเส้นทางอีกต่อไป เนื่องจากถูกลบออกจากพูลแล้ว แต่หลังจากผ่านไป 15 วินาที มันจะกลับลงสระโดยอัตโนมัติ จริงๆ แล้ว เราเพิ่งแสดงให้เห็นว่า Pool Ejection ทำงานอย่างไร
มาเริ่มสร้างสถาปัตยกรรมกันดีกว่า
Pool Ejection รวมกับความสามารถในการตรวจสอบของ Istio ช่วยให้คุณสามารถเริ่มสร้างเฟรมเวิร์กสำหรับการแทนที่คอนเทนเนอร์ที่ผิดพลาดโดยอัตโนมัติ เพื่อลดการหยุดทำงานและความล้มเหลว หากไม่กำจัด
NASA มีคติประจำใจอันดังอยู่ข้อหนึ่ง - ความล้มเหลวไม่ใช่ทางเลือก ซึ่งผู้เขียนถือเป็นผู้อำนวยการการบิน
ตามที่เราเขียนไว้ข้างต้น Istio ได้นำแนวคิดของเซอร์กิตเบรกเกอร์มาใช้ ซึ่งพิสูจน์ตัวเองได้ดีในโลกทางกายภาพ และเช่นเดียวกับเบรกเกอร์ไฟฟ้าจะปิดส่วนที่มีปัญหาของวงจร ซอฟต์แวร์ Circuit Breaker ของ Istio จะเปิดการเชื่อมต่อระหว่างกระแสคำขอและคอนเทนเนอร์ที่มีปัญหาเมื่อมีบางอย่างผิดปกติกับตำแหน่งข้อมูล เช่น เมื่อเซิร์ฟเวอร์ขัดข้องหรือเริ่มที่จะ ช้าลงหน่อย.
ยิ่งไปกว่านั้น ในกรณีที่สองมีปัญหามากขึ้นเนื่องจากการเบรกของคอนเทนเนอร์เดียวไม่เพียงทำให้เกิดความล่าช้าในการเข้าถึงบริการและเป็นผลให้ประสิทธิภาพของระบบโดยรวมลดลง แต่ยังสร้างซ้ำอีก ร้องขอบริการที่ทำงานช้าอยู่แล้ว ซึ่งจะทำให้สถานการณ์แย่ลงเท่านั้น
เซอร์กิตเบรกเกอร์ในทางทฤษฎี
Circuit Breaker เป็นพร็อกซีที่ควบคุมการไหลของคำขอไปยังอุปกรณ์ปลายทาง เมื่อจุดนี้หยุดทำงานหรือเริ่มช้าลง ทั้งนี้ขึ้นอยู่กับการตั้งค่าที่ระบุ พร็อกซีจะตัดการเชื่อมต่อกับคอนเทนเนอร์ จากนั้นการรับส่งข้อมูลจะถูกเปลี่ยนเส้นทางไปยังคอนเทนเนอร์อื่น ๆ เพียงเพราะการปรับสมดุลโหลด การเชื่อมต่อยังคงเปิดอยู่สำหรับหน้าต่างสลีปที่กำหนด เช่น สองนาที จากนั้นถือว่าเปิดเพียงครึ่งเดียว ความพยายามที่จะส่งคำขอถัดไปจะกำหนดสถานะการเชื่อมต่อเพิ่มเติม หากทุกอย่างเรียบร้อยดีกับบริการ การเชื่อมต่อจะกลับสู่สภาพการทำงานและปิดอีกครั้ง หากยังมีสิ่งผิดปกติเกิดขึ้นกับบริการ การเชื่อมต่อจะถูกตัดการเชื่อมต่อ และหน้าต่างสลีปจะถูกเปิดใช้งานอีกครั้ง ต่อไปนี้คือแผนภาพสถานะ Circuit Breaker แบบง่ายที่มีลักษณะดังนี้:
สิ่งสำคัญคือต้องทราบที่นี่ว่าทั้งหมดนี้เกิดขึ้นในระดับของสถาปัตยกรรมระบบ ดังนั้นเมื่อถึงจุดหนึ่ง คุณจะต้องสอนให้แอปพลิเคชันของคุณทำงานกับ Circuit Breaker ได้ เช่น ระบุค่าเริ่มต้นในการตอบสนอง หรือหากเป็นไปได้ ละเว้นการมีอยู่ของบริการ มีการใช้รูปแบบกั้นสำหรับสิ่งนี้ แต่อยู่นอกเหนือขอบเขตของบทความนี้
เซอร์กิตเบรกเกอร์ในทางปฏิบัติ
ตัวอย่างเช่น เราจะใช้งานไมโครเซอร์วิสคำแนะนำของเราสองเวอร์ชันบน OpenShift เวอร์ชัน 1 จะทำงานได้ดี แต่ในเวอร์ชัน 2 เราจะสร้างความล่าช้าเพื่อจำลองการชะลอตัวบนเซิร์ฟเวอร์ หากต้องการดูผลลัพธ์ให้ใช้เครื่องมือ
siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io
ดูเหมือนทุกอย่างจะได้ผล แต่ราคาเท่าไหร่ล่ะ? เมื่อมองแวบแรก เรามีความพร้อมใช้งาน 100% แต่ลองพิจารณาให้ละเอียดยิ่งขึ้น - ระยะเวลาการทำธุรกรรมสูงสุดคือมากถึง 12 วินาที นี่เป็นคอขวดอย่างชัดเจนและจำเป็นต้องขยาย
ในการดำเนินการนี้ เราจะใช้ Istio เพื่อกำจัดการเรียกคอนเทนเนอร์ที่ช้า นี่คือลักษณะการกำหนดค่าที่สอดคล้องกันโดยใช้ Circuit Breaker:
บรรทัดสุดท้ายที่มีพารามิเตอร์ httpMaxRequestsPerConnection ส่งสัญญาณว่าการเชื่อมต่อควรถูกตัดการเชื่อมต่อเมื่อพยายามสร้างการเชื่อมต่อใหม่ - การเชื่อมต่อครั้งที่สองนอกเหนือจากที่มีอยู่ เนื่องจากคอนเทนเนอร์ของเราจำลองบริการที่ช้า สถานการณ์ดังกล่าวจึงจะเกิดขึ้นเป็นระยะ จากนั้น Istio จะส่งข้อผิดพลาด 503 กลับคืนมา แต่นี่คือสิ่งที่ระบบจะแสดง:
โอเค เรามีเซอร์กิตเบรกเกอร์แล้ว จะทำอย่างไรต่อไป?
ดังนั้นเราจึงใช้การปิดระบบอัตโนมัติโดยไม่ต้องแตะต้องซอร์สโค้ดของบริการเลย การใช้ Circuit Breaker และขั้นตอนการดีดพูลที่อธิบายไว้ข้างต้น เราสามารถถอดคอนเทนเนอร์เบรกออกจากพูลทรัพยากรจนกว่าจะกลับสู่สภาวะปกติ และตรวจสอบสถานะที่ความถี่ที่ระบุ - ในตัวอย่างของเรา นี่คือสองนาที (พารามิเตอร์ sleepWindow)
โปรดทราบว่าความสามารถของแอปพลิเคชันในการตอบสนองต่อข้อผิดพลาด 503 ยังคงถูกกำหนดไว้ที่ระดับซอร์สโค้ด การใช้ Circuit Breaker มีหลายวิธี ขึ้นอยู่กับสถานการณ์
ในโพสต์ถัดไป: เราจะพูดถึงการติดตามและการเฝ้าติดตามที่มีอยู่แล้วภายในหรือเพิ่มลงใน Istio อย่างง่ายดาย รวมถึงวิธีการนำข้อผิดพลาดเข้าสู่ระบบโดยเจตนา
ที่มา: will.com