כיצד להפוך אפליקציית NodeJS ללא שרת

מקווה שתאהב את Serverless כמוני, מכיוון שזהו פוסט נוסף באותו נושא.

אם מדובר בממשק API REST פשוט ללא שרתים, ההתקנה שלך ב- AWS: Lambda + API Gateway די ברורה.

אבל מה דעתך על שירותים אחרים (מיקרו) שעשוי להיות ל- backend שלך? אתה יודע, הכנסת כל קוד היישום שלך לפונקציה אחת מונוליטית AWS למבדה היא לא הרעיון הטוב ביותר.

האתגר

אנו רוצים לספק מודולי יישומים פשוט כמיקרו-שירותים ללא שרתים שגם עליהם לתקשר זה עם זה. רצוי להסדיר תקשורת בין שירותים לפי סוג ACL.

ניסיון 1. שער ה- API

זו המחשבה הראשונה שהייתה לי כשניסיתי לפתור את הבעיה: פשוט לחשוף את כל שירותי המיקרו דרך ה- API Gateway. הבעיה היא ... ממשקי ה- API שנוצרים הם ציבוריים.

מדוע זו בעיה? לדוגמה, איננו רוצים ששירות חיובים יהיה זמין בשום מקום בעולם, גם אם הגישה מוגבלת על ידי הרשאה.

ובכן, אתה יכול להפוך את ה- API לפרטי, אך הנחיות האבטחה מוגבלות למדי:

אתה יכול להשתמש במדיניות משאבי ה- Gateway של API כדי לאפשר הפעלה מאובטחת של ה- API שלך על ידי:
* משתמש בחשבון AWS ספציפי * טווחי כתובות IP מקוריים מוגדרים או חסימות CIDR * ענני וירטואלים פרטיים (VPC) או נקודות קצה VPC (בכל חשבון)

זה מקשה למדי על השליטה בתקשורת בין שירותים כאלה. הדרך היחידה לעשות זאת כאן היא לשים שירותים ב- VPC נפרדים, שזה יותר מדי עבודה.

ניסוי 2. למבדה

מדוע אנחנו לא מכניסים כל מיקרו-שירות למבדה AWS נפרדת? האם זה יפתור את הבעיה?

כן, זהו אכן שירות מיקרו ללא שרתים, ותוכלו להשתמש במדיניות IAM כדי לייעל את הגישה הבין-שירותית. עם זאת, זה לא "קל".

אני יודע שזה די נורמלי בימינו להיות בעל תפקיד זעיר כיחידת משלוח. במקרה שלשירות שלכם יש יותר מנקודת קצה / שיטה / פונקציה אחת, זה בסדר לספק אותו כמספר lambdas.

אני מבין את היתרונות, אבל אתה מקריב את קלות התחזוקה והפיתוח. כמו כן, אני לא ממש אוהב את הרעיון של שירות חשוף כמערכת של פונקציות למבדה. דמיין כמה פונקציות נפרדות העוסקות בחיוב? זה כבר לא הקשר מוגבל. אמנם ישנם מקרים שבהם גרגריות כזו יכולה להיות שימושית, אך זהו מקרה נדיר.

נסה 3. למבדה שמנה

האם אנו יכולים למעשה לספק מספר נקודות קצה כממבה אחת (ללא שער API, כמובן)?

אם היינו יכולים לעשות זאת ננצל עד תום את האופציה הקודמת, אך נוכל גם לבחור את פירוט יחידות הפריסה שלנו.

הנה מה שאני רוצה לראות: כל שירות שתוכל ליישם צריך להיות אובייקט JS פשוט וישן עם שיטות. זה די קל לביצוע על ידי הוספת כמה שורות של קוד דבק בין האובייקט שלך ל- AWS Lambda.

הנה היישום שלי: aws-rpc. מודול nodejs זה חושף את פונקציית lambdaHandler בה אתה מעביר רק אובייקט אחד, והיא זמינה באופן אוטומטי לכל המשתמשים שיכולים לגשת ל- lambda:

ייבא את {lambdaHandler} מ- 'aws-rpc'; ייבא את {TestServiceImpl} מ- ./TestServiceImpl ';
// זוהי יחידת ההיערכות שלך // זה מה שאתה מציין כפונקציה מטפלת למבדה ייצוא מטפל קונסט = lambdaHandler (TestServiceImpl חדש ());

עכשיו אתה יכול פשוט לספק את "המטפל" כ- AWS למבדה. איך קוראים לשיטות:

ייבא את {TestService} מ- './TestService';
לקוח const = המתן ל- createClient ("LambdaName", "test"); console.log (המתן ל- client.test ());

שים לב שכדי שתוכל ליצור שיטות עבור אובייקט ה- stub של הלקוח, עליך להעביר את כל שמות השיטות כדי ליצור Client כמו בדוגמה.

זה הכרחי מכיוון של- JS אין מידע זמן ריצה על ממשקי TypeScript. אני יכול ליישם את זה בעזרת שיעורים מופשטים, אבל אני לא אוהב את ¯ \ _ (ツ) _ / ¯.

מַעֲנָק! אתה יכול לעשות הכל מקומי!

אני חושב שחשוב מאוד שסביבת הפיתוח המקומית שלך תהיה נוחה ככל האפשר. מסיבה זו, הוספתי גם את היכולת להפעיל את השירות ואת הלקוח באופן מקומי מבלי להצטרך לספק שום דבר עבור AWS (ראה פונקציות runService ו- createClient). תוכל למצוא דוגמאות במאגר GitHub.

סיכום

קל מאוד לעשות זאת כשאתה הולך לאיבוד בשירותים שמציעים ספקי ענן ומשפץ את התשתית שלך.

אני תמיד בוחר בפתרון הכי פשוט ומפורש שאני יכול לחשוב עליו. כמו כן, זכרו תמיד כי ניתן לעשות שימוש חוזר בטכניקות ופרקטיקות רבות מפלטפורמות אחרות (הרעיון של NodeJS Lambda הנועז הוא בהשראת מה שמכונה משקפיים מודגשים מעולם Java).

אם אהבתם נושא זה, קראו גם את הדברים הבאים:

  • עליכם ללמוד כיצד לבנות את הארכיטקטורה הטובה ביותר ללא שרתים
  • כיצד לבנות צינור CI / CD ללא שרת: 3 דוגמאות פשוטות
  • שכפול קל של DynamoDB בכל אזורים
  • כיצד לבנות יישום רב אזורי (ולשלם אפס)
  • הפוך את Java Web App ללא שרתים

תגובות, לייקים ושיתופים זוכים להערכה רבה. מלמטה למעלה!