การจัดการ Load Balance ใน Kong
หนึ่งในหน้าที่หลักของ API Gateway คือ การทำ Load Balance ดังนั้นในบทความนี้จะอธิบายว่าถ้าเราอยากได้การกระจาย Load(Load Balance) ใน Kong เราจะต้องทำยังไงบ้าง
Load Balancer คืออะไร
Load Balancer คือ Engine ที่ทำหน้าที่กระจาย Load ออกไปยัง service ปลายทางที่มีมากกว่า 1 service
ถ้าเรารับ request เข้ามาแล้วส่งออกไปที่เดียวอันนี้เรียกว่า reverse proxy แต่ถ้าเราต้องการจะกระจาย Load ออกไปมากกว่า 1 ที่เราจะใช้ Load Balancer
การทำงานของ Load Balancer จะขึ้นอยู่กับ Algorithm ที่เราเลือก ซึ่งใน Kong จะ support algorithm ต่างๆ ดังนี้
-
round-robin อันนี้เป็น algorithm ที่ง่ายที่สุดคือไล่เรียงคิวไปเรื่อยๆ เริ่มจาก service ที่ 1, 2 และ 3(เรียงตามลำดับใน targets) เมื่อกระจาย load ครบทุก service แล้วก็จะวนกลับมาที่ service แรกใหม่
Load balancer ใน Kong จะใช้ round-robin เป็น default
-
consistent-hashing การใช้ algorithm นี้จะต้องใส่ input ที่ต้องการ hash เข้ามา เพราะเราต้องการ input อะไรซักอย่างที่ unique เข้ามา hash เพื่อใช้เป็นตัวเลือก โดยใน Kong จะมีตัวเลือกให้เรา ดังนี้ none, consumer, ip, header และ cookie
ถ้าเราใส่ ip เข้ามาเป็น input จะทำให้เครื่องที่มี ip เดิม จะถูกกระจาย load เข้าที่ target เดิม
ถ้าเราเลือก none Kong จะกลับไปเลือกใช้ round-robin แทน
-
least-connection algorithm นี้จะนับจำนวน connection ถ้า target ไหนมี connection น้อยที่สุด ก็น่าจะว่างงานที่สุด
-
latency ใน algorithm นี้จะใช้ upstream_response_time ของ target เป็นตัวตัดสินใจ target ไหนมี response time ต่ำที่สุดก็จะได้รับ load ไป
ข้อควรระวังของ algorithm คือต้องใช้กับ service ที่มี response type แบบเดียวกัน เช่น เป็น JSON ทั้งหมด เพราะการมี response ที่ต่างกัน เช่น รูปภาพ และ video มี latency(เวลาที่ใช้ในการ load content) ไม่เท่ากัน ซึ่งจะทำให้การกระจาย load ไม่ balance
Upstreams และ Targets
ในการสร้าง route และ service ใน Gateway จะเป็นการระบุ service ปลายทางแค่ตัวเดียว แต่ถ้าต้องการจะระบุ upstream services มากกว่า 1 ตัว(Load Balancer) เราจะต้องสร้างเป็น upstream และ targets โดยที่เราต้องกำหนด
- Targets เป็นการระบุที่อยู่ของ upstreaming service แต่ละตัว โดยที่ต้องกำหนด url และ weight(ยิ่งกำหนด weight มาก Load Balancer ก็จะส่ง request เข้ามาที่ service นี้มาก)
- Upstreams จะเป็นการรวบรวม tagets ให้อยู่ภายใต้ service เดียวกัน และเราจะระบุ algorithm ในการกระจาย load เข้าไปยัง target แต่ละตัว
ตัวอย่าง kong.yml(การ Config Kong แบบ Declarative) ซึ่งแสดงความสัมพันธ์ตามรูปด้านบน
|
|
จากในตัวอย่างนี้ route จะรับทุก path ส่งต่อเข้าไปยัง service ชื่อ login-service และ service นี้จะระบุ host เป็นชื่อ upstreams(login-service.upstream) โดยปกติตรงนี้จะระบุ host ของ service ปลายทาง
และหลังจากนั้น upstreams ก็จะกระจาย load(ด้วย round-robin algorithm) ไปยัง target 2 ตัวคือที่ ip 10.130.12.43:8080 และ 10.130.12.164:8080 โดยที่มีน้ำหนักเท่ากัน คือจะได้ traffic ไปคนละครึ่ง
ในตัวอย่างนี้ใช้ Kong Configuration แบบ DBless เพื่อให้เห็นความสัมพันธ์ของ routes, services, upstreams และ targets คุณอาจไปสร้าง unstream ด้วย API, Kong Manager หรือ Konga ก็ได้
การทำ Health Check
สิ่งที่ต้องอยู่คู่กับการทำ Load Balance คือการทำ liveness หรือ health check เพราะว่า load balancer ต้องรู้ว่า service ปลายทาง(target) นั้นยังทำงานอยู่หรือไม่เพราะตอนกระจาย load ไปให้จะได้ไม่ error ดังนั้นในขั้นตอนต่อจากนี้เราจะทำการใส่ health check เข้าไปยัง target แต่ละตัวกัน
ซึ่ง Kong จะมี 2 วิธีในการทำ health check คือ
1. Active Health Check
การทำ health check แบบ active นั้น Kong จะทำเหมือนตัวเองเป็น client และส่ง request เข้าไปที่ target ถ้าไม่ได้ผลลัพธ์กลับมา หรีือมี http status ที่เรานิยามว่าเป็น unhealthy Kong จะถืิอว่า service ตัวนั้น unavailable
|
|
ในตัวอย่างนี้เราระบุว่าถ้า http status ตอบกลับมาเป็น 429,404,500-505 หรือไม่ตอบกลับมาภายใน 5 วินาที(timeout) เกิน 5 ครั้ง(http_failures) จะถือว่า target นั้นเป็น unhealthy
2. Passive Health Check
การทำ health check แบบ passive นั้น Kong จะไม่ส่ง request เข้าไปที่ target โดยตรงแต่จะใช้ค่าที่ได้จาก Log หรือ metrics ของ backend มาเป็นตัวตัดสินใจแทน
|
|
ในตัวอย่างนี้ถ้า เกิดใน Log มี http status 429,404,500-505 เกิน 5 ครั้งแสดงว่า target นี้เป็น unhealthy
3. Hybrid Health Check
ซึ่งจากการทำ Health Check ทั้งแบบ Active และ Passive นั้นต่างมีข้อดีและข้อเสีย ซึ่งเราจะเห็นว่าการทำ health check แบบ Active นั้นน่าจะได้ผลที่ดีกว่าการทำ Passive แต่ปํญหาของการทำ health check แบบ Active คือระบบจะรองรับ traffic มากๆไม่ได้ เนื่องจาก Kong ต้องใช้ timmer ในการตั้งเวลาเพื่อส่ง request ไปยัง target
ดังนั้นในการทำ Health Check เราสามารถใส่ทั้ง Active และ Passive เข้าไปพร้อมๆกันแบบนี้ได้เลย
|
|
การทำงานแบบ Hybrid Health Check จะเริ่มต้นจาก Passive Health Check ก่อนหลังจากที่ Kong พบว่า Target นั้นเป็น unhealthy Kong จะเปลี่ยนมาใช้ Active Health Check ตรวจสอบที่ target นั้นเลยว่าพร้อมใช้งานได้รึยัง และ Kong จะทำ Active Health Check ไปเรื่อยๆจนกว่า target นั้นจะกลับมาใช้งานได้
ข้อดีของการใช้ Hybrid Health Check คือ
- การใช้ Passive Health Check ใช้ resource น้อยกว่า Active(Passive more efficient) เพราะใช้การ Monitor response code ซึ่งเป็นสิ่งที่วิ่งผ่าน Gateway อยู่แล้ว
- การ Scale ทำได้ง่ายกว่า(Scalability) เพราะ Passive Health Check ใช้ resource น้อยกว่า Active เลยทำให้สามารถเพิ่มจำนวน service หลังบ้านได้มากขึ้น(เราจะเพิ่ม target ไปอีกกี่ตัวก็ไม่ได้มีผลต่อ Performance มากนัก) แต่ถ้าเป็น Active Health Check การเพิ่ม target เข้าไปจะเป็นการเพิ่มภาระให้กับ Kong โดยตรง
- หลังจาก target เปลี่ยนสถานะเป็น unhealthy แล้วการใช้ Active Health Check จะทำให้รู้ว่า target กลับมาทำงานได้เร็วกว่า(Fast recovery)