Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

ปรับขนาด Sidekiq อย่างหมดจด

ต้นปีนี้ เราได้ย้ายจากเซิร์ฟเวอร์เฉพาะที่โฮสต์สิ่งอำนวยความสะดวกไปยัง AWS และเราดีใจมากที่ได้ทำ เรายินดีที่จะมีระบบอัตโนมัติจำนวนมาก เนื่องจากเราใช้เวลาน้อยลงในการเล่นซอกับเซิร์ฟเวอร์ด้วยวิธีนี้ :) โพสต์นี้อธิบายสิ่งที่เกิดขึ้นในโครงสร้างพื้นฐานของเราเมื่อเรามีการเปลี่ยนแปลงปริมาณการแจ้งเตือนข้อผิดพลาดที่ประมวลผล

เราปรับขนาดอย่างไร

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

เราปรับขนาดอย่างไร อย่างมีสไตล์

อุปสรรคประการเดียวในการตั้งค่านี้คือ เราต้องการให้แน่ใจว่า Sidekiqworker ทำงานทั้งหมดของพวกเขาเสร็จก่อนที่อินสแตนซ์จะถูกกำจัด แม้ว่า Sidekiq จะสนับสนุนการจัดกำหนดการงานที่ถูกยกเลิกก่อนเสร็จสิ้น แต่เราต้องการหลีกเลี่ยงเมื่อทำได้ ดีกว่าที่จะใช้เวลาสองสามวินาทีเพิ่มเติมเพื่อทำงานให้เสร็จ ดีกว่าที่จะจัดตารางใหม่และเริ่มต้นใหม่ โชคดีที่ในความยอดเยี่ยมของมัน Sidekiq มีวิธีบอกกระบวนการของพนักงานให้หยุดรับงานใหม่หลังจากงานปัจจุบันเสร็จสิ้น ทำให้ง่ายต่อการระบายพนักงานเพื่อเตรียมพร้อมสำหรับการเลิกจ้าง เคล็ดลับคือการทำให้คนงานเหล่านั้นรู้ว่าพวกเขาต้องการเริ่มระบาย — และสำหรับสิ่งนั้น เราใช้ Lifecycle Hooks, CloudWatch Events + Lambda, EC2 Simple Systems Manager และโค้ดเล็กน้อย

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

ข้อกำหนดเบื้องต้น

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

เดอะโค้ด

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

เราได้รับรายการกระบวนการ Sidekiq ที่ทำงานบนอินสแตนซ์ปัจจุบันผ่าน Sidekiq API บอกให้หยุดรับงานใหม่ จากนั้นรอจนกว่ากระบวนการทั้งหมดจะไม่มีงานที่ใช้งานอยู่

นี่คือเชลล์สคริปต์ที่จะทริกเกอร์สคริปต์นั้นเมื่อถึงเวลาสิ้นสุดอินสแตนซ์:

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

เอกสาร SSM

ตอนนี้เราต้องการบางสิ่งที่จะเรียกใช้เชลล์สคริปต์นี้ นั่นคือสิ่งที่ตัวแทน SSM เข้ามา มันทำงานอย่างมีความสุขในพื้นหลัง รอให้เอกสารแสดงผ่าน SendCommand เพื่อบอกว่าต้องทำอย่างไร OurDocument สั่งให้ตัวแทนเรียกใช้สคริปต์การยุติ:

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

ฟังก์ชันแลมบ์ดา

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

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

ฟังก์ชัน Lambda นี้ต้องการการอนุญาตสองอย่าง (นอกเหนือจากการอนุญาตตามปกติของ Lambda) และนี่คือเอกสารนโยบาย IAM สำหรับสิ่งนั้น:

คุณอาจต้องเปลี่ยนชื่อเอกสารอีกครั้ง

ตะขอและกฎของเหตุการณ์

รออยู่ตรงนั้น - เราใกล้จะถึงแล้ว! คุณเหลือสองสิ่งที่ต้องทำ:สร้าง Cloudwatch Event และ Lifecycle Hook ขั้นแรก เหตุการณ์:

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

ปรับขนาด Sidekiq อย่างหมดจด

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

เมื่อเสร็จแล้ว ให้กลับไปที่คอนโซลการจัดการ EC2 และไปที่กลุ่มการปรับขนาดอัตโนมัติที่มีอินสแตนซ์ที่คุณต้องการจัดการ หลังจากคลิกที่ Lifecycle Hooks แท็บ คุณจะสามารถสร้างเบ็ดของเรามีลักษณะดังนี้:

ปรับขนาด Sidekiq อย่างหมดจด

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

นั่นมันแรป

คุณทำมัน! ตอนนี้คุณมีกลุ่มการปรับขนาดอัตโนมัติที่สามารถยุติอินสแตนซ์ของ Sidekiq ได้อย่างมีมนุษยธรรม สนุก!

ป.ล. เครดิตไปที่ awslabs สำหรับบทแนะนำที่เป็นประโยชน์อย่างยิ่งในการนำชิ้นส่วนเหล่านี้มารวมกัน