Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Redis

सर्वर रहित आर्किटेक्चर:एडब्ल्यूएस लैम्ब्डा, अपस्टैश रेडिस और स्केलेबल, लागत प्रभावी ऐप्स के लिए जाएं

परिचय

<पी> सर्वर रहित कंप्यूट प्लेटफ़ॉर्म अद्भुत हैं, लेकिन सर्वर रहित डेटाबेस के बिना वे बहुत सीमित हैं।

<पी> जब मैं अपने आगामी पाठ्यक्रम, द एलिमेंट्स ऑफ सीआई/सीडी के लिए मंच का निर्माण कर रहा था, तो मैं एक सर्वर रहित डेटाबेस चाहता था क्योंकि मैंने कुछ चीजों के लिए अपने सर्वर के रूप में एडब्ल्यूएस लैम्ब्डा का उपयोग करने का निर्णय लिया था। मेरी आवश्यकताएं ये थीं:

  1. मूल्य निर्धारण के अनुसार भुगतान करें . मैं प्रति घंटे या प्रति नोड के हिसाब से भुगतान नहीं करना चाहता, बल्कि उपयोग (अनुरोध, भंडारण, आदि) के आधार पर भुगतान करना चाहता हूं। इसका उपयोग शुरू करना बहुत सस्ता होना चाहिए और जैसे-जैसे उपयोग बढ़ेगा लागत आनुपातिक रूप से बढ़ेगी।
  2. कम विलंबता . किसी को भी धीमी प्रतिक्रिया पसंद नहीं है, इसलिए डेटाबेस को क्वेरी करना AWS क्षेत्रों के अंदर से तेज़ होना चाहिए (उदाहरण के लिए eu-west-1 ).
  3. उत्कृष्ट डेवलपर अनुभव (DevX) . किसी अन्य विशिष्ट डीएसएल को सीखे बिना, या किसी वेबसाइट पर घंटों बर्बाद किए बिना डेटाबेस के लिए एक अच्छा इंटरफ़ेस रखना प्राथमिकता है।
<पी> अपस्टैश रेडिस उपरोक्त सभी आवश्यकताओं को पूरा करता है, और यह इस पर बहुत अच्छा काम करता है।

  • जाते ही भुगतान करें?
    • ✅ शुरू करना वास्तव में किफायती है, और बड़े पैमाने पर भी!
  • कम विलंबता?
    • < AWS Lambda के अंदर से क्वेरी करने पर 1ms विलंबता!
  • महान DevX?
    • ✅ यह मानक रेडिस है। तो, हाँ.
<पी> इस लेख में हम यह देखने जा रहे हैं कि AWS लैम्ब्डा के अंदर से अपस्टैश रेडिस का उपयोग कैसे करें, यह सुनिश्चित करें कि यह हमारी आवश्यकताओं के लिए पर्याप्त तेज़ है, साथ ही साथ हमारे कोड को बनाए रखने योग्य भी रखा जाए ताकि स्थानीय स्तर पर परीक्षण किया जा सके या ज़रूरत पड़ने पर एक अलग प्लेटफ़ॉर्म पर तैनात किया जा सके।

हम क्या कार्यान्वित कर रहे हैं?

<पी> सरलता के लिए, हम केवल 3 एपीआई एंडपॉइंट लागू करने जा रहे हैं:

  1. GET|POST /login समापन बिंदु जो userId स्वीकार करता है GET में एक क्वेरी पैरामीटर के रूप में , या POST के साथ सबमिट किए गए फॉर्म मान के अंदर अनुरोध. यह समापन बिंदु एक सत्र आईडी उत्पन्न करेगा, इसे रेडिस में संग्रहीत करेगा, और बाद की यात्राओं के लिए एक कुकी भी सेट करेगा। GET इससे परीक्षण करना आसान हो जाता है।🙃
  2. GET /lessons/completed एंडपॉइंट के लिए लॉग इन उपयोगकर्ताओं की आवश्यकता होती है (अर्थात सत्र आईडी के साथ कुकी होना) और उपयोगकर्ता द्वारा पूरा किए गए सभी पाठों और कब पूरा हुआ, इसके साथ एक JSON प्रतिक्रिया देता है।
  3. POST /lessons/{lessonSlug}/mark-complete एंडपॉइंट के लिए लॉग इन उपयोगकर्ताओं की आवश्यकता होती है (अर्थात सत्र आईडी के साथ कुकी होना) और lessonSlug द्वारा दर्शाए गए पाठ को चिह्नित करता है जैसा कि वर्तमान समय के साथ पूरा हुआ।
<पी> ध्यान दें:नीचे दिए गए कोड में कुछ चीजें गायब हैं, इसलिए यह उत्पादन के लिए तैयार कॉपी-पेस्ट करने योग्य कोड नहीं है। उदाहरण के लिए, हमें यह जांचना चाहिए कि दिए गए lessonSlug इसे अद्यतन करने से पहले मौजूद है। लॉगिन एंडपॉइंट को एक पासवर्ड भी स्वीकार करना चाहिए और सत्र आईडी आदि बनाने से पहले उचित नमकीन/हैशेड सत्यापन करना चाहिए।

1. सेटअप

  • नीचे विस्तृत पूरा कोड मेरे aws-playground में भी मौजूद है रिपॉजिटरी यदि आप यह देखना चाहते हैं कि सब कुछ एक साथ कैसे फिट बैठता है।
<पी> जैसा कि आप नीचे देखेंगे, हम दो एंट्रीपॉइंट यानी दो निष्पादन योग्य कमांड बना रहे हैं। एक सामान्य स्थानीय सर्वर के लिए होगा, और एक AWS लैम्ब्डा के लिए होगा। इस तरह, हम अपने संपूर्ण तर्क का स्थानीय स्तर पर और यदि हम चाहें तो मानक इकाई/एकीकरण परीक्षणों के साथ परीक्षण करने में सक्षम होंगे।

<पी> उनके बीच एकमात्र अंतर नीचे अनुभाग 1.2 और 1.3 में दिखाया गया है।

1.1 कार्यक्षेत्र

<पी> इससे पहले कि हम कोड में उतरें, आइए गो के लिए अपनी कार्यशील निर्देशिका सेटअप करें।

  1. गो डाउनलोड करें।
  2. अपनी पसंद के क्षेत्र में एक अपस्टैश रेडिस खाता और डेटाबेस बनाएं। आदर्श रूप से यह वही AWS क्षेत्र होना चाहिए जहां आप अपना लैम्ब्डा तैनात करेंगे। मैं eu-west-1 का उपयोग करूंगा (यूरोप, आयरलैंड) इस लेख में।
<पी> सर्वर रहित आर्किटेक्चर:एडब्ल्यूएस लैम्ब्डा, अपस्टैश रेडिस और स्केलेबल, लागत प्रभावी ऐप्स के लिए जाएं

<पी> उपरोक्त पूरा करने के बाद, अब हम अपना कार्यक्षेत्र बना सकते हैं। शेष आलेख के लिए, मान लें कि हमारा कोड ~/dev/aws-lambda-upstash-redis के अंतर्गत है .

mkdir -p ~/dev/aws-lambda-upstash-redis
cd ~/dev/aws-lambda-upstash-redis
<पी> फिर, एक गो पैकेज बनाएं:

go mod init com.upstash/example/aws-lambda-upstash-redis

1.2 स्थानीय सर्वर एंट्रीपॉइंट

  • निम्नलिखित कोड को ~/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 AWS लैम्ब्डा एंट्रीपॉइंट

  • निम्नलिखित कोड को ~/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 मूल तर्क

<पी> हमारा मुख्य मूल तर्क core में जाएगा पैकेज को उपरोक्त दोनों प्रवेश बिंदुओं द्वारा साझा किया जाना है।

  • निम्नलिखित कोड को ~/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 निर्माण/संकलन

<पी> मैं आमतौर पर एक छोटा makefile लिखता हूं हर बार जब मैं संकलन करना चाहता हूं तो लंबे कमांड टाइप करने से बचने के लिए निम्नलिखित को ~/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
<पी> विवरण के बारे में अभी बहुत अधिक चिंता न करें लेकिन यह हमें ऐसा करने की अनुमति देता है:

  • make build-server :सर्वर को स्थानीय रूप से चलाने के लिए बाइनरी बनाता है (निष्पादन योग्य ./build/server ).
  • make build-lambda :AWS Lambda (निष्पादन योग्य ./build/handler) पर सर्वर चलाने के लिए बाइनरी बनाता है और ./build/handler.zip ).
  • make या make build दोनों करता है.
<पी> CGO_ENABLED=0 विकल्प यह सुनिश्चित करता है कि हमारी निष्पादन योग्य बायनेरिज़ स्व-निहित हैं (यानी स्थिर रूप से संकलित)। GOOS=linux GOARCH=amd64 यदि आप स्थानीय रूप से मैक या विंडोज सिस्टम का उपयोग कर रहे हैं तो AWS लैम्ब्डा के लिनक्स वातावरण को क्रॉस-कंपाइल और मैच करने के लिए विकल्पों की आवश्यकता होती है।

<पी> इसके बाद, go mod tidy चलाएँ सभी कोड निर्भरताएँ लाने के लिए। हर बार जब आप गो निर्भरताएँ जोड़ते या हटाते हैं तो इसे चलाना याद रखें।

<पी> अंत में, make चलाएँ कोड की गहराई में जाने से पहले, एक बार सब कुछ बनाने और यह सुनिश्चित करने के लिए कि आपका कार्यक्षेत्र सेटअप है।

2. एपीआई कार्यान्वयन

<पी> इस सेक्शन के लिए हम हमेशा ~/dev/aws-lambda-upstash-redis/core/lib.go के अंदर काम करते रहेंगे फ़ाइल. <पी> निम्नलिखित कुछ पंक्तियाँ आश्चर्यजनक go-chi का उपयोग करते हुए एपीआई एंडपॉइंट्स को परिभाषित करती हैं जिनकी हमने पहले चर्चा की थी पुस्तकालय.

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
}
<पी> उपरोक्त स्निपेट में, r.Group(...) एक साझा परत बनाता है जहां हम इसके अंदर परिभाषित किसी भी रूट के लिए सामान्य मिडलवेयर लागू कर सकते हैं। इस मामले में, हम अपना स्वयं का मिडलवेयर UsersWithSessionOnly जोड़ते हैं , जैसा कि हम बाद में देखेंगे यह गारंटी देता है कि अनुरोध में एक सक्रिय सत्र आईडी के साथ कुकी शामिल है।

2.1 UsersWithSessionOnly मिडलवेयर

<पी> इस मिडलवेयर में हम निम्नलिखित को लागू करना चाहते हैं:

  1. उस कुकी को निकालें जिसमें सत्र आईडी है, और अन्यथा विफल हो जाएं।
  2. सत्र आईडी के आधार पर उपयोगकर्ता विवरण लाने के लिए रेडिस को क्वेरी करें, और यदि प्रदान की गई सत्र आईडी सक्रिय नहीं है तो विफल हो जाती है।
  3. उपयोगकर्ता आईडी को अनुरोध के context.Context में संग्रहीत करें इसे डाउनस्ट्रीम मिडलवेयर या हैंडलर्स के लिए उपलब्ध कराने के लिए।
<पी> सबसे पहले, हमें कुछ आयातों और परिभाषाओं के लिए कुछ बॉयलरप्लेट कोड की आवश्यकता है जो हर जगह उपयोग किए जाते हैं।

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
}
<पी> और अब प्रमाणीकरण मिडलवेयर के लिए मुख्य तर्क।

// 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 मार्कलेसनकंप्लीट(...)

<पी> यह एक सीधा ऑपरेशन है जहां हम रेडिस में lessonSlug द्वारा दर्शाए गए पाठ को संग्रहीत करना चाहते हैं। अनुरोध के वर्तमान समय में पथ पैरामीटर पूरा हो गया है।

<पी> रेडिस में हम प्रत्येक उपयोगकर्ता के लिए एक मानचित्र रखना चाहते हैं जहां मानचित्र में प्रत्येक कुंजी-मूल्य जोड़ी कुंजी के रूप में पाठ और मूल्य के रूप में पूर्णता तिथि होगी। इसलिए, हम HSET का उपयोग करते हैं रेडिस कमांड. हम प्रति पाठ एक अलग कुंजी भी संग्रहीत कर सकते हैं लेकिन इससे बाद में उपयोगकर्ता के लिए सभी पाठों को एक साथ लाना आसान हो जाता है।

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 सूचीपाठ पूर्ण(...)

<पी> पिछले अनुभाग की तरह ही, यहां हम केवल पाठों के पूरा होने का पूरा नक्शा वापस करना चाहते हैं और इसे JSON प्रतिक्रिया में उपयोगकर्ता को लौटाना चाहते हैं। हम HGETALL का उपयोग करते हैं इसके लिए आदेश दें.

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 लॉगिन(...)

<पी> अंत में, लॉगिन समापन बिंदु। एक बार फिर, कृपया निम्नलिखित कोड को उत्पादन में कॉपी न करें, क्योंकि यह किसी भी प्रकार का सत्यापन नहीं कर रहा है। इस लेख के प्रयोजनों के लिए हमारी रुचि केवल इस बात में है कि यह रेडिस से कैसे पूछताछ करता है और सत्र आईडी के लिए कुकी कैसे सेट करता है।

<पी> सत्र आईडी ksuid द्वारा उत्पन्न होती है लाइब्रेरी, जिसमें सामान्य यूयूआईडी की तुलना में कुछ फायदे हैं, और हम इसे केवल 1 घंटे के लिए सक्रिय मानते हैं। हम रेडिस SET की टाइम-टू-लाइव कार्यक्षमता का उपयोग करते हैं एक घंटे के बाद डेटाबेस से स्वत:हटाने का आदेश।

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. डेमो - स्थानीय रूप से

<पी> ओह, वह बहुत सारा कोड था।😅

<पी> आइए यह सुनिश्चित करने के लिए एक त्वरित डेमो करें कि सब कुछ अपेक्षा के अनुरूप काम करता है।

  • सबसे पहले, UPSTASH_REDIS_URL सेट करें उपरोक्त अनुभाग 1 में आपके द्वारा बनाए गए डेटाबेस के यूआरएल में पर्यावरण चर। आप इसे विवरण में पा सकते हैं आपके डेटाबेस के पृष्ठ का टैब (ऊपर अनुभाग 1.1 देखें)।
export UPSTASH_REDIS_URL="<your-url-here>"
  • फिर, स्थानीय सर्वर बनाएं और चलाएं:
make build-server && ./build/server

ब्राउज़र परीक्षण

<पी> अब आइए http://localhost:5000/lessons/completed पर जाकर ब्राउज़र में कुछ परीक्षण करें।

<पी> सर्वर रहित आर्किटेक्चर:एडब्ल्यूएस लैम्ब्डा, अपस्टैश रेडिस और स्केलेबल, लागत प्रभावी ऐप्स के लिए जाएं

<पी> हमें 403 - Forbidden मिलता है , तो आइए http://localhost:5000/login?userId=lambros पर जाकर लॉगिन करें।

<पी> सर्वर रहित आर्किटेक्चर:एडब्ल्यूएस लैम्ब्डा, अपस्टैश रेडिस और स्केलेबल, लागत प्रभावी ऐप्स के लिए जाएं

<पी> अब हम लॉग इन हैं, और हम स्वचालित रूप से /lessons/completed पर रीडायरेक्ट हो गए हैं , लेकिन वे खाली हैं. तो, आइए एक पाठ को पूर्ण के रूप में चिह्नित करें। console में अपने ब्राउज़र के डेवटूल्स के अंदर टैब में निम्नलिखित चलाएँ:

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'}
<पी> http://localhost:5000/lessons/completed पर जाने पर यह पाठ अभी चिह्नित के रूप में दिखना चाहिए:

{ "Lessons": { "123": "2022-10-12T02:01:14+03:00" } }
<पी> और वोइला. सब कुछ ठीक काम करता है!

<पी> हाल ही में लॉन्च किए गए ऑनलाइन डेटा ब्राउज़र का उपयोग करके रेडिस डेटाबेस को देखने से यह भी साबित होता है कि अपेक्षित डेटा वहां मौजूद है।

<पी> सर्वर रहित आर्किटेक्चर:एडब्ल्यूएस लैम्ब्डा, अपस्टैश रेडिस और स्केलेबल, लागत प्रभावी ऐप्स के लिए जाएं

4. AWS लैम्ब्डा

<पी> AWS लैम्ब्डा का परीक्षण और तैनाती करने के लिए हम sam का उपयोग करने जा रहे हैं क्ली.

  • <पी> सबसे पहले, SAM cli सेटअप करें और सुनिश्चित करें कि आपके उपयोगकर्ता/भूमिका के पास सही अनुमतियाँ हैं।

  • <पी> sam सीएलआई को काम करने के लिए क्लाउडफॉर्मेशन टेम्पलेट की आवश्यकता है, इसलिए निम्नलिखित को aws-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
  • AWS Lambda के लिए हैंडलर बंडल बनाएं:
make build-lambda
  • निम्नलिखित को makefile में जोड़ें कोड परिवर्तन करने के बाद इसे तैनात करना आसान बनाने के लिए:
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
  • निर्दिष्ट क्षेत्र में तैनात करें (पिछला आदेश देखें)।
make sam-deploy
  • आपको नीचे जैसा कुछ आउटपुट मिलना चाहिए:
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
  • तैनात AWS लैम्ब्डा का URL मुद्रित आउटपुट में दिखाया गया है, इस मामले में https://6pmmwqmg5vec3bcsldabckaf5i0nlgje.lambda-url.eu-west-1.on.aws/ . इसलिए, बेझिझक उन डेमो चरणों को दोहराएं जो हमने localhost का उपयोग करने से पहले अपने ब्राउज़र में किए थे अब वास्तविक डोमेन के साथ।
    • वैकल्पिक रूप से, आप क्लाउडफॉर्मेशन स्टैक UpstashRedisGoArticleStackDemo के आउटपुट में नव निर्मित फ़ंक्शन का यूआरएल भी पा सकते हैं। क्लाउडफॉर्मेशन कंसोल में।
    • नोट: UPSTASH_REDIS_URL सेट करना सुनिश्चित करें आपके AWS लैम्ब्डा कॉन्फ़िगरेशन पर भी पर्यावरण चर, अन्यथा यह क्रैश हो जाएगा। AWS लैम्ब्डा कंसोल पर जाएँ, फिर अपने नए तैनात लैम्ब्डा पर क्लिक करें, कॉन्फ़िगरेशन पर क्लिक करें टैब, और फिर बाईं ओर के मेनू पर पर्यावरण चर पर क्लिक करें . UPSTASH_REDIS_URL टाइप करें कुंजी के रूप में, और आपका अपस्टैश रेडिस यूआरएल मान के रूप में। सहेजें पर क्लिक करें , और अब आपका लैम्ब्डा तैयार है।

4.1 एसएएम स्थानीय परीक्षण

<पी> हम sample-event.json प्रदान करके अपने लैम्ब्डा का स्थानीय स्तर पर परीक्षण कर सकते हैं सही पथ/कुकी/क्वेरी पैरामीटर/आदि के साथ। ऐसे JSON का उदाहरण aws-lambda-upstash-redis-article/sample-event.json में पाया जा सकता है .

  • फिर, एक बार जब आपके पास एक वैध JSON इवेंट फ़ाइल हो, तो सर्वर लॉजिक को लागू करने के लिए निम्नलिखित को चलाएँ क्योंकि यह AWS लैम्ब्डा पर चलेगा:
sam local invoke -t aws-iac/sam-template.yml -e sample-event.json

4.2 अपस्टैश रेडिस यूआरएल की सुरक्षा

<पी> इस आलेख में, सरलता के लिए हमने पर्यावरण चर के माध्यम से पासवर्ड युक्त अपस्टैश रेडिस यूआरएल प्रदान किया है। हम इसे एसएएम क्लाउडफॉर्मेशन टेम्पलेट में हार्डकोड नहीं करना चाहते हैं जो हमारे कोड के साथ संस्करणित है, इसलिए हमें इसे एडब्ल्यूएस लैम्ब्डा कंसोल के माध्यम से मैन्युअल रूप से कॉन्फ़िगर करना पड़ा। <पी> हर बार लैम्ब्डा कॉन्फ़िगरेशन को संशोधित किए बिना इसे स्वचालित रूप से करने का एक बेहतर तरीका है और कंसोल एक्सेस वाले किसी भी व्यक्ति के लिए रेडिस क्रेडेंशियल/यूआरएल को स्पष्ट रूप से देखने से बचना है।

<पी> हम AWS सिस्टम मैनेजर पैरामीटर स्टोर और संबंधित क्लाउडफॉर्मेशन संसाधन AWS::SSM::Parameter का उपयोग कर सकते हैं यूआरएल को होल्ड करने के लिए (हम इसे एक बार सेट कर सकते हैं और तैनाती के दौरान बनाए रख सकते हैं), और रनटाइम पर पैरामीटर का मान लाने के लिए हमारे लैम्ब्डा कोड को बदलें। हम इसे स्वचालित रूप से sam-template.yml के अंदर एक env वैरिएबल के रूप में भी इंजेक्ट कर सकते हैं , हालाँकि यह अभी भी कंसोल में सादे पाठ में होगा।

<पी> एसएसएम पैरामीटर स्टोर से इसे लाने के लिए कोड को बदलना हमारे प्रवेश बिंदुओं को अलग करने के कारण आसान है, इसलिए हम पैरामीटर को केवल एडब्ल्यूएस लैम्ब्डा (~/dev/aws-lambda-upstash-redis/cmd/lambda/main.go) के अंदर चलने पर ही प्राप्त कर सकते हैं। ) और इसे NewClient() से गुजारें वह फ़ंक्शन जो Redis क्लाइंट बनाता है।

5. यह कितना तेज़ है?

<पी> पहले कोल्ड स्टार्ट आमंत्रण के अलावा जिसमें लगभग 100-120 ms लगता है , उसके बाद प्रत्येक आह्वान बिजली की तेजी से होता है और हमेशा 4 ms के अंतर्गत होता है .

<पी> नीचे /login?userId=lambros के लिए एक हॉट आमंत्रण का उदाहरण दिया गया है समापन बिंदु जैसा कि ऊपर लागू किया गया है:

<पी> सर्वर रहित आर्किटेक्चर:एडब्ल्यूएस लैम्ब्डा, अपस्टैश रेडिस और स्केलेबल, लागत प्रभावी ऐप्स के लिए जाएं

<पी> जैसा कि आप देख सकते हैं हमारे अनुरोध की कुल अवधि 2.06 ms थी . हाँ, वहदो मिलीसेकंडहै , एक सत्र आईडी उत्पन्न करने के लिए, इसे दूरस्थ रूप से अपस्टैश रेडिस पर लिखें, और पुनर्निर्देशन प्रतिक्रिया लौटाएँ।

<पी> लॉग आउटपुट में अधिक ध्यान से देखें अनुभाग में, हम देख सकते हैं कि अनुरोध 789.435μs तक चला , कम से कम हमारे कोड के नजरिए से। इसका मतलब है कि हमारा तर्क 1 ms के तहत अच्छी तरह से पूरा हो गया है (लगभग 0.790 ms ). यह सोचकर आश्चर्य होता है कि हम एक दूरस्थ डेटाबेस का उपयोग कर रहे हैं।🤯

निष्कर्ष

<पी> मैं वास्तव में आश्चर्यचकित हूं कि अपस्टैश रेडिस कितना अच्छा प्रदर्शन करता है, खासकर जब से एडब्ल्यूएस लैम्ब्डा जैसे प्लेटफार्मों के लिए उपयुक्त सर्वर रहित डेटाबेस के लिए ऐसा प्रदर्शन खोजना कठिन है।

<पी> रेडिस एपीआई वास्तव में सुविधाजनक है, अपस्टैश रेडिस के पास शीर्ष मूल्य निर्धारण मॉडल और अद्भुत डेवलपर अनुभव है, और यह तेज़ है। मुझे संयोजन पसंद है!

<पी> AWS लैम्ब्डा + अपस्टैश रेडिस + गो =🚀❤️


  1. Android का उपयोग करके Google डॉक्स के साथ ऑफ़लाइन कार्य करें Android का उपयोग करके Google डॉक्स के साथ ऑफ़लाइन कार्य करें

    कई स्थानों में; हवाई जहाज, कैफे, जहाज, आदि…। आपको उचित इंटरनेट कनेक्शन नहीं मिलता है, लेकिन कई लोगों के लिए जहां कहीं भी काम करना आवश्यक हो जाता है। Google डॉक्स ऐसे लोगों की ऑफ़लाइन मोड सुविधा के माध्यम से सहायता करता है। Google डिस्क का उपयोग करके, आप दस्तावेज़ों, स्प्रैडशीट्स और प्रस्तुतियों को ऑ

  1. एचटीएमएल डोम इनपुट तिथि ऑटोफोकस संपत्ति एचटीएमएल डोम इनपुट तिथि ऑटोफोकस संपत्ति

    HTML DOM इनपुट दिनांक ऑटोफोकस गुण सेट/रिटर्न करता है कि इनपुट दिनांक प्रारंभिक पृष्ठ लोड पर केंद्रित है या नहीं। सिंटैक्स निम्नलिखित वाक्य रचना है - बूलियन मान लौटाना - सही/गलत inputDateObject.autofocus सेटिंग ऑटोफोकस बूलियनवैल्यू के लिए inputDateObject.autofocus = booleanValue बूलियन मान यहा

  1. जावास्क्रिप्ट Array.join () विधि जावास्क्रिप्ट Array.join () विधि

    जावास्क्रिप्ट की Array.join () विधि का उपयोग सरणी में शामिल होने और एक स्ट्रिंग के रूप में वापस आने के लिए किया जाता है। वाक्य रचना इस प्रकार है - array.join(separator) ऊपर, विभाजक को पैरामीटर के रूप में उपयोग करने के लिए सेट करें। आइए अब जावास्क्रिप्ट माइनस में Array.join() मेथड को लागू करें; उद