เนื่องจากไปทำการ review ปัญหาของระบบที่พัฒนาด้วย Elixir
พบว่าเจอปัญหา ACCEPT ERROR: :system_limit เมื่อมีผู้ใช้งานมากยิ่งขึ้น
โดยเมื่อสอบถามการแก้ไขแล้วคือ การเพิ่ม ulimit ของ Kernel OS ไปแล้ว
แต่ปัญหายังเกิดขึ้นเหมือนเดิม จะต้องทำอย่างไรดี ?
ก่อนอื่นต้องเข้าใจปัญหาก่อนคือ File Descriptor (FD)
โดยใน Linux นั้นในแต่ละ process ก่อนที่จะเข้าถึงไฟล์ หรือ resource ต่าง ๆ ของระบบ
จะทำการสร้างตัวเลข fd ขึ้นมาใน File descriptor table มาให้
เพื่อให้ process อ้างอิงหรือใช้งานผ่านตัวเลขนั้น ๆ
โดยที่ OS จะมีการกำหนด limit ของจำนวนตัวเลขของ FD ที่จะมีได้สูงสุดเท่าไร
ใช้งานผ่านคำสั่ง ulimit ได้เลย
ถ้าใช้งานเกินจะเกิด error ขึ้นมา ทั้งในระดับ System (OS) และ application เช่น
- Too many open files in system
- Too many open files
- Erlang VM out of file descriptors (EMFILE)
แสดงการทำงานดังรูป

ต่อจากนั้นกลับมาดูระบบงานพบว่ามี 3 level ให้จัดการ
เนื่องจากมีการใช้งาน Container เข้ามาในการ deploy ด้วย
โดยค่า ulimit ของแต่ละ layer จะไม่เกิน level ของ OS แน่นอน
ซึ่งเป็นค่าสูงสุดที่จะกำหนดได้นั่นเอง
แต่ว่าในแต่ละส่วนก็จะมีค่า default ด้วยเช่นกัน ซึ่งต้องตรวจสอบเสมอ
แสดงดังรูป

จากปัญหาที่พบเจอคือ
ทำการกำหนดใน OS layer แล้ว (ok)
ทำการกำหนดใน Container แล้ว (ok)
แต่ยังไม่ทำการกำหนดใน layer ของ process
ซึ่ง Elixir นั้นใช้ Erlang ซึ่งมี BEAM (Virtual machine)
ทำการจัดการ process และ gc ต่าง ๆ ให้
ดังนั้นจำเป็นต้อง config ที่ระดับนี้ด้วย เพิ่ม “+Q” เข้ามา
สามารถทำการตรวจสอบง่าย ๆ ด้วย
ยกตัวอย่างเช่น การจัดการใน docker compose
หรือลองเปลี่ยนค่า +Q น้อย ๆ เช่น 1000
แล้วทำการเขียน shell script ยิงง่าย ๆ และตรวจสอบ log ได้เลย ดังนี้
จะเจอ error log ประมาณนี้ แสดงว่ามาถูกทางแล้ว
เพียงเท่านี้ก็สามารถบรรเทาปัญหาในระดับหนึ่งได้แล้ว
โดยเรื่องนี้เป็นหนึ่งในความรู้พื้นฐาน ที่ใช้กับทุก ๆ software นั่นเอง
Reference websites