สำหรับผู้ที่ได้อ่านเกี่ยวกับคอนเทนเนอร์และ Docker แล้วแต่ไม่เข้าใจว่า Java เชื่อมโยงกับคอนเทนเนอร์ได้อย่างไร ก่อนอื่น มารีเฟรชหน่วยความจำของเราเกี่ยวกับหน่วยความจำ Java กัน ก่อน ฉันขอเตือนคุณว่าหน่วยความจำประกอบด้วย Stack และ Heap ซึ่งใช้ RAM (หน่วยความจำเข้าถึงโดยสุ่ม) ของเซิร์ฟเวอร์ เมื่อพูดถึงหน่วยความจำเพิ่มเติม เราจะหมายถึง RAM ทีนี้มาดูคอนเทนเนอร์แบบหน้าตัดกัน ไม่ ไม่แน่นอน เราไม่สนใจก้นและต้นขา เราจะดูที่โครงสร้างความจำในคอนเทนเนอร์ดีกว่า มันสามารถแบ่งออกเป็นสามส่วน: • หน่วยความจำฮีป – ฮีปนั้นเอง; • Off Heap คือทุกสิ่งที่ไม่อยู่ในฮีป • OS Overhead คือโอเวอร์เฮดของหน่วยความจำสำหรับการดำเนินการกระบวนการต่างๆ ภายในคอนเทนเนอร์ สมมติว่า: เราได้จัดสรร 1 Gb ให้กับคอนเทนเนอร์ โดยในรูปจะเป็นContainer Limit - ขอบเขตของมันจะระบุด้วยสี่เหลี่ยมสีน้ำเงิน เราจัดสรร 80% นั่นคือ 0.8 Gb สำหรับหน่วยความจำ Java ในคอนเทนเนอร์และHeapเอาเราไปประมาณ 80% ของคอนเทนเนอร์นั่นคือไม่น้อยกว่า 0.8 Gb มากนักเนื่องจากOS Overhead เป็นส่วนหนึ่งของทรัพยากร (โอเวอร์เฮด) สำหรับการรักษากระบวนการ เหลือประมาณ 20% ของคอนเทนเนอร์สำหรับทุกสิ่งที่ไม่ได้เชื่อมต่อกับฮีป ( Off Heap ) พื้นที่ที่ใช้ในรูปแสดงพื้นที่หน่วยความจำที่ใช้สำหรับการรันแอปพลิเคชัน ตอนนี้เราต้องพูดถึงสถานการณ์ที่หน่วยความจำในคอนเทนเนอร์อาจหมด OutOfMemoryError หากการใช้หน่วยความจำของแอปพลิเคชัน ( พื้นที่ที่ใช้ ) ถึงขีดจำกัดฮีป ( Heap ) เราจะตรวจจับOutOfMemoryError (ข้อผิดพลาด OOM) ซึ่งบอกว่ามีพื้นที่ในฮีปไม่เพียงพอ กล่าวคือ ในพื้นที่หน่วยความจำซึ่งออบเจ็กต์ที่สร้างขึ้นโดยทางโปรแกรมในแอปพลิเคชันถูกวางไว้ หากยังไม่ชัดเจนฉันจะอธิบายเป็นแมว OOM Error คือการที่แมวกรีดร้องอยู่หน้าประตูระเบียงเป็นเวลานาน และเมื่อประตูนี้ถูกเปิด มันจะยืนอยู่ที่ทางเข้าประตูและไม่ไปทางใดทางหนึ่ง พวกเขามักจะบอกว่าแมวถูกแช่แข็ง หากคุณผลักเขาทันเวลา เขาจะอ้าปากค้างและไปที่ระเบียงเพื่อทำธุรกิจเกี่ยวกับลูกแมว OOM Killer นี่เป็นอีกสถานการณ์หนึ่งที่อาจเกิดขึ้นในคอนเทนเนอร์เมื่อหน่วยความจำหมด หากโปรแกรมออกไปนอกคอนเทนเนอร์ เราจะได้OutOfMemory Killer (OOM Killer)ซึ่งเป็นกระบวนการที่จะยุติแอปพลิเคชันเพื่อป้องกันไม่ให้เคอร์เนลเสียหาย มันเสียสละแอปพลิเคชันเพื่อให้คอนเทนเนอร์ทำงานต่อไป ไม่ใช่ความจริงที่ว่าคอนเทนเนอร์จะพัง แต่แอปพลิเคชันที่ทำงานอยู่ในนั้นจะพังอย่างแน่นอน สิ่งนี้จะเกิดขึ้นหากคุณปล่อยให้การใช้หน่วยความจำของแอปพลิเคชัน Java ไม่ได้รับการควบคุม อีกครั้งเกี่ยวกับแมว หากคุณตัดสินใจที่จะนอนให้นานขึ้นในวันเสาร์และลืมให้อาหารแมวOOM Killerรับประกันดอกครับ กระถางอาจไม่เสียหาย แต่ดอกต้องปลูกใหม่ครับ ความแตกต่างระหว่าง OOM Error และ OOM Killer คืออะไร คุณสามารถประมวลผล ข้อผิดพลาด OOMและดำเนินการบางอย่างได้ (เช่น ปรับขนาดแอปพลิเคชัน) และOOM Killerจะฆ่ากระบวนการทั้งหมด OOM Killerนั้นคล้ายคลึงกับkill-9 (kill ลบ เก้า) - คำสั่งที่ฆ่ากระบวนการในLinux ประเด็นก็คือการใช้งานคอนเทนเนอร์ที่ได้รับความนิยมมากที่สุดคือ คอนเทนเนอร์ Dockerซึ่งใช้Linuxแม้ว่าคุณจะเรียกใช้ภายใต้Windows เคอร์เนลก็จะยังมาจากLinux ใน Linux เรามีความสนใจในแนวคิดหนึ่ง: CGgroups (กลุ่มควบคุมภาษาอังกฤษ) - กลไกเคอร์เนล Linux ที่จำกัดและแยกทรัพยากรการประมวลผล (โปรเซสเซอร์ เครือข่าย ทรัพยากรหน่วยความจำ ทรัพยากร I/O) สำหรับกลุ่มของกระบวนการ พูดง่ายๆ ก็คือ กลไกนี้ช่วยให้คุณจัดการทรัพยากรในคอนเทนเนอร์ในหน่วยความจำเคสของเราได้ Java เกี่ยวข้องกับสิ่งนี้อย่างไร? ผ่าน กลไกCGgroupsที่ Java สามารถเชื่อมโยงกับหน่วยความจำคอนเทนเนอร์ได้ แต่ทั้งหมดนี้ขึ้นอยู่กับเวอร์ชันของ Java ตัวอย่างเช่นJava 7ไม่ทราบวิธีใช้CGgroupsและไม่ทราบขีดจำกัดของคอนเทนเนอร์ ตามค่าเริ่มต้นขนาดฮีปสูงสุด = ¼หน่วยความจำกายภาพ หากแอปพลิเคชันเกินขีด จำกัด ของคอนเทนเนอร์ก็จะมีOOM Killerและหากไม่ได้ตั้งค่าขีด จำกัด ของคอนเทนเนอร์แอปพลิเคชันจะใช้หน่วยความจำจากแอปพลิเคชันอื่นบนเซิร์ฟเวอร์ (ควรกำหนดขีด จำกัด จะดีกว่ามิฉะนั้นทุกคนจะสูญเสีย) . แน่นอนคุณสามารถใช้ การตั้งค่า ฮีปหรือใช้ "รูปภาพ" พิเศษที่ช่วยแก้ปัญหานี้ได้ แต่วิธีที่ง่ายที่สุดคือใช้ Java เวอร์ชันที่ถูกต้อง เวอร์ชันที่ถูกต้องเริ่มต้นด้วยJava 8 x131 ( พอร์ตจาก Java 9) เริ่มเข้าใจCGgroups และในJava 10การสนับสนุนคอนเทนเนอร์ปรากฏขึ้น: UseContainerSupportหลังจากนั้นฟังก์ชันนี้ถูกย้ายไปยังJava 8 x 191 หรือคุณสามารถใช้Java: 11+ สรุปได้อะไรบ้าง: เมื่อใช้หน่วยความจำคอนเทนเนอร์ คุณอาจได้รับ OutOfMemoryError (ข้อผิดพลาด OOM) หรือ OutOfMemoryKiller (OOM Killer) ในกรณีแรก แอปพลิเคชันจะไม่ขัดข้องทันที สามารถตรวจพบข้อผิดพลาด OOM ประมวลผลและควบคุมการดำเนินการได้ ตัวอย่างเช่น ปรับขนาดแอปพลิเคชัน หาก OOM Killer เกิดขึ้น แอปพลิเคชันจะหยุดทำงานทันที และไม่มีตัวเลือกเหลือให้บันทึก และสิ่งที่แย่ที่สุดคือภายนอกภาชนะจะไม่เป็นไรนั่นคือคุณอาจไม่สงสัยด้วยซ้ำว่ามีบางอย่างตกลงไปที่นั่น กลไก Linux ใช้เพื่อโต้ตอบกับคอนเทนเนอร์และหน่วยความจำ Java แต่ไม่ใช่ทุก Java ที่จะนำไปใช้ เพื่อหลีกเลี่ยงปัญหาสำหรับ Java 8 คุณต้องใช้เวอร์ชันที่เริ่มต้นจาก 131 หรือดีกว่าคือจาก 191 หรือใช้ Java: 11+ สำหรับการฝึกฝน: OutOfMemoryError: จับให้ได้ถ้าทำได้
Павел
ระดับ
GO TO FULL VERSION