ארכיטקטורה של מערכת גמישה, עמידה וסקלבילית – חלק 1 (צד לקוח – front-end)

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

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

במדריך זה אנחנו נתייחס למערכת יחסית פשוטה – מערכת שיש לה צד לקוח (front-end), צד שרת (back-end) ונתונים (data). צד הלקוח מתקשר עם צד השרת, וצד השרת מתקשר עם מסד הנתונים. ההגדרה פה אומנם מופשטת, אבל הרבה מערכות מבוססות על החלקים האלה ומתפתחות לעוד ועוד עם הזמן.

צד לקוח (Front-end)

צד הלקוח הינו כל מה שהמשתמש משתמש בו – אפליקציה, אתר, תוכנה… מה שפונה אל הלקוח, הוא ה-front של המערכת שלנו, הפנים של המערכת שלנו. את צד הלקוח אפשר לבנות בכמעט כל שפה שיש וצורה שיש, החל מממשק שורת-פקודה (command line interface או CLI), תוכנה חלונאית (לדוגמה – תוכנת Word), אתר אינטרנט (למשל האתר הזה שאתם רואים דרך הדפדפן), אפליקציה (כל אפליקציה שיש לכם לטלפון הנייד) וכד'. היום כבר רוב החברות מבינות שהן צריכות לפתח מספר "צדדי לקוח" כיוון שהן צריכות לתמוך במגוון רחב של משתמשים – למשתמשי אנדרואיד אפליקציה אחת, למשתמשי אייפון אפליקציה אחרת, לגולשים דרך האתר – אתר מותאם, וכולם בסוף ידברו עם צד השרת (back-end).

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

קצת היסטוריה על צד לקוח

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

קצת בהמשך המחשבים האישיים תפסו תאוצה והתחילו לקבל כח עיבוד משמעותי ומעבדים חזקים יותר – אז התחילו לצוץ התוכנות שבצד הלקוח. היה למשל תוכנת דואר בשם Outlook, או צ'אט מיידי כמו mIRC, ICQ, MSN Messenger. כולן היו תוכנות שעבדו על המחשב והתחברו לשרת מרוחק, מה שגרם למחשבים האישיים לחלוק קצת מהעבודה הנדרשת, וחלק מהחישובים ובעיקר הגרפיקה היו על המחשבים האישיים. כלומר כעת כח העבודה היה מבוזר – decentralized, מה שאפשר לשרתים להיות מעט רזים יותר לעומת התצורה הקודמת. אבל – ופה אבל גדול – עדכוני תוכנה התחילו להוות בעיה. תארו לכם שיצאה גרסה 1.05 של תוכנה X, ואחרי חודש יוצאת גרסה 1.06 בעקבות פרצת אבטחה – כמה זמן ייקח לכל המשתמשים בעולם לעדכן את התוכנה? האם בכלל אפשר להבטיח שזה יקרה? אז התשובה היא שלא ממש, ובשפה המקצועית זה נקרא version fragmentation.

כדי לפתור את הבעיה הזאת ובמקביל להתפתחות הדפדפן ושפות צד שרת כגון ASP, ASP.NET, PHP וכד' – חלק מהתוכנות התקדמו לאתרים חכמים. האתרים נתנו שירותים משרתים מרכזיים וחזקים ויכלו, בזכות התפתחות וקידמת הטכנולוגיה, לתת שירות להרבה משתמשים בו זמנית. כתוצאה מהשימוש באתרים – עדכוני תוכנה כבר לא היו בעיה מרכזית, כיוון שבמידה ויש עדכון באתר אז הוא מיד זמין לכל המשתמשים. (עדיין יכולה להיות בעיית עדכון של הדפדפן, אבל גם את זה אפשר להגביל/להזהיר/לפתור). חזרנו שוב למצב של כח עיבוד מרוכז, centralized.

עם השנים, הכפר הגלובלי גדל עוד ועוד, מאות מיליוני משתמשים מתחברים לאינטרנט ומציפים כל שירות שקיים. אתרי האינטרנט שנבנו בעבר צריכים עוד ועוד שרתים כדי לתת תמיכה ולתת שירות לכל המשתמשים – ופה חייבים פתרון חדש קצת יותר. הדפדפנים התקדמו קצת יותר, שפת JavaScript נתמכת באופן רשמי ומסודר ומתחילות לצוץ להן ספריות עזר חזקות כמו jQuery, ובשלב מאוחר יותר – angular.js, React, Angular. ספריות אלה מאפשרות לכתוב צד לקוח חכם וחזק שנשמר באתר. כלומר משתמש גולש לאתר כלשהו שטוען את הספריות האלה ומאפשר לבצע פעולות מתקדמות על הדפדפן. כיוון שהספריות וקוד המערכת נשמר בשרתים – עדכון שלו זמין כמעט מיידית לכל מי שגולש לאתר, ולכן בעיית הגרסאות נפתרה, כמו כן העיבוד מבוזר (decentralized) כך שמאפשר לשרתים להיות שוב רזים.

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

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

אז מה עושים עם הצד לקוח?

אחרי שהבנו קצת את ההיסטוריה, אנחנו יודעים שכדאי לנו לבנות צד לקוח חזק, כזה שלא באמת צריך את השרת – אלא כזה שכשגולשים לאתר – מוריד את הקבצים הרלוונטיים ועוזב את השרת שהנגיש את הקבצים. זה נקרא Single Page Application או SPA, ואתם יכולים למצוא כזה במגוון שפות (Angular, React, Vue.JS ועוד).

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

ה-CDN הוא Content Delivery Network הינו שירות של אלפי שרתים שפזורים בעולם והוא נמצא בין המשתמש לבין קבצי האפליקציה. לשירות יש 2 מטרות שרלוונטיות לנו:

  1. מטמון (cache) – כאשר המשתמש גולש לאפליקציה דרך ה-CDN בפעם הראשונה, השרתים שהנגישו לו את האפליקציה שומרים עותק של הקבצים, וככה בקריאות הבאות ה-CDN כבר לא צריך לפנות לשרתים המקוריים, אלא רק להנגיש את הקבצים ששמורים לו במטמון. זה חוסך זמן ותעבורה במידה ויש הרבה משתמשים שפונים מאזור מסויים. (למען הסר ספק – גם למטמון יש תוקף והוא לא נשמר לעד, ובמידה ויש עדכון גרסה אפשר להכריח את ה-CDN לנקות את המטמון).
  2. הנגשה – נניח והקבצים יושבים על שרת באירלנד, כל המשתמשים שנמצאים בישראל ורוצים לגשת לשרת צריכים לעשות את כל הדרך לאירלנד דרך ספק האינטרנט שלהם. לספקי האינטרנט יכול להיות הסכמים שונים של תעבורה בינלאומית, יכול להיות שיעברו בכבל תת-ימי רחב פס ויכול להיות שיעברו בכבל תת-ימי צר פס – מה שיגרום לאיטיות. לעומת זאת – אם ניגשים ל-CDN, אז ניגשים לשרת קרוב יותר (יש להסתכל על מפת האזורים המונגשים של כל שירות CDN אם יש לו שרת מקומי למשתמשים שלכם), ובמידה והמטמון לא עובד – אז כל התעבורה והבקשות עוברות דרך התקשורת של ה-CDN ולא דרך ספק האינטרנט של המשתמש. זה נותן יתרונות במספר צורות כמו עדיפות על התקשורת, מהירות ואמינות, ולכן פניות שיעברו דרך ה-CDN סביר להניח שיהיו יותר טובות ונוחות למשתמשים בכל מצב.

אז מה עושים? בוחרים CDN שיש לו שרתים שנמצאים בארץ, ומוודאים את ההגדרות הרלוונטיות למטמון ואבטחה. יש מספר כאלה כמו CloudFront של אמזון (AWS) אבל אני ממליץ על CloudFlare – שירות אמין, חזק, ידוע, טוב, זול, מאובטח, וכמובן שיש לו שרתים בארץ.

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

סיכום

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

בהמשך נדבר גם על צד השרת (back-end) וגם על הנתונים (data), בינתיים אתם מוזמנים לחשוב איך עוד שירות ה-CDN יכול לתת לכם מענה (בעיקר בנקודת ההנגשה).

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *