נדרשת תוכנית App Service עבור אפליקציית ווב בייצור עם דומיינים מותאמים אישית/SSL, התאמה אוטומטית (autoscale) ו-deployment slots.
השתמש בשכבת התוכנית Standard (S1) של App Service או גבוהה יותר.
למה: Standard היא השכבה המינימלית התומכת בכל תכונות הייצור העיקריות: דומיינים מותאמים אישית עם SSL, התאמה אוטומטית (autoscale) ו-deployment slots. שכבת Basic חסרה autoscale ו-slots.
App Service צריך להתחבר למשאב מקומי (לדוגמה, SQL Server) ללא VPN או ExpressRoute.
השתמש ב-App Service Hybrid Connections. התקן את Hybrid Connection Manager (HCM) באתר הלקוח (on-premises).
למה: Hybrid Connections מספקות מנהרת TCP מאובטחת למשאבים מקומיים מבלי לדרוש פורטים נכנסים של חומת אש, VPN או אינטגרציית VNet. ה-HCM יוזם את החיבור היוצא.
Azure Function בתוכנית Consumption חווה cold starts ארוכים, מה שגורם לשיהוי (latency).
העבר לתוכנית Functions Premium וקבע תצורה של לפחות מופע אחד מחומם מראש (pre-warmed instance).
למה: תוכנית Premium מבטלת cold starts על ידי שמירה על מספר מוגדר של מופעים תמיד מוכנים. היא חסכונית יותר מתוכנית Dedicated מלאה למטרה זו.
Azure Function בתוכנית Consumption חורג מזמן הקצוב (timing out) מכיוון שלוקח לו יותר מ-10 דקות לבצע.
העבר את הפונקציה לתוכנית Premium או Dedicated (App Service).
למה: לתוכנית Consumption יש זמן קצוב מרבי של 10 דקות. תוכניות Premium ו-Dedicated תומכות בזמני ביצוע ארוכים בהרבה (עד 60 דקות או ללא הגבלה).
עבד מספר רב של פריטים בלתי תלויים במקביל והמתן עד שכולם יסתיימו לפני שתמשיך.
הטמע את תבנית Durable Functions Fan-out/Fan-in. המארגן (orchestrator) קורא למספר פונקציות פעילות במקביל ומשתמש ב-`Task.WhenAll` (או מקביל) כדי להמתין להשלמה.
למה: תבנית זו מיועדת לביצוע מקביל, שהוא יעיל בהרבה מעיבוד סדרתי (Function Chaining) עבור משימות בלתי תלויות.
זרימת עבודה ארוכת טווח חייבת להמתין לאירוע חיצוני, כגון אישור אנושי, עם זמן קצוב (timeout).
השתמש בתבנית Durable Functions Human Interaction. שלב `waitForExternalEvent` עם `createTimer`. השתמש ב-`Task.WhenAny` כדי להמשיך כאשר האירוע מגיע או שהטיימר פג.
למה: תבנית זו מאפשרת לתזמונים (orchestrations) להשהות ללא הגבלה מבלי לצרוך כוח מחשוב, בהמתנה לטריגר חיצוני, תוך טיפול בזמני קצוב (timeouts) בצורה אלגנטית.
אפליקציה בתוך קונטיינר צריכה להתרחב לאפס מופעים כאשר אין תעבורה כדי למזער עלויות.
השתמש ב-Azure Container Apps עם כלל התאמה מבוסס KEDA (לדוגמה, בקשות HTTP או אורך תור).
למה: Container Apps עם KEDA scalers יכולים להתרחב לאפס רפליקות כאשר אינם פעילים ולהתרחב לפי דרישה, וזה אידיאלי לעומסי עבודה מונעי אירועים או לסירוגין. התאמת CPU/זיכרון אינה יכולה להתרחב לאפס.
מיקרו-שירות בקצה עורפי ב-Azure Container Apps חייב להיות נגיש רק על ידי אפליקציות קונטיינר אחרות באותה סביבה, ולא מהאינטרנט הציבורי.
הפעל ingress באפליקציית הקונטיינר בקצה העורפי וקבע את נראות התעבורה ל-`internal`.
למה: Ingress פנימי מגביל גישה לסביבת Container Apps. אפליקציות אחרות בסביבה יכולות לגלות ולקרוא לשירות באמצעות ה-FQDN הפנימי שלו.
צריך להריץ קונטיינר יחיד עבור משימה פשוטה, בדיקה או עבודת אצווה ללא תזמור (orchestration).
השתמש ב-Azure Container Instances (ACI).
למה: ACI היא הדרך המהירה והפשוטה ביותר להריץ קונטיינר יחיד ללא ניהול תשתית בסיסית כלשהי. השתמש ב-Container Apps או AKS לתזמור יישומי ריבוי קונטיינרים.
צריך לבנות ולדחוף תמונת Docker ל-Azure Container Registry (ACR) מ-Dockerfile מקומי, אך Docker אינו מותקן מקומית.
השתמש בפקודה `az acr build`.
למה: `az acr build` מעביר את תהליך הבנייה ל-ACR Tasks בענן. הוא שולח את הקונטקסט של הבנייה ל-Azure, בונה את התמונה ושומר אותה ישירות ב-registry.
פיתוח עבור אחסון Azure
עיצוב קונטיינר של Cosmos DB עם שאילתות תכופות המסננות לפי מאפיין ספציפי (לדוגמה, `region`).
בחר את המאפיין הנשאל בתדירות הגבוהה ביותר, בעל קרדינליות גבוהה, כמפתח המחיצה (partition key) (לדוגמה, `/region`).
למה: שאילתות הכוללות את מפתח המחיצה (partition key) בסעיף `WHERE` ממוקדות למחיצה לוגית יחידה, ובכך נמנעות שאילתות fan-out יקרות על פני מחיצות שונות וממוזערת צריכת RU.
אפליקציה מבוזרת גלובלית דורשת שקריאות יחזירו תמיד את הכתיבה האחרונה שאושררה.
הגדר את רמת העקביות של חשבון Cosmos DB ל-Strong.
למה: עקביות Strong מספקת ערובה לליניאריות (linearizability), ומבטיחה שקריאות תמיד מעודכנות. רמות אחרות (Session, Bounded Staleness, Eventual) מחליפות עקביות תמורת שיהוי (latency) נמוך יותר וזמינות גבוהה יותר.
צריך לעבד את כל המסמכים החדשים או המעודכנים בקונטיינר של Cosmos DB בזמן אמת כדי לעדכן materialized view.
השתמש ב-Azure Function עם Cosmos DB trigger, המשתמש במעבד change feed.
למה: ה-change feed מספק יומן עקבי של שינויים. ה-Cosmos DB trigger עם מעבד change feed מבצע אוטומציה של ניהול מצב ואיזון עומסים על פני מופעי פונקציות מרובים.
צריך לבצע פעולה אטומית על מספר מסמכים בתוך אותה מחיצה לוגית (לדוגמה, ליצור שניים ולעדכן אחד).
השתמש ב-`TransactionalBatch` API ב-Cosmos DB SDK. כל הפעולות חייבות לכוון לאותו partition key.
למה: TransactionalBatch מבטיח שכל הפעולות ב-batch יצליחו או ייכשלו כיחידה אטומית אחת, ומונע עדכונים חלקיים. זה יעיל יותר מפרוצדורה מאוחסנת עבור פעולות batch בצד הלקוח.
עומס העבודה של Cosmos DB אינו צפוי, עם שיאים ושפל משמעותיים בתעבורה.
הגדר תפוקה מסופקת עם התאמה אוטומטית (autoscale provisioned throughput) על מסד הנתונים או הקונטיינר.
למה: Autoscale מתאים אוטומטית את יחידות ה-RU/s בהתבסס על השימוש, מבטיח ביצועים בשיאים וחיסכון בעלויות בשפלים. הוא מתרחב בין 10% ל-100% מה-RU/s המקסימלי שהוגדר.
נתונים נגישים בתדירות גבוהה בהתחלה, לאחר מכן בתדירות נמוכה, ולבסוף מאורכבים לשמירה לטווח ארוך.
השתמש בשילוב של רמות גישה Hot, Cool ו-Archive. בצע אוטומציה של מעברים עם מדיניות Lifecycle Management.
למה: התאמת רמת הגישה לדפוס הגישה מייעלת עלויות. Hot מיועד לגישה תכופה, Cool לגישה לא תכופה, ו-Archive לאחסון לטווח ארוך ובעלות נמוכה. מדיניות Lifecycle מבצעת אוטומציה זו.
הטמע blob leases. תהליך רוכש נעילת כתיבה בלעדית (lease) על blob לפני שינויו.
למה: Leases מספקים בקרת מקביליות פסימית. לאחר רכישת lease, אף לקוח אחר אינו יכול לכתוב ל-blob עד שה-lease משוחרר או פג תוקפו.
אחסן יומני ביקורת (audit logs) ב-Blob Storage וודא שלא ניתן לשנותם או למחוק אותם למשך תקופת שמירה קבועה (לדוגמה, 7 שנים).
הגדר מדיניות שמירה מבוססת זמן (time-based retention policy) על קונטיינר ה-blob. עבור החזקות ללא הגבלה, השתמש ב-legal hold.
למה: מדיניות אחסון בלתי ניתנת לשינוי (immutable storage policies) אוכפת מצב WORM (Write-Once, Read-Many), החיוני לעמידה בתקנים. לאחר נעילה, לא ניתן לקצר מדיניות מבוססת זמן.
צריך לקטלג blobs עם תכונות key-value ולשאול אותם על פני כל חשבון אחסון מבלי לרשום את כל ה-blobs.
השתמש ב-Blob Index Tags.
למה: Index tags מקוטלגים על ידי שירות האחסון וניתן להשתמש בהם בשאילתות סינון בצד השרת (`Find Blobs by Tags`). metadata אינו מקוטלג וניתן לסנן אותו רק בצד הלקוח לאחר רישום.
הטמעת אבטחת Azure
אמת משתמשים בצורה מאובטחת ב-Single-Page Application (SPA) ורכוש אסימונים עבור API בקצה העורפי.
השתמש בזרימת Authorization Code עם PKCE (Proof Key for Code Exchange).
למה: זוהי שיטת האבטחה המומלצת כיום עבור לקוחות ציבוריים. היא מונעת חשיפת אסימונים בכתובת ה-URL (בניגוד לזרימת Implicit המיושנת) ואינה דורשת client secret.
שירות רקע או daemon צריך לקרוא ל-API מוגן (כמו Microsoft Graph) ללא משתמש מחובר.
השתמש בזרימת Client Credentials עם הרשאות Application.
למה: זרימה זו מאמתת את היישום עצמו באמצעות client secret או certificate. הרשאות Application מעניקות גישה על פני הארגון, בכפוף להסכמת מנהל מערכת.
API ווב בשכבת ביניים צריך לקרוא ל-API במורד הזרם תוך שמירה על זהות המשתמש המקורי המחובר.
הטמע את זרימת On-Behalf-Of (OBO).
למה: ה-API בשכבת הביניים מחליף את אסימון הגישה של המשתמש באסימון חדש המיועד ל-API במורד הזרם. זה מפצל את זהות המשתמש בצורה מאובטחת.
אפליקציה המשתמשת ב-MSAL צריכה לרכוש אסימונים ביעילות, תוך מזעור הנחיות למשתמש.
קרא תמיד ל-`AcquireTokenSilent()` תחילה. אם הוא נכשל עם `MsalUiRequiredException`, חזור לשיטה אינטראקטיבית כמו `AcquireTokenInteractive()`.
למה: `AcquireTokenSilent()` בודק את המטמון עבור אסימון תקף או משתמש ב-refresh token כדי לקבל אסימון חדש ללא אינטראקציה עם המשתמש. זה חיוני לחווית משתמש טובה.
משאב Azure (לדוגמה, App Service, Function) צריך לגשת למשאב Azure אחר (לדוגמה, Key Vault, SQL Database) מבלי לאחסן אישורים בקוד או בקובץ תצורה.
הפעל זהות מנוהלת (managed identity) (מוקצית על ידי המערכת או מוקצית על ידי משתמש) במשאב המקור והענק לה הרשאות RBAC במשאב היעד.
למה: זהות מנוהלת מספקת זהות ב-Microsoft Entra ID למשאב. Azure מנהלת את מחזור החיים של האישורים, ומבטלת את הצורך של מפתחים לטפל בסודות.
מספר משאבי Azure צריכים לשתף את אותה זהות והרשאות כדי לגשת לשירותים אחרים.
צור זהות מנוהלת אחת המוקצית על ידי משתמש והקצה אותה לכל המשאבים הנדרשים.
למה: לזהות המוקצית על ידי משתמש יש מחזור חיים בלתי תלוי בכל משאב, מה שהופך אותה לניתנת לשימוש חוזר. זהות המוקצית על ידי המערכת קשורה למשאב יחיד ונמחקת כאשר המשאב נמחק.
צריך להעניק גישה לסודות ב-Key Vault באמצעות קבוצות Azure AD עם הרשאות מפורטות ברמת הסוד הבודד.
השתמש במודל הרשאות Azure RBAC עבור Key Vault. הקצה תפקידים כמו `Key Vault Secrets User` ל-principals.
למה: RBAC מאפשר הקצאת תפקידים ברמת ה-vault, או ברמת key/secret/certificate בודדים, ומספק פירוט רב יותר ממדיניות גישה, החלה על כל האובייקטים מסוג מסוים ב-vault.
אפליקציה צריכה לקלוט שינויים בתצורה מ-Azure App Configuration מבלי להפעיל מחדש.
השתמש ב-App Configuration provider/SDK והגדר אותו לרענון על ידי ניטור מפתח sentinel.
למה: ה-SDK יכול לבדוק תקופתית מפתח sentinel עבור שינויים. כאשר אתה מעדכן הגדרות יישום, אתה גם מעדכן את מפתח ה-sentinel, מה שמפעיל את כל הלקוחות לרענן את התצורה שלהם.
צריך לאפשר תכונה חדשה לקבוצה ספציפית של משתמשים (לדוגמה, בודקי בטא) ולאחוז מסוים מהקהל הכללי.
השתמש ב-feature flag של Azure App Configuration עם מסנן Targeting.
למה: מסנן Targeting תומך בהשקות מורכבות, ומאפשר לך להגדיר קהלים על בסיס משתמשים וקבוצות עם אחוזים ספציפיים, בתוספת אחוז השקה ברירת מחדל לכל השאר.
צריך ליצור אסימון מאובטח, קצר טווח, כדי להעניק ללקוח גישה ל-blob ספציפי.
צור user delegation SAS.
למה: user delegation SAS חתום עם אישורי Microsoft Entra ID, לא עם מפתח חשבון האחסון. זה מאובטח יותר מכיוון שהוא מונע הפצת מפתח החשבון וניתן לבטל גישה באמצעות מדיניות Entra ID.
ניטור, פתרון בעיות ואופטימיזציה של פתרונות Azure
פתור בעיית ביצועים באפליקציית מיקרו-שירותים על ידי הדמיית תלויות וזיהוי איזה שירות במורד הזרם גורם לשיהוי (latency) גבוה.
השתמש בתכונת Application Map ב-Application Insights.
למה: Application Map מגלה אוטומטית ומציג תצוגה טופולוגית של היישום המבוזר שלך, מראה מדדי בריאות וביצועים עבור כל רכיב והקריאות ביניהם.
עקוב אחר בקשת משתמש יחידה כשהיא זורמת על פני מספר מיקרו-שירותים.
השתמש בתצוגת פרטי טרנזקציה מקצה לקצה ב-Application Insights. כל נתוני טלמטריה מתואמים על ידי `operation_Id` משותף.
למה: ה-SDKs של Application Insights מפיצים אוטומטית כותרות W3C Trace Context, ומאפשרים לכל נתוני טלמטריה עבור פעולה יחידה להיות מתואמים עם אותו `operation_Id`, מה שמאפשר תצוגה מאוחדת.
אבחן בעיית ייצור: ביצועים איטיים לסירוגין לעומת חריגה (exception) לסירוגין.
עבור ביצועים איטיים, השתמש ב-Application Insights Profiler. עבור חריגות, השתמש ב-Snapshot Debugger.
למה: Profiler לוכד מעקבי תזמון ברמת המתודה עבור בקשות איטיות ("hot paths"). Snapshot Debugger לוכד את מחסנית הקריאות והמשתנים המקומיים ברגע שחריגה נזרקת.
הפחת את נפח הנתונים והעלות של Application Insights מאפליקציה בעלת תעבורה גבוהה תוך שמירה על נתונים תקפים סטטיסטית.
הפעל דגימה אדפטיבית (adaptive sampling) בתצורת ה-SDK של היישום.
למה: דגימה אדפטיבית מתאימה אוטומטית את קצב הדגימה כדי להישאר בנפח נתונים יעד, דוגמת בצורה אגרסיבית יותר במהלך תעבורה גבוהה ופחות במהלך תעבורה נמוכה, תוך שמירה על נתוני טלמטריה חשובים.
נטר באופן רציף את זמינות נקודת קצה של אפליקציית ווב ממספר מיקומים גיאוגרפיים.
למה: בדיקות זמינות שולחות בקשות לנקודת הקצה שלך ממרכזי נתונים של Azure ברחבי העולם, ומספקות ניטור פרואקטיבי של זמינות ותגובתיות ומפעילות התראות על כשל.
צור התראה שמופעלת כאשר מדד ביצועים (לדוגמה, זמן תגובה ממוצע) עולה על סף מסוים למשך תקופה מוגדרת.
צור כלל התראת מדד של Azure Monitor. כוון את המשאב והמדד, הגדר סף סטטי, סוג צבירה (aggregation type) ותקופת הערכה. קשר לקבוצת פעולה (action group).
למה: התראות מדדים מספקות ניטור בעל שיהוי נמוך, מבוסס מצב, של נתוני מדדים כמעט בזמן אמת, וזה אידיאלי להתראות מבוססות ביצועים.
התחברות וצריכה של שירותי Azure ושירותי צד שלישי
שלוט בשימוש ב-API על ידי הגבלת תדירות הקריאות (לדוגמה, 100 קריאות/דקה) לעומת סך הקריאות על פני תקופה ארוכה יותר (לדוגמה, 10,000 קריאות/חודש).
השתמש במדיניות `rate-limit` עבור תדירות הקריאות. השתמש במדיניות `quota` עבור נפח הקריאות הכולל.
למה: `rate-limit` מגביל עליות קצרות טווח ומחזיר HTTP 429. `quota` אוכף מגבלת שימוש לטווח ארוך יותר (לדוגמה, תקופת חיוב) ומחזיר HTTP 403 כאשר חורגים ממנה.
למה: שילוב מדיניות דו-חלקי זה מאפשר שמירת תגובות במטמון. `cache-lookup` בודק פריט שנשמר במטמון, ו-`cache-store` שומר את התגובה. תכונות ה-`vary-by` מבטיחות ערכי מטמון ייחודיים עבור וריאציות בקשה שונות.
נהל שינויים ב-API. נדרש שינוי שובר תאימות (breaking change) לעומת שינוי שאינו שובר תאימות (non-breaking change) שצריך להיבדק.
השתמש ב-Versions עבור שינויים שוברי תאימות (לדוגמה, /v1, /v2). השתמש ב-Revisions עבור שינויים שאינם שוברי תאימות והשקות בטוחות ומדורגות.
למה: גרסאות (Versioning) מאפשרות למספר גרסאות API להיות פעילות בו-זמנית. תיקונים (Revisions) מאפשרים לך לשנות API במצב לא מקוון, לבדוק אותו, ולאחר מכן להפוך אותו לתיקון "הנוכחי" ללא השבתה.
הודע למספר שירותים במורד הזרם, בלתי תלויים, כאשר מתרחש אירוע בשירות Azure (לדוגמה, blob נוצר, resource group נוצרה).
השתמש ב-Azure Event Grid. צור topic מערכת עבור משאב Azure ומנויי אירועים עבור כל handler במורד הזרם.
למה: Event Grid הוא שירות pub/sub מנוהל במלואו, מבוסס push, המפריד בין מפרסמי אירועים למנויים, ומאפשר ארכיטקטורות ריאקטיביות מונעות אירועים.
קלוט זרם גדול של נתוני טלמטריה או אירועים (מיליוני אירועים בשנייה) ממכשירים רבים.
השתמש ב-Azure Event Hubs.
למה: Event Hubs היא פלטפורמת הזרמת נתונים הניתנת להרחבה מאסיבית המיועדת לקליטה בתפוקה גבוהה. היא משתמשת במודל צרכנים מחולק למחיצות (partitioned consumer model) עבור עיבוד מקביל.
ודא שאירועים מאותו מקור (לדוגמה, מכשיר IoT ספציפי) מעובדים בסדר על ידי אותו צרכן.
שלח אירועים ל-Event Hubs עם partition key המוגדר למזהה המקור (לדוגמה, device ID).
למה: Event Hubs מנתב את כל ההודעות עם אותו partition key לאותה מחיצה. בתוך מחיצה, סדר ההודעות נשמר.
עבד רצף של הודעות קשורות בסדר First-In, First-Out (FIFO) קפדני.
השתמש ב-Azure Service Bus sessions. שלח את כל ההודעות הקשורות עם אותו `SessionId`.
למה: Sessions מספקות זרם הודעות מקביל ומסודר. מקבל מודע-ל-session נועל את ה-session, ומבטיח שההודעות יעובדו ברצף על ידי צרכן יחיד.
מפרסם יחיד שולח הודעות ל-topic, אך מספר מנויים רוצים רק קבוצת משנה של הודעות אלה בהתבסס על מאפייני הודעה.
השתמש ב-Service Bus topic עם מספר מנויים. החל SQL filters או Correlation filters על כל מנוי.
למה: זוהי תבנית publish-subscribe קנונית עם ניתוב מבוסס תוכן. כל מנוי מקבל עותק של ההודעה אם היא תואמת לכלל הסינון שלו.
הודעה לא ניתנת לעיבוד בהצלחה לאחר ניסיונות חוזרים ונשנים וחייבת להיות מוצבת בצד לבדיקה מאוחרת יותר.
תן להודעה להיכשל בעיבוד עד שיעלה על סף המסירה המקסימלי שלה. היא תועבר אוטומטית ל-Dead-Letter Queue (DLQ).
למה: ה-DLQ הוא sub-queue מובנה להודעות בעייתיות (poison messages). זה מונע מהודעה נכשלת לחסום את התור הראשי ומאפשר ניתוח ועיבוד מחדש במצב לא מקוון.
בחר שירות העברת הודעות עבור: פקודות ארגוניות, אירועים ריאקטיביים או טלמטריה בנפח גבוה.
Service Bus לפקודות (הזמנות, עסקאות). Event Grid לאירועים ריאקטיביים (blob נוצר, משאב השתנה). Event Hubs לטלמטריה (נתוני IoT, clickstreams).
למה: Service Bus מציע תכונות עשירות כמו סדר, טרנזקציות ו-dead-lettering. Event Grid מיועד לניתוב אירועים קל משקל מבוסס push. Event Hubs מיועד להזרמת נתונים בתפוקה גבוהה.