Sử dụng lambda + sqs làm hệ thống send message trên aws

August 20, 2019
Golang aws lambda sqs

Chắc hẳn các bạn đã từng làm các server với send message hoặc gửi email sử dụng queue, Các đó ổn tuy nhiên về hiệu năng với bài toán gửi cho số lượng lớn khoảng 1.000.000 end user nhận được message cùng lúc thì đó cũng là 1 bài toán khá đau đầu. Ở bài viết này mình xin giới thiệu sử dụng lambda function 1 service ngon bổ rẻ của aws chuyên để sử dụng dành cho các công việc như thế này. Ở đây mình sẽ sử dụng golang cho công việc send message này. Thật may là aws cũng hỗ trợ sẵn layer dành cho go.

Tổng quan

Trước hết mình sẽ mô tả qua về hoạt động của service này.

Mình muốn send message cho 1.000.000 end user cùng nhận được các message cùng 1 lúc. Thông thường công việc phải làm sẽ đẩy các jobs send message vào trong queue, Sau đó sử dụng tool supervisord và setup numprocs tạo ra nhiều worker. Các worker này sẽ có nhiệm vụ truy xuất vào redis đọc các queue và xử lý song song các queue đó. Tuy nhiên để send 1.000.000 message đồng thời tốn khá nhiều worker, dẫn tới các tài nguyên của server khó lòng đáp ứng đủ.

Tuy nhiên giải pháp đó có cách để khắc phục đó là sử dụng lambda + sqs. https://docs.aws.amazon.com/lambda/latest/dg/go-programming-model-handler-types.html. Cũng tương tự như cách trên nhưng thay vì push các queue vào redis chứa thì thay vào đó mình sẽ sử dụng sqs của aws. Các sqs này có nhiệm vụ nhận các job queue và trigger tới lambda. lambda xử lý gọn nhẹ và rất nhanh, hơn thế có cớ ché scaling có thể tùy ý tăng số lượng lambda để xử lý song song nhiều queue cùng lúc. Hơn nữa chi phí lambda khá là rẻ,

Pricing lambda free cho 1M request free, sau đó mỗi 1M request sẽ tính $0.2. Như vậy 1$ bạn sẽ có 6M request. có thể coi là chấp nhận được. Bạn đừng lo lắng nếu chi phí đắt. Nếu application của bạn có lượng end user nhiều như vậy thì mình tin rằng con số này chả là gì cả.

Tiến hành.

github.com/aws/aws-lambda-go/events github.com/aws/aws-lambda-go/lambda

2 thư viện trên là thư viện chính trong applicatin này

Trong file main.go của mình như sau

package main

import (
    "context"
    "errors"
    "fmt"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)


func Handler(ctx context.Context, sqsEvent events.SQSEvent) error {
    for _, msg := range sqsEvent.Records {
        // Send message with msg.Body
        fmt.Printf("Got SQS message %q with body %q\n", msg.MessageId, msg.Body)
    }
}

func main() {
    lambda.Start(Handler)
}

Trong function trên lambda đơn giản chỉ lắng nghe sự kiện được trigger từ sqs. lambda sẽ đọc các records từ sqs sau đó thực hiện actions send message. Trong ví dụ trên mình sẽ thay thể bằng log ra màn hình.

Setup trong aws.

Để đăng ký lambda trước tiên bạn cần login vào console của lambda sau đó register 1 lambda service. Sau khi đăng ký sau sẽ tới màn hình configuration

golang configuration

Tại dropdown trigger các bọn select và chọn sqs queue để trigger. Các bạn có thể tùy chọn nhiều trigger như API Gateway,.. đồng thời song song.

Như vậy là xong các bạn zip file source code của mình lại và upload lên lambda function. sau đó save lại.

Nhìn vào sơ đồ design ta có thể thấy bất cứ khi nào sqs có event thì lập tức sẽ được trigger tới lambda, và lambda sẽ thực hiện function send message như đã viết ở trên.

Công việc bây giờ của bạn chẳng cần làm gì chỉ cần push queue vào trong sqs việc còn lại đã có lambda xử lý. Tuyệt vời quá phải ko nào.