Coding Gun

การจัดการ 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 ต่างๆ ดังนี้

Upstreams และ Targets

ในการสร้าง route และ service ใน Gateway จะเป็นการระบุ service ปลายทางแค่ตัวเดียว แต่ถ้าต้องการจะระบุ upstream services มากกว่า 1 ตัว(Load Balancer) เราจะต้องสร้างเป็น upstream และ targets โดยที่เราต้องกำหนด

ตัวอย่าง kong.yml(การ Config Kong แบบ Declarative) ซึ่งแสดงความสัมพันธ์ตามรูปด้านบน

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
_format_version: "3.0"
_transform: true

routes:
- name: all-paths
  id: 4d00558f-9c29-4c00-bc28-eaf8a7b3c7fd
  service: b0fbe2ea-49b9-41a8-98d5-1d770f9a7d54
  paths:
  - /
  protocols:
  - http
  strip_path: false
services:
- id: b0fbe2ea-49b9-41a8-98d5-1d770f9a7d54
  name: login-service
  host: login-service.upstream
  path: /
  port: 80
  protocol: http
upstreams:
- name: login-service.upstream
  id: ccaf7511-37f6-458a-a676-cdf2d4f93dee
  algorithm: round-robin
targets:
- id: 1cb2af1f-454e-5205-a31e-c9a73ebc3fe2
  target: 10.130.12.43:8080
  upstream: ccaf7511-37f6-458a-a676-cdf2d4f93dee
  weight: 50
- id: 1122a7b2-86bd-4a1b-a712-45a8b0052860
  target: 10.130.12.164:8080
  upstream: ccaf7511-37f6-458a-a676-cdf2d4f93dee
  weight: 50

จากในตัวอย่างนี้ 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
upstreams:
- algorithm: round-robin
  id: ccaf7511-37f6-458a-a676-cdf2d4f93dee
  name: login-service.upstream
  healthchecks:
    active:
      http_path: /health
      healthy:
        http_statuses:
        - 200
        successes: 3
        interval: 10
      unhealthy:
        http_failures: 5
        tcp_failures: 5
        timeouts: 5
        http_statuses:
        - 429
        - 404
        - 500
        - 501
        - 502
        - 503
        - 504
        - 505
        interval: 5

ในตัวอย่างนี้เราระบุว่าถ้า 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 มาเป็นตัวตัดสินใจแทน

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
upstreams:
- algorithm: round-robin
  id: ccaf7511-37f6-458a-a676-cdf2d4f93dee
  name: login-service.upstream
  healthchecks:
    passive:
      healthy:
        http_statuses:
        - 200
        - 201
        - 202
        - 203
        - 204
        - 205
        - 206
        - 207
        - 208
        successes: 3
      type: http
      unhealthy:
        http_failures: 5
        http_statuses:
        - 429
        - 404
        - 500
        - 501
        - 502
        - 503
        - 504
        - 505
        tcp_failures: 5
        timeouts: 5

ในตัวอย่างนี้ถ้า เกิดใน 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 เข้าไปพร้อมๆกันแบบนี้ได้เลย

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
upstreams:
- algorithm: round-robin
  id: ccaf7511-37f6-458a-a676-cdf2d4f93dee
  name: login-service.upstream
  healthchecks:
    active:
      http_path: /health
      healthy:
        http_statuses:
        - 200
        successes: 3
        interval: 0
      unhealthy:
        interval: 5
    passive:
      healthy:
        http_statuses:
        - 200
        - 201
        - 202
        - 203
        - 204
        - 205
        - 206
        - 207
        - 208
        successes: 3
      type: http
      unhealthy:
        http_failures: 5
        http_statuses:
        - 429
        - 404
        - 500
        - 501
        - 502
        - 503
        - 504
        - 505
        tcp_failures: 5
        timeouts: 5

การทำงานแบบ Hybrid Health Check จะเริ่มต้นจาก Passive Health Check ก่อนหลังจากที่ Kong พบว่า Target นั้นเป็น unhealthy Kong จะเปลี่ยนมาใช้ Active Health Check ตรวจสอบที่ target นั้นเลยว่าพร้อมใช้งานได้รึยัง และ Kong จะทำ Active Health Check ไปเรื่อยๆจนกว่า target นั้นจะกลับมาใช้งานได้

ข้อดีของการใช้ Hybrid Health Check คือ

  1. การใช้ Passive Health Check ใช้ resource น้อยกว่า Active(Passive more efficient) เพราะใช้การ Monitor response code ซึ่งเป็นสิ่งที่วิ่งผ่าน Gateway อยู่แล้ว
  2. การ Scale ทำได้ง่ายกว่า(Scalability) เพราะ Passive Health Check ใช้ resource น้อยกว่า Active เลยทำให้สามารถเพิ่มจำนวน service หลังบ้านได้มากขึ้น(เราจะเพิ่ม target ไปอีกกี่ตัวก็ไม่ได้มีผลต่อ Performance มากนัก) แต่ถ้าเป็น Active Health Check การเพิ่ม target เข้าไปจะเป็นการเพิ่มภาระให้กับ Kong โดยตรง
  3. หลังจาก target เปลี่ยนสถานะเป็น unhealthy แล้วการใช้ Active Health Check จะทำให้รู้ว่า target กลับมาทำงานได้เร็วกว่า(Fast recovery)

อ่านต่อเพิ่มเติมได้ที่

Phanupong Permpimol
Follow me

Software Engineer ที่เชื่อในเรื่องของ Process เพราะเมื่อ Process ดี Product ก็จะดีตาม ปัจจุบันเป็นอาจารย์และที่ปรึกษาด้านการออกแบบและพัฒนา Software และ Web Security