upgrade nginx ยังไงไม่ให้มี downtime

การ upgrade software แต่ละครั้งหมายความว่าต้องมีการ restart software เพื่อให้ใช้งาน software version ใหม่ทุกครั้ง นั่นหมายความว่าจะต้องมี downtime เกิดขึ้นในระบบเสมอ

แต่สำหรับ software (หรือระบบ) ที่ออกแบบมาดี จะสามารถ upgrade แบบ in-place โดยไม่มี downtime เลยก็ยังได้ครับ

บทความนี้อ้างอิงถึง > คุณ Shutdown Nginx Container ใน Kubernetes ถูกวิธีอยู่รึเปล่า? < จากวงในครับ

nginx มีระบบควบคุม process ที่ออกแบบมาเพื่อให้สามารถสั่ง reload configuration, reopen log file รวมถึง upgrade binary ได้โดยไม่ต้อง restart เลยครับ โดยขั้นตอนการทำงานสภาพปกติของ nginx คือ

  1. เมื่อ start nginx จะสร้าง master process สำหรับสร้าง process ย่อย (worker process, cache manager, cache loader และอื่นๆ)
  2. master จะทำหน้าที่ monitor process ย่อยทั้งหมด ให้ตรงกับการตั้งค่าเสมอ

จากการออกแบบนี้ทำให้ nginx สามารถ “full reload” การตั้งค่าทั้งหมดได้ โดยเมื่อมีการสั่ง reload (ด้วย SIGHUP) ตัว master process จะสร้าง worker process ใหม่ขึ้นมา แล้วสั่งให้ worker process เดิมเลิกรับ connection ใหม่ โดยระหว่างนั้น connection เดิมจะทำงานที่ worker process เดิม จน connection ปิดหมด worker เดิมจึงจะตายไป โดย worker จะยังใช้ binary เดิม

นอกจากนี้สำหรับการ upgrade nginx จะมี signal พิเศษอีกตัว (SIGUSR2) แต่ใช้งานลำบากนิดหน่อยครับ ดังนี้

  1. จด pid ของ nginx master process เดิม ไว้ โดยปกติจะอยู่ใน /var/run/nginx.pid หรือสั่ง ps ax|grep nginx:\ master ดูได้
  2. สั่ง kill -USR2 <pid> เพื่อสั่งให้ nginx สร้าง master process ใหม่ด้วย binary ใหม่ ณ ตอนนี้ nginx จะมี worker ที่ทำงานอยู่พร้อมกันทั้ง 2 version
  3. สั่ง kill -QUIT <pid> เพื่อสั่งให้ nginx version เก่าจบการทำงาน โดยจะเข้ากระบวนการ graceful shutdown (รอ connection ค้างทำงานจนเสร็จ) ตามปกติครับ
Show your support

Clapping shows how much you appreciated icez network’s story.