Giới thiệu
Nền tảng điện toán serverless thật tuyệt vời nhưng nếu không có cơ sở dữ liệu serverless thì chúng quá hạn chế.
Trong khi xây dựng nền tảng cho khóa học sắp tới của mình, Các thành phần của CI/CD, tôi muốn có một cơ sở dữ liệu phi máy chủ vì tôi quyết định sử dụng AWS Lambda làm máy chủ cho một số thứ nhất định. Yêu cầu của tôi là:
- Định giá theo mức sử dụng . Tôi không muốn trả tiền theo giờ hoặc theo nút mà theo mức sử dụng (yêu cầu, dung lượng lưu trữ, v.v.). Sẽ rất rẻ khi bắt đầu sử dụng nó và khi mức sử dụng tăng lên thì chi phí sẽ tăng theo tỷ lệ.
- Độ trễ thấp . Không ai thích phản hồi chậm, vì vậy việc truy vấn cơ sở dữ liệu phải nhanh từ bên trong các khu vực AWS (ví dụ:
eu-west-1). - Trải nghiệm tuyệt vời dành cho nhà phát triển (DevX) . Ưu tiên có một giao diện đẹp cho cơ sở dữ liệu mà không cần phải tìm hiểu thêm một DSL thích hợp nào khác hoặc lãng phí hàng giờ để loay hoay với một trang web.
Upstash Redis đáp ứng tất cả các yêu cầu trên và nó làm rất tốt việc đó.
- Thanh toán khi bạn di chuyển?
- ✅ Giá cả thực sự phải chăng để bắt đầu và trên quy mô lớn!
- Độ trễ thấp?
- ✅
<Độ trễ 1ms khi truy vấn từ bên trong AWS Lambda!
- ✅
- DevX tuyệt vời?
- ✅ Đó là Redis tiêu chuẩn. Đúng vậy.
Trong bài viết này, chúng ta sẽ tìm hiểu cách sử dụng Upstash Redis từ bên trong AWS Lambda, đảm bảo nó đủ nhanh cho nhu cầu của chúng ta, đồng thời giữ cho mã của chúng ta có thể duy trì được để có thể kiểm tra cục bộ hoặc triển khai sang một nền tảng khác nếu cần.
Chúng ta đang triển khai cái gì?
Để đơn giản, chúng tôi sẽ chỉ triển khai 3 điểm cuối API:
GET|POST /loginđiểm cuối chấp nhậnuserIddưới dạng tham số truy vấn trongGEThoặc bên trong giá trị biểu mẫu được gửi bằngPOSTyêu cầu. Điểm cuối này sẽ tạo ID phiên, lưu trữ nó trong Redis và cũng đặt cookie cho các lần truy cập tiếp theo.GETchỉ làm cho việc kiểm tra dễ dàng hơn.🙃- Số
GET /lessons/completedđiểm cuối yêu cầu người dùng đăng nhập (tức là có cookie với ID phiên) và trả về phản hồi JSON với tất cả các bài học mà người dùng đã hoàn thành và thời điểm hoàn thành. - Số
POST /lessons/{lessonSlug}/mark-completeđiểm cuối yêu cầu người dùng đăng nhập (tức là có cookie với ID phiên) và đánh dấu bài học được biểu thị bằnglessonSlugnhư đã hoàn thành với thời điểm hiện tại.
Lưu ý:Trong mã bên dưới có một số thứ bị thiếu, do đó đây không phải là mã có thể sao chép và dán sẵn sàng sản xuất. Ví dụ:chúng ta nên kiểm tra xem lessonSlug đã cho tồn tại trước khi cập nhật nó. Điểm cuối đăng nhập cũng phải chấp nhận mật khẩu và thực hiện xác minh muối/băm thích hợp trước khi tạo ID phiên, v.v.
1. Thiết lập
- Mã đầy đủ chi tiết bên dưới cũng tồn tại trong
aws-playgroundcủa tôi kho lưu trữ nếu bạn muốn xem mọi thứ khớp với nhau như thế nào.
Như bạn sẽ thấy bên dưới, chúng tôi đang tạo hai điểm vào, tức là hai lệnh thực thi. Một cái sẽ dành cho máy chủ cục bộ bình thường và một cái sẽ dành cho AWS Lambda. Bằng cách này, chúng tôi sẽ có thể kiểm tra toàn bộ logic của mình một cách cục bộ và bằng các thử nghiệm đơn vị/tích hợp tiêu chuẩn nếu chúng tôi muốn.
Sự khác biệt duy nhất giữa chúng được thể hiện trong phần 1.2 và 1.3 bên dưới.
1.1 Không gian làm việc
Trước khi đi sâu vào mã, hãy thiết lập thư mục làm việc cho Go.
- Tải xuống Go.
- Tạo tài khoản và cơ sở dữ liệu Upstash Redis ở khu vực bạn chọn. Lý tưởng nhất là khu vực AWS mà bạn sẽ triển khai Lambda của mình. Tôi sẽ sử dụng
eu-west-1(Châu Âu, Ireland) trong bài viết này.

Sau khi hoàn thành những điều trên, bây giờ chúng ta có thể tạo không gian làm việc của mình. Đối với phần còn lại của bài viết, giả sử mã của chúng tôi ở dưới ~/dev/aws-lambda-upstash-redis .
mkdir -p ~/dev/aws-lambda-upstash-redis
cd ~/dev/aws-lambda-upstash-redis Sau đó, tạo gói Go:
go mod init com.upstash/example/aws-lambda-upstash-redis 1.2 Điểm vào máy chủ cục bộ
- Dán đoạn mã sau vào
~/dev/aws-lambda-upstash-redis/cmd/server/main.go.
package main
import (
"log"
"net/http"
"os"
"com.upstash/example/aws-lambda-upstash-redis/core"
)
func main() {
mux := core.NewMux()
port := os.Getenv("PORT")
if len(port) == 0 {
port = "5000"
}
if err := http.ListenAndServe(":"+port, mux); err != nil {
log.Fatal(err)
}
} 1.3 Điểm vào AWS Lambda
- Dán đoạn mã sau vào
~/dev/aws-lambda-upstash-redis/cmd/lambda/main.go.
package main
import (
"com.upstash/example/aws-lambda-upstash-redis/core"
"github.com/aws/aws-lambda-go/lambda"
"github.com/awslabs/aws-lambda-go-api-proxy/httpadapter"
)
func main() {
mux := core.NewMux()
lambda.Start(httpadapter.NewV2(mux).ProxyWithContext)
} 1.4 Logic cốt lõi
Logic cốt lõi chính của chúng tôi sẽ đi vào core gói được chia sẻ bởi cả hai điểm truy cập ở trên.
- Dán đoạn mã sau vào
~/dev/aws-lambda-upstash-redis/core/lib.go.
package core
import (
"github.com/go-chi/chi/v5"
)
func NewMux() *chi.Mux {
r := chi.NewRouter()
return r
} 1.5 Xây dựng/Biên dịch
Tôi thường viết một makefile nhỏ để tránh phải gõ lệnh dài mỗi lần tôi muốn biên dịch, vì vậy hãy sao chép đoạn sau vào ~/dev/aws-lambda-upstash-redis/makefile :
default: build
clean:
rm -rf build/
build: build-lambda build-server
build-lambda: clean
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o build/handler cmd/lambda/main.go
cd build/ && zip handler.zip ./handler
build-server: clean
CGO_ENABLED=0 go build -o build/server cmd/server/main.go Bây giờ đừng lo lắng quá nhiều về các chi tiết nhưng điều này cho phép chúng tôi làm:
make build-server:Xây dựng hệ nhị phân để chạy máy chủ cục bộ (có thể thực thi./build/server).make build-lambda:Xây dựng tệp nhị phân để chạy máy chủ trên AWS Lambda (có thể thực thi./build/handlervà./build/handler.zip).makehoặcmake buildlàm cả hai.
CGO_ENABLED=0 tùy chọn đảm bảo các tệp nhị phân thực thi của chúng tôi được khép kín (tức là được biên dịch tĩnh). GOOS=linux GOARCH=amd64 cần có các tùy chọn để biên dịch chéo và khớp với môi trường linux của AWS Lambda trong trường hợp bạn đang sử dụng hệ thống Mac hoặc Windows cục bộ.
Tiếp theo, chạy go mod tidy để tìm nạp tất cả các phụ thuộc mã. Hãy nhớ chạy cái này mỗi khi bạn thêm hoặc xóa phần phụ thuộc của Go.
Cuối cùng, chạy make một lần, để xây dựng mọi thứ và đảm bảo không gian làm việc của bạn được thiết lập trước khi chúng ta đi sâu hơn vào mã.
2. Triển khai API
Đối với phần này, chúng tôi sẽ luôn làm việc bên trong ~/dev/aws-lambda-upstash-redis/core/lib.go tập tin.
Một số dòng sau đây xác định các điểm cuối API mà chúng ta đã thảo luận trước đó bằng cách sử dụng go-chi tuyệt vời thư viện.
import (
//...
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
func NewMux() *chi.Mux {
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Get("/login", login)
r.Post("/login", login)
r.Group(func(r chi.Router) {
r.Use(UsersWithSessionOnly)
r.Get("/lessons/completed", listLessonsCompleted)
r.Post("/lessons/{lessonSlug}/mark-complete", markLessonComplete)
})
return r
}
Trong đoạn trích trên, r.Group(...) tạo một lớp chia sẻ nơi chúng ta có thể áp dụng phần mềm trung gian phổ biến cho bất kỳ tuyến đường nào được xác định bên trong nó. Trong trường hợp này, chúng tôi thêm phần mềm trung gian UsersWithSessionOnly của riêng mình , như chúng ta sẽ thấy sau, đảm bảo rằng yêu cầu chứa cookie có ID phiên hoạt động.
2.1 Phần mềm trung gian UsersWithSessionOnly
Trong phần mềm trung gian này, chúng tôi muốn triển khai những điều sau:
- Trích xuất cookie chứa ID phiên và không thực hiện được.
- Truy vấn Redis để tìm nạp chi tiết người dùng dựa trên ID phiên và không thành công nếu ID phiên được cung cấp không hoạt động.
- Lưu trữ ID người dùng trong
context.Contextcủa yêu cầu để cung cấp cho phần mềm trung gian hoặc trình xử lý xuôi dòng.
Đầu tiên, chúng ta cần một số mã soạn sẵn cho một số nội dung nhập và định nghĩa được sử dụng ở mọi nơi.
import (
//...
"log"
"os"
"strings"
"github.com/go-redis/redis/v8"
)
type contextKey struct {
name string
}
const (
COOKIE_AUTH_NAME = "xxx_session_id"
)
var (
CTX_USER_ID = &contextKey{"LoggedInUserId"}
redisDb = NewClient()
)
func NewClient() *redis.Client {
redisUrl := strings.TrimSpace(os.Getenv("UPSTASH_REDIS_URL"))
if redisUrl == "" {
log.Fatalln("Required env UPSTASH_REDIS_URL not set!")
}
opt, _ := redis.ParseURL(redisUrl)
redisDb := redis.NewClient(opt)
return redisDb
} Và bây giờ là logic chính cho phần mềm trung gian xác thực.
// UsersWithSessionOnly middleware restricts access to just logged-in users.
// If validation passes, then the context will contain the user id (CTX_USER_ID).
func UsersWithSessionOnly(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
c, err := r.Cookie(COOKIE_AUTH_NAME)
if err != nil {
render.Status(r, http.StatusForbidden)
render.JSON(w, r, struct{}{})
return
}
ctx := r.Context()
userId, err := redisDb.Get(ctx, "session:"+c.Value).Result()
if err == redis.Nil {
// If session is not found then user is forbidden from accessing the API!
render.Status(r, http.StatusForbidden)
render.JSON(w, r, struct{}{})
return
} else if err != nil {
// Something went wrong querying Redis!
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, struct{ Message string }{Message: "We could not validate the provided session ID"})
return
}
// Set it for downstream middleware and handlers.
next.ServeHTTP(w, r.WithContext(context.WithValue(ctx, CTX_USER_ID, userId)))
})
} 2.2 markLessonComplete(...)
Đây là một thao tác đơn giản mà chúng tôi muốn lưu trữ trong Redis bài học được biểu thị bằng lessonSlug tham số đường dẫn được hoàn thành tại thời điểm hiện tại của yêu cầu.
Trong Redis, chúng tôi muốn giữ một bản đồ cho mỗi người dùng trong đó mỗi cặp khóa-giá trị trong bản đồ sẽ là bài học làm khóa và ngày hoàn thành là giá trị. Vì vậy, chúng tôi sử dụng HSET Lệnh Redis. Chúng tôi cũng có thể lưu trữ một khóa riêng cho mỗi bài học nhưng điều này giúp người dùng dễ dàng tìm nạp tất cả các bài học cùng một lúc sau đó.
func markLessonComplete(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
lessonSlug := chi.URLParam(r, "lessonSlug")
userId := r.Context().Value(CTX_USER_ID).(string)
timeNow := time.Now().Format(time.RFC3339)
err := redisDb.HSet(ctx, "lessons:"+userId, lessonSlug, timeNow).Err()
if err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, struct{ Message string }{Message: "We could not save your progression..."})
return
}
render.JSON(w, r, struct {
LessonSlug string
LastCompleted string
}{
lessonSlug,
timeNow,
})
} 2.3 danh sáchBài học đã hoàn thành(...)
Tương tự như phần trước, ở đây chúng tôi chỉ muốn trả về toàn bộ bản đồ hoàn thành bài học và trả lại cho người dùng dưới dạng phản hồi JSON. Chúng tôi sử dụng HGETALL lệnh cho việc này.
func listLessonsCompleted(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
userId := r.Context().Value(CTX_USER_ID).(string)
lessons, err := redisDb.HGetAll(ctx, "lessons:"+userId).Result()
if err == redis.Nil {
lessons = map[string]string{}
} else if err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, struct{ Message string }{Message: "We could not load your lessons..."})
return
}
render.JSON(w, r, struct {
Lessons map[string]string
}{
lessons,
})
} 2.4 đăng nhập(...)
Cuối cùng là điểm cuối đăng nhập. Một lần nữa, vui lòng không sao chép đoạn mã sau vào sản xuất vì nó không thực hiện bất kỳ loại xác thực nào. Vì mục đích của bài viết này, chúng tôi chỉ quan tâm đến cách nó truy vấn Redis và cách nó đặt cookie cho ID phiên.
ID phiên được tạo bởi ksuid thư viện, có một số ưu điểm so với UUID thông thường và chúng tôi chỉ coi nó hoạt động trong 1 giờ. Chúng tôi sử dụng chức năng thời gian tồn tại của Redis SET lệnh tự động xóa khỏi cơ sở dữ liệu sau một giờ.
import (
// ...
"github.com/segmentio/ksuid"
)
func login(w http.ResponseWriter, r *http.Request) {
// Check credentials and update redis session and return Set-Cookie
// WARNING: You should do an actual validation in production for credentials!
// ...
// For now we always assume correctness and automatically create a session token
// by saving it to Redis, and also setting it as a cookie.
userId := strings.TrimSpace(r.FormValue("userId"))
if userId == "" {
render.Status(r, http.StatusBadRequest)
render.JSON(w, r, struct{ Message string }{Message: "Missing required userId"})
return
}
sessionId := ksuid.New()
redisDb.Set(r.Context(), "session:"+sessionId.String(), userId, time.Hour*1)
http.SetCookie(w, &http.Cookie{
Name: COOKIE_AUTH_NAME, Value: sessionId.String(),
Path: "/", MaxAge: int((time.Hour * 1).Seconds()),
// This should be true when deploying in production (https), but locally we need it false (http).
Secure: false,
})
http.Redirect(w, r, "/lessons/completed", http.StatusTemporaryRedirect)
} 3. Bản trình diễn - Cục bộ
Phù, có rất nhiều mã.😅
Hãy làm một bản demo nhanh để đảm bảo mọi thứ hoạt động như mong đợi.
- Đầu tiên, đặt
UPSTASH_REDIS_URLbiến môi trường thành URL của cơ sở dữ liệu bạn đã tạo ở phần 1 ở trên. Bạn có thể tìm thấy nó trong phần chi tiết của trang cơ sở dữ liệu của bạn (xem phần 1.1 ở trên).
export UPSTASH_REDIS_URL="<your-url-here>" - Sau đó, xây dựng và chạy máy chủ cục bộ:
make build-server && ./build/server Kiểm tra trình duyệt
Bây giờ, hãy thực hiện một số thử nghiệm trong trình duyệt bằng cách truy cập http://localhost:5000/lessons/completed.

Chúng tôi nhận được 403 - Forbidden , vậy hãy đăng nhập bằng cách truy cập http://localhost:5000/login?userId=lambros.

Chúng tôi đã đăng nhập ngay bây giờ và chúng tôi tự động được chuyển hướng đến /lessons/completed , nhưng chúng trống rỗng. Vì vậy, hãy đánh dấu một bài học là đã hoàn thành. Trong console tab bên trong devtools của trình duyệt của bạn chạy như sau:
await (
await fetch("http://localhost:5000/lessons/123/mark-complete", {
method: "POST",
credentials: "same-origin",
})
).json();
// Should output something like:
// {LessonSlug: '123', LastCompleted: '2022-10-12T02:01:14+03:00'} Truy cập http://localhost:5000/lessons/completed sẽ hiển thị bài học này như được đánh dấu ngay bây giờ:
{ "Lessons": { "123": "2022-10-12T02:01:14+03:00" } } Và thì đấy. Mọi thứ đều hoạt động tốt!
Nhìn vào chính cơ sở dữ liệu Redis bằng Trình duyệt dữ liệu trực tuyến mới ra mắt gần đây cũng chứng minh rằng dữ liệu dự kiến có ở đó.

4. AWS Lambda
Để thử nghiệm và triển khai lên AWS Lambda, chúng tôi sẽ sử dụng sam cli.
-
Trước tiên, hãy thiết lập SAM cli và đảm bảo người dùng/vai trò của bạn có quyền phù hợp.
-
samcli cần mẫu Cloudformation để hoạt động, vì vậy hãy sao chép nội dung sau vàoaws-iac/sam-template.yml:
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Defines all the AWS resources we need for our Upstash Redis API.
Resources:
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html
GoUpstashRedis:
Type: AWS::Serverless::Function
Properties:
CodeUri: ../build/handler.zip
Handler: handler
Runtime: go1.x
MemorySize: 512
FunctionUrlConfig:
AuthType: NONE
Cors:
AllowCredentials: false
AllowMethods: ["*"]
AllowOrigins: ["*"]
Outputs:
GoUpstashRedisApi:
Description: "Endpoint URL"
Value: !GetAtt GoUpstashRedisUrl.FunctionUrl
GoUpstashRedis:
Description: "Lambda Function ARN"
Value: !GetAtt GoUpstashRedis.Arn
GoUpstashRedisIamRole:
Description: "Implicit IAM Role created for GoUpstashRedis"
Value: !GetAtt GoUpstashRedisRole.Arn - Xây dựng gói xử lý cho AWS Lambda:
make build-lambda - Thêm phần sau vào
makefileđể dễ dàng triển khai sau khi chúng tôi thay đổi mã:
sam-deploy: build-lambda
sam deploy -t aws-iac/sam-template.yml --stack-name "UpstashRedisGoArticleStackDemo" --region eu-west-1 --resolve-s3 --no-confirm-changeset --no-fail-on-empty-changeset --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
- Triển khai đến khu vực được chỉ định (xem lệnh trước).
make sam-deploy - Bạn sẽ nhận được một số kết quả như bên dưới:
CloudFormation outputs from deployed stack
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Key GoUpstashRedis
Description Lambda Function ARN
Value arn:aws:lambda:eu-west-1:<redacted>:function:UpstashRedisGoArticleStackDem-GoUpstashRedis-baB8dQPkTfg0
Key GoUpstashRedisIamRole
Description Implicit IAM Role created for GoUpstashRedis
Value arn:aws:iam::<redacted>:role/UpstashRedisGoArticleStac-GoUpstashRedisRole-16UWC7HR6KII8
Key GoUpstashRedisApi
Description Endpoint URL
Value https://6pmmwqmg5vec3bcsldabckaf5i0nlgje.lambda-url.eu-west-1.on.aws/
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Successfully created/updated stack - UpstashRedisGoArticleStackDemo in eu-west-1 - URL của AWS Lambda đã triển khai hiển thị trong kết quả được in ra, trong trường hợp này là
https://6pmmwqmg5vec3bcsldabckaf5i0nlgje.lambda-url.eu-west-1.on.aws/. Vì vậy, vui lòng lặp lại các bước demo mà chúng tôi đã thực hiện trong trình duyệt trước khi sử dụnglocalhostvới miền thực tế ngay bây giờ.- Ngoài ra, bạn cũng có thể tìm thấy URL của hàm mới được tạo trong kết quả đầu ra của ngăn xếp CloudFormation
UpstashRedisGoArticleStackDemotrong bảng điều khiển Cloudformation. - Lưu ý: Đảm bảo đặt
UPSTASH_REDIS_URLbiến môi trường trên cấu hình AWS Lambda của bạn, nếu không nó sẽ bị lỗi. Truy cập bảng điều khiển AWS Lambda, sau đó nhấp vào Lambda mới được triển khai của bạn, nhấp vào Cấu hình rồi trên menu bên trái, nhấp vào Biến môi trường . NhậpUPSTASH_REDIS_URLlàm khóa và URL Upstash Redis của bạn làm giá trị. Nhấp vào Lưu , và bây giờ Lambda của bạn đã sẵn sàng.
- Ngoài ra, bạn cũng có thể tìm thấy URL của hàm mới được tạo trong kết quả đầu ra của ngăn xếp CloudFormation
4.1 Kiểm tra cục bộ SAM
Chúng tôi có thể kiểm tra Lambda cục bộ bằng cách cung cấp sample-event.json với đường dẫn/cookie/tham số truy vấn/vv phù hợp. Ví dụ về JSON như vậy có thể được tìm thấy trong aws-lambda-upstash-redis-article/sample-event.json .
- Sau đó, khi bạn có tệp sự kiện JSON hợp lệ, hãy chạy lệnh sau để gọi logic máy chủ giống như khi nó chạy trên AWS Lambda:
sam local invoke -t aws-iac/sam-template.yml -e sample-event.json 4.2 Bảo mật của URL Upstash Redis
Trong bài viết này, để đơn giản, chúng tôi đã cung cấp URL Upstash Redis, chứa mật khẩu, thông qua các biến môi trường. Chúng tôi không muốn mã hóa cứng phần này vào mẫu SAM Cloudformation được phiên bản cùng với mã của chúng tôi, đó là lý do tại sao chúng tôi phải định cấu hình thủ công thông qua bảng điều khiển AWS Lambda.
Có một cách tốt hơn để thực hiện việc này một cách tự động mà không cần sửa đổi cấu hình Lambda mỗi lần và tránh để bất kỳ ai có quyền truy cập vào bảng điều khiển đều thấy được thông tin xác thực/URL Redis.
Chúng tôi có thể sử dụng Kho lưu trữ thông số của Trình quản lý hệ thống AWS và tài nguyên Cloudformation tương ứng AWS::SSM::Parameter để giữ URL (chúng ta có thể đặt URL một lần và giữ lại trong quá trình triển khai) đồng thời thay đổi mã Lambda để tìm nạp giá trị của tham số khi chạy. Chúng ta cũng có thể tự động đưa nó vào dưới dạng biến env bên trong sam-template.yml , mặc dù điều này vẫn có ở dạng văn bản thuần túy trong bảng điều khiển.
Việc thay đổi mã để tìm nạp từ Kho tham số SSM thật dễ dàng do chúng tôi phân tách các điểm vào, vì vậy, chúng tôi chỉ có thể tìm nạp tham số khi chạy bên trong AWS Lambda (~/dev/aws-lambda-upstash-redis/cmd/lambda/main.go ) và chuyển nó tới NewClient() chức năng tạo ứng dụng khách Redis.
5. Nó nhanh đến mức nào?
Ngoài lệnh khởi động nguội đầu tiên mất khoảng 100-120 ms , mọi lệnh gọi sau đó đều nhanh như chớp và luôn ở mức 4 ms .
Dưới đây là một ví dụ về lời gọi hấp dẫn dành cho /login?userId=lambros điểm cuối như đã triển khai ở trên:

Như bạn có thể thấy tổng thời lượng yêu cầu của chúng tôi là 2.06 ms . Có, đó là hai mili giây , để tạo ID phiên, hãy ghi ID phiên đó vào Upstash Redis từ xa và trả về phản hồi chuyển hướng.
Xem xét kỹ hơn trong Đầu ra nhật ký phần này, chúng ta có thể thấy rằng yêu cầu đã kéo dài 789.435μs , ít nhất là từ quan điểm mã của chúng tôi. Điều này có nghĩa là logic của chúng tôi đã hoàn thành tốt theo 1 ms (khoảng 0.790 ms ). Thật ngạc nhiên khi chúng ta đang sử dụng cơ sở dữ liệu từ xa.🤯
Kết luận
Tôi thực sự ngạc nhiên trước hiệu suất hoạt động của Upstash Redis, đặc biệt là vì thật khó để tìm được hiệu suất như vậy đối với cơ sở dữ liệu không có máy chủ phù hợp với các nền tảng như AWS Lambda.
API Redis thực sự tiện lợi, Upstash Redis có mô hình định giá hàng đầu và trải nghiệm tuyệt vời dành cho nhà phát triển, đồng thời nó rất nhanh. Tôi thích sự kết hợp này!
AWS Lambda + Upstash Redis + Go =🚀❤️