บ่อยครั้งมาก 'ไฟล์ที่เปิดมากเกินไป ’ เกิดข้อผิดพลาดบนเซิร์ฟเวอร์ Linux ที่มีโหลดสูง หมายความว่ากระบวนการเปิดไฟล์จำนวนมากเกินไป (ตัวอธิบายไฟล์) และไม่สามารถเปิดไฟล์ใหม่ได้ ใน Linux ขีดจำกัดสูงสุดของไฟล์ที่เปิดอยู่จะถูกตั้งค่าเริ่มต้นสำหรับแต่ละกระบวนการหรือผู้ใช้ และค่าค่อนข้างน้อย
ในบทความนี้ เราจะเรียนรู้วิธีตรวจสอบขีดจำกัดปัจจุบันของจำนวนไฟล์ที่เปิดสูงสุดใน Linux และวิธีเปลี่ยนสำหรับโฮสต์ทั้งหมด บริการแต่ละรายการ หรือเซสชันปัจจุบัน
ข้อผิดพลาด "ไฟล์ที่เปิดมากเกินไป" และข้อจำกัดการเปิดไฟล์ใน Linux
ก่อนอื่น มาดูกันว่าข้อผิดพลาด 'ไฟล์ที่เปิดมากเกินไป' ปรากฏขึ้นที่ใด มักเกิดขึ้นบนเซิร์ฟเวอร์ที่ติดตั้งเว็บเซิร์ฟเวอร์ NGINX/httpd หรือเซิร์ฟเวอร์ฐานข้อมูล (MySQL/MariaDB/PostgreSQL) เมื่ออ่านบันทึกจำนวนมาก ตัวอย่างเช่น เมื่อเว็บเซิร์ฟเวอร์ Nginx เกินขีดจำกัดไฟล์ที่เปิด คุณจะเห็นข้อผิดพลาด:
socket () failed (29: Too many open files) while connecting to upstream
เมื่อใช้คำสั่งนี้ คุณจะได้รับ file descriptor จำนวนสูงสุดที่ระบบของคุณสามารถเปิดได้:
# cat /proc/sys/fs/file-max
ขีดจำกัดไฟล์ที่เปิดสำหรับผู้ใช้ปัจจุบันคือ 1024 คุณสามารถตรวจสอบได้ดังนี้:
# ulimit -n
ขีดจำกัดมีสองประเภท:ยาก และ นุ่ม . ผู้ใช้สามารถเปลี่ยนขีดจำกัดซอฟต์ได้ (อย่างไรก็ตาม ค่าซอฟต์ต้องไม่เกินค่าฮาร์ด) เฉพาะผู้ใช้ที่มีสิทธิพิเศษหรือผู้ใช้รูทเท่านั้นที่สามารถแก้ไขค่าฮาร์ดลิมิตได้
หากต้องการแสดงขีดจำกัดซอฟต์ ให้รันคำสั่งนี้:
# ulimit –nS
วิธีแสดงค่าฮาร์ดลิมิต:
# ulimit -nH
จะเพิ่มขีดจำกัดไฟล์เปิดสูงสุดใน Linux ได้อย่างไร
ในการอนุญาตให้บริการทั้งหมดเปิดไฟล์จำนวนมากได้ คุณสามารถเปลี่ยนขีดจำกัดใน Linux OS ของคุณได้ หากต้องการให้การตั้งค่าใหม่เป็นแบบถาวรและป้องกันการรีเซ็ตหลังจากเซิร์ฟเวอร์หรือเซสชันเริ่มใหม่ คุณต้องทำการเปลี่ยนแปลงใน /etc/security/limits.conf . เพิ่มบรรทัดเหล่านี้:
* hard nofile 97816 * soft nofile 97816
หากคุณกำลังใช้ Ubuntu ให้เพิ่มบรรทัดนี้ด้วย:
session required pam_limits.so
พารามิเตอร์นี้อนุญาตให้ตั้งค่าขีดจำกัดของไฟล์ที่เปิดหลังจากการตรวจสอบผู้ใช้
หลังจากทำการเปลี่ยนแปลงใดๆ ให้โหลดเทอร์มินัลใหม่และตรวจสอบค่า max_open_files:
# ulimit -n
97816
การเพิ่มขีดจำกัด Open File Descriptor ต่อบริการ
คุณสามารถเปลี่ยนขีดจำกัดของตัวอธิบายไฟล์ที่เปิดอยู่สำหรับบริการเฉพาะ แทนที่จะเป็นสำหรับระบบปฏิบัติการทั้งหมด ลองใช้ apache เป็นตัวอย่าง เปิดการตั้งค่าบริการโดยใช้ systemctl:
# systemctl edit httpd.service
เพิ่มขีดจำกัดที่คุณต้องการ เช่น:
[Service] LimitNOFILE=16000 LimitNOFILESoft=16000
หลังจากทำการเปลี่ยนแปลงแล้ว ให้อัปเดตการกำหนดค่าบริการและเริ่มต้นใหม่:
# systemctl daemon-reload
# systemctl restart httpd.service
เพื่อให้แน่ใจว่าค่าต่างๆ เปลี่ยนไป ให้เรียกใช้บริการ PID:
# systemctl status httpd.service
ตัวอย่างเช่น PID ของบริการคือ 3724:
# cat /proc/3724/limits | grep "Max open files”
ดังนั้น คุณจึงได้เปลี่ยนค่าสำหรับจำนวนไฟล์ที่เปิดสูงสุดสำหรับบริการเฉพาะ
จะตั้งค่าขีดจำกัดไฟล์เปิดสูงสุดสำหรับ Nginx และ Apache ได้อย่างไร
เมื่อเปลี่ยนการจำกัดจำนวนไฟล์ที่เปิดสำหรับเว็บเซิร์ฟเวอร์ คุณต้องเปลี่ยนไฟล์การกำหนดค่าบริการด้วย ตัวอย่างเช่น ระบุ/เปลี่ยนค่าคำสั่งต่อไปนี้ในไฟล์การกำหนดค่า Nginx /etc/nginx/nginx.conf :
worker_rlimit_nofile 16000เมื่อกำหนดค่า Nginx บนเซิร์ฟเวอร์ 8-core ที่โหลดสูงด้วย worker_connections 8192 คุณต้องระบุ 8192*2*8 (vCPU) =131072 ใน worker_rlimit_nofile
จากนั้นรีสตาร์ท Nginx
สำหรับ Apache ให้สร้างไดเร็กทอรี:
# mkdir /lib/systemd/system/httpd.service.d/
จากนั้นสร้างไฟล์ limit_nofile.conf:
# nano /lib/systemd/system/httpd.service.d/limit_nofile.conf
เพิ่มเข้าไป:
[Service] LimitNOFILE=16000
อย่าลืมรีสตาร์ท httpd
เปลี่ยนขีดจำกัดไฟล์ที่เปิดสำหรับเซสชันปัจจุบัน
หากต้องการเปลี่ยนขีดจำกัดสูงสุดของไฟล์ที่เปิดสำหรับเทอร์มินัลเซสชัน ให้เรียกใช้คำสั่งนี้:
# ulimit -n 3000
หลังจากปิดเทอร์มินัลและสร้างเซสชันใหม่ ขีดจำกัดจะกลับไปเป็นค่าเดิมที่ระบุไว้ใน /etc/security/limits.conf .
วิธีเปลี่ยนค่าทั่วไปของระบบ /proc/sys/fs/file-max ให้เปลี่ยนค่า fs.file-max ใน /etc/sysctl.conf:
fs.file-max = 100000
และนำไปใช้:
# sysctl -p
ในบทความนี้ เราได้เรียนรู้วิธีแก้ปัญหาเมื่อค่า open file descriptor limit ใน Linux มีค่าน้อยเกินไป และได้พูดคุยถึงตัวเลือกบางประการในการเปลี่ยนขีดจำกัดเหล่านี้บนเซิร์ฟเวอร์