יום שלישי, 27 ביולי 2010

בקרת איכות ידנית היא שורש כל רע

ראשית עלינו להבדיל בין בקרת איכות - QA, לבדיקות קבלה (Acceptance Test). 
בקרת איכות היא תהליך החוזר על עצמו בכל פריסה של המוצר בסביבת הייצור. למעשה בקרת איכות היא בדיקת המוצר כWhite Box. ניתן על כן להוסיף בדיקות אילו כבדיקות האינטגרציה (Integration Tests) של המוצר, להם יש תפקיד דומה עם מספר הבדלים סמנטיים. בקרת איכות צריכות להתבצע במהירות מרבית, קרי דקות, בכל (!!!) פריסה ועל מגוון רחב של קונפיגורציות (למשל פרמוטציות על אוסף מערכות הפעלה ודפדפנים). על מנת להגיע לכך, בדיקות אילו חייבות להיות ממוכנות.
בדיקות קבלה הם בדיקות שהלקוח צריך לעשות על מנת לאשר שאכן המוצר תואם את הציפיות כפי שנכתבו בהגדרות המוצר (spec). על פי רוב הלקוח הוא מנהל המוצר המייצג את משתמש הקצה, ויש לדרוש ממנו להגדיר את הבדיקות בהגדרת המוצר. בדיקות הקבלה הם על פי רוב ידניות בהנחה שמדובר בממשק ויזואלי, והם מתבצעים ע"י מנהל המוצר באבני דרך או סיום המוצר.
בדיקת איכות צריכה לכלול לפחות את כל בדיקות הקבלה, מקרי קצה, טיפול בשגיאות, התקפות זדוניות (או יותר גרוע: משתמשים מבולבלים), ובדיקות של באגים שהתגלו עם הזמן.

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

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

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

יום שבת, 24 ביולי 2010

מצגת על פריסה ממשכת

בביקורי האחרון בישראל זכיתי להתארח במעבדות המחקר של יבמ, Outbrain וAnswers.com. בביקור הצגתי את עקרונות הפריסה הממשכת והמימוש בקצ'ינג בעזרת מצגת Prezi.




יום שבת, 17 ביולי 2010

ארבעה שלבים חיוניים בראיון עבודה למשרת תכנה

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

1. סינון טלפוני מהיר (עשר דקות): בחרת מועמד מערמת קורות החיים, איש כוח האדם או אתה תדברו עם המועמד, ספרו לו בקצרה על מה מדובר ותגידו לו שתשלחו לו חומר נוסף באמייל. תכינו שלוש עד חמש שאלות פשוטות הדורשות תשובה פשוטה ותשאלו את אותם השאלות. למשל: כמה זה שתיים בחזקת עשר, האם "Hash Code" הוא ייחודי בHashMap וכיוצא בזה. כבר כאן הרוב נופלים.

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

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

4. ארוחת צהריים או כוס קפה עם המרואיין (שעה עד שעתיים): חיוני ! חייבים להרגיש טוב עם הבן אדם. לדבר קצת על נושאים שלא קשורים לעבודה. גישה לא נכונה תהרוג כל צוות.

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

הרצאה על פריסה ממשכת ביבמ חיפה

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

יום ראשון, 4 ביולי 2010

תזרום אחי, תזרום

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

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

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

יום שבת, 3 ביולי 2010

פריסת אשכולות בגן חיות

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

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

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

יום שישי, 2 ביולי 2010

קו ההגנה לעולם יפרץ - על בדיקות, ניטור, ומערכות חיסוניות

בדיקות יחידה [Unit Testing], ניתוח קוד סטטי [Static analysis], בדיקות שילוב [Integration Tests], ניטור טכני [Monitoring] וניטור עסקי [KPI - Key Performance Indicators] - כולם הם קווי הגנה חיוניים המיועדים להגן על איכות המוצר אל מול הלקוחות.

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

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

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

לצירוף זה של קווי הגנה ופעולות הגנתיות מכניות מיידיות אנו קוראים מערכת חיסונית. מערכת זו מאפשרת לנו לנוע במהירות גבוהה מאוד של עשרות ואף מאות פריסות ביום. מערכת הפריסה מאפשרת למהנדס התכנה להורות על פריסת קוד חדש בסביבת ייצור, כבר בעת שליחת הקוד למאגר (git/svn).

יום חמישי, 1 ביולי 2010

פריסה לעומת השקה

ברוב חברות האינטרנט אין הבדל משמעותי בין פריסה [deployment] להשקה [release], דבר המקשה על הטמעת הפריסה הממשכת [continuous deployment].
קוד מקור [source code] לא פרוש משול למלאי היושב במחסן ומחכה לשיווק. תחזוק המלאי עולה כסף רב, ככל שהמלאי גדול יותר מחזור החיים של המוצר מתארך.
קוד פרוש משול למוצר המונח על המדף וזמין ללקוחות. אמנם לא כל מוצר או תכונה [feature] בשלה מספיק על מנת להיות זמינה בפני הלקוח מיומה הראשון, לשם כך מציגים תכונות אלה בפני לקוחות מעטים בלבד כגון מנהלי המוצר [product managers] בחברה. מנגנון התצוגה החלקית קיים בכל מקרה עבור בדיקות פילוח שוק [A/B testing].
בעוד שפריסה הנה ארוע הנדסי, השקה הנה ארוע עסקי שבתהליכו מרימים את הלוט מעל המוצר. תהליך הנדסי טוב הוא תהליך המבטל את התלות בין האירועים.

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

יום ראשון, 13 ביוני 2010

פריסה ממשכת בחברת הזנק קלילה

למרות שהנושאים הבאים נחשבים חדשים יחסית, ניתן למצא עליהם חומר רב באנגלית (פרטים נוספים בתחתית הדף). הדיון מבוסס על ניסיוני בחברות ההזנק [Startup] בה אני עובד כעת (קצ'ינג/kaChing) ובעבר (לינקד-אין/LinedIn), ומכאן מתייחס בעיקר לחברות המתבססות על אתר אינטרנטי.

לפני שנרחיב על פריסה מתמשכת [Continuous Deployment] ראוי להציג את הגישה המקובלת לפריסת תכנה ברוב חברות הרשת. גישה זאת כוללת לרוב שילוב מסוים של השלבים הבאים:
  1. תכנון אוסף תכונות חדשות של המוצר, כתיבת הגדרות עסקיות וטכניות.
  2. מימוש התכונות [Features] וכתיבת בדיקות. לרוב אין מעבר חד בין תת השלבים הנ"ל אך הם מתבצעים פחות או יותר ברצף. ככל שהפיתוח יותר מונחה בדיקות, יש פחות (אם בכלל) הפרדה בין שלב מימוש לבדיקות. בקבוצות בינוניות וגדולות קוד המקור לתכונות שונות נשלח לענפים שונים במאגר הקוד [Code Repository]. ענפים אילו ממוזגים לקראת סיום השלב לענף הייצור. במקרים קשים,כתיבת קוד הבדיקה נעשה ע"י קבוצה שונה.
  3. בקרת איכות [Quality Assurance] ידנית ע"י קבוצה פחות טכנית מצוות ההנדסה. לרוב בדיקה זאת נעשית בסביבת הערכות [Staging Environment].
  4. פריסת התכנה בסביבת הייצור [Production Environment] והשקת התכונות החדשות.
כתוצאה מכך, הזמן הנע בין כתיבת קוד המקור ועד הגעת הקוד לסביבת הייצור יכול לנוע בין ימים, מספר שבועות בממוצע ועד לחודשים!

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

פריסה ממשכת באה לקצר זמנים אלה לדקות בודדות ומיושמת בעיקר בחברות הזנק קלילות [Lean Startup]. חברת הזנק קלילה שמה חשיבות רבה על בניית הלקוח, לא ע"י ניחושים או שאלת הלקוח מה הוא רוצה, אלא תוך מעקב אחרי התנהגות בתנאי שוק אמתיים. פריסה ממשכת מאפשרת למנהלי המוצר להאיץ את תהליך הפקת הלקחים בעזרת שינוי תכניות ותעדופים על המקום.

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

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

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

בשיטה זאת אין קבוצת בדיקת איכות, וקוד חדש מגיע לסביבת מוצר תוך דקות בודדות. בממוצע יש כעשרים פריסות ביום וניתן לשלוח קוד לייצור תוך פחות מחמש דקות. צוותים העובדים בפריסה ממשכת מקדשים מאמצים רבים לבדיקות, ונותנים ביטחון רב באמינותם. הבדיקות אינם אלא קו הגנה אליהם נוספים קווי הגנה בצורת בדיקה עצמית של התכנה בסביבת השרת, וניטור ברמות טכניות ועסקיות. במידה ואחת מהבדיקות נכשלת הגרסא נמשכת חזרה וגרסא הקודמת נפרסת מחדש. מאחר וכל השירותים רצים באשכול, מספיק שיחידה בודדת נכשלת, כל האשכול מוחזר לגרסא הקודמת. לרוב, אם ישנם בעיות הם מתגלות תוך כדי פריסת היחידה הראשונה באשכול, יחידה זאת אינה זמינה לתנועת "ייצור" אלא עד שהיא עוברת סדרת בדיקות עצמיות ובדיקות שילוב [Integration Tests] עם כלי בדיקה מערכתיים כמו סלניום [Selenium].

עוד על היבטים טכניים של פריסה ממשכת בהמשך.

[1] חברת הזנק: Startup
[2] פריסה ממשכת: Continuous DeploymentAt WordpressAt kaChing
[3] תכונה: Feature
[4] מאגר קוד: Code Repository such as GIT and SVN
[5] בקרת איכות: Quality Assurance - QA
[6] סביבת הערכות: Staging Environment
[7] סביבת הייצור: Production Environment
[8] חברת הזנק קלילה: Lean Startup
[9] השקה: Release
[10] בדיקות שילוב: Integration Tests
[11] סלניום: Selenium