Triển khai api gateway cho microservice với Kong
- Kong là gì ? Tại sao phải dùng nó ?
Thử tưởng tượng bạn có 1 hệ thống như mô hình bên dưới:
Mỗi khi có nhu cầu, client sẽ gọi 1 request http tới 1 endpoint nào đó để lấy dữ liệu. Ví dụ như danh sách sản phẩm chúng ta có
GET /product HTTP/1.1
Hoặc khi cần thêm một sản phẩm vào cơ sở dữ liệu:
POST /product HTTP/1.1
Chúng ta khá thoải mái để lấy thông tin cần thiết từ server chỉ cần biết endpoint là gì. Bạn cần lấy thông tin user đăng nhập ? Bạn gọi api lấy thông tin người dùng; bạn cần thông tin đơn hàng ? Bạn gọi api lấy thông tin đơn hàng. Không có gì đơn giản hơn thế.
Có một vấn đề tiềm ẩn ở đây và nó chỉ xảy ra khi hệ thống của chúng ta mở rộng không kiểm soát và buộc chúng ta phải chuyển sang mô hình microservice ( Sau khi đã cân nhắc đầy đủ về ưu và nhược điểm) hoặc bạn có một danh sách dài các api cho nghiệp vụ của hệ thống. Lúc này sơ đồ giao tiếp của client và server sẽ trông như thế này:
Sau khi xem hình minh họa thì có lẽ bạn nên nghỉ ngơi một chút rồi đọc tiếp :D
Vấn đề ở đây không chỉ là số lượng api/service, nếu cứ kết nối chéo một các tự do như vậy, bạn sẽ làm gì nếu chúng ta phải thay thế server hoặc horizontal scaling cho một vài service ? Chính xác là bạn phải đi cập nhật code ở tất các những nơi gọi đến các service đó ! Nghĩ đã thấy kinh rồi!
Để giải quyết rắc rối này chúng ta có “API Gateway” !
Có thể kể đến một vài tên tuổi như: NginxPlus, AWS API Gateway, Kong …
Cá nhân mình chọn Kong vì đầu tiên là nó miễn phí :D Ngoài ra Kong còn có 1 số plugin rất hay giúp việc triển khai microservice nhẹ nhàng hơn rất nhiều như authenticate, cors, caching, transformer request …
- Sử dụng Kong như thế nào ?
a. Đầu tiên chúng ta cần cài đặt Kong
Có nhiều cách để cài đặt Kong, tuy nhiên theo trào lưu thì tôi sẽ sử dụng container cho nhẹ nhàng.
Trước đó các bạn cần:
- Docker
- Cuối cùng là 1 đường truyền internet :D
Theo như hướng dẫn trên trang chủ: https://docs.konghq.com/install/docker/?_ga=2.147747959.133277498.1534086219-1868463842.1534086219
Để chạy được Kong thì chúng ta phải có:
- database: cassandra hoặc postgres
- migration
- kong
Bạn có thể làm theo hướng dẫn install của trang chủ.
Hoặc bạn cũng có thể đùng docker-compose như sau:
version: ‘3’
services:
db:
image: cassandra:3
ports:
— 9042:9042
kong-migration:
image: kong:latest
environment:
KONG_DATABASE: cassandra
KONG_CASSANDRA_CONTACT_POINTS: db
command:
— kong
— migrations
— up
restart: on-failure
kong:
image: kong:latest
environment:
KONG_DATABASE: cassandra
KONG_CASSANDRA_CONTACT_POINTS: db
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: 0.0.0.0:8001
KONG_ADMIN_LISTEN_SSL: 0.0.0.0:8444
KONG_PROXY_LISTEN: 0.0.0.0:8000
KONG_PROXY_LISTEN_SSL: 0.0.0.0:8443
ports:
— 8000:8000
— 8443:8443
— 8001:8001
— 8444:8444
restart: on-failure
Vì Kong migration phải đợi database sẵn sàng và kong thì phải đợi kong migration đã chạy xong, vì vậy chúng ta phải thêm restart: on-failure để container tự reset.
Kiểm tra xem kong đã hoạt động chưa:
docker ps
Tuyệt vời! Thử trên trình duyệt nào:
http://localhost:8000 hoặc <machine-ip>:8000
Kong Admin
Vậy là đã cài đặt xong! Xung phong ! 4fun tí, chiến tiếp thôi các bạn :D
b. Config kong
Các bạn có thể lựa chọn sử dụng api của kong admin để config hoặc các tool UI như kong-dashboard hoặc konga. Trong bài viết này tôi sử dụng konga
Thêm konga vào docker-compose.yml
konga:
image: pantsel/konga
ports:
— 1337:1337
Giả sử hệ thống của chúng ta có các service sau:
Đăng ký user: http://mockapi/register
Login: http://mockapi2/login
Lấy thông tin user hiện tại: http://mockapi3/me
Các service này độc lập và được triển khai trên các server vật lý khác nhau.
Đầu tiên chúng ta sẽ tạo ra các kong service (đối tượng trừu tượng trỏ tới các service nghiệp vụ)
Tương tự như vậy chúng ta sẽ có services /login và /me
Bước tiếp theo là tạo các route: các quy tắc để kong match request với các service
Thử một request nhé:
Vậy là chúng ta đã tạo thành công api gateway. Request /register tới kong đã “upstream” tới mockapi. Tương tự với các services còn lại.
Api /me cần login để có thể lấy được thông tin. Thông thường chúng ta hay sử dụng Oauth2 hoặc Jwt để authen. Vậy làm thế nào để các service validate được token ?
Câu trả lời là Kong plugin.
Config plugin JWT cho service /me
Thử request nào
Ngon lành! Kong đã bắt chúng ta đăng nhập
Để đăng nhập thì đầu tiên chúng ta phải tạo user đăng nhập. Chính là Kong consumer, nếu bạn có services register, thì sau khi đăng kí, service register phải gọi api kong để tạo consumer.
Tạo credential JWT cho consumer vừa tạo
vào trang https://jwt.io/ để lấy token hợp lệ
iss: ứng với key của credential
secret: secret của credential
Thử lại nào:
Tuyệt vời !
Vậy là chúng ta đã hoàn tất một ví dụ config đơn giản cho Kong.
Hy vọng bài viết này sẽ giúp ích cho các bạn.
Thân ái và quyết thắng.