תכונות דגלים עם אביב

1. סקירה כללית

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

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

2. דגלי תכונה

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

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

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

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

ישנם תרחישים רבים בהם דגלי תכונות יכולים להועיל:

פיתוח מבוסס תא מטען ותכונות לא סודיות

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

תצורה ספציפית לסביבה

אנו עשויים למצוא עצמנו דורשים פונקציונליות מסוימת כדי לאפס את ה- DB שלנו לסביבת בדיקות E2E.

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

לפיכך, נוכל לנצל את דגלי התכונות כדי להחליף את ההתקנה הנכונה בסביבה הנכונה.

בדיקת A / B

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

שחרור הקנרית

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

בחלקים הבאים ננסה לספק גישה מעשית להתמודדות עם התרחישים הנ"ל.

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

3. דגלי תכונה ברמת היישום

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

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

3.1. תכונות דגלים באמצעות פרופילי אביב

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

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

בשלנו JavaConfig נוכל לפרופיל את הרכיבים שלנו:

@Configuration מחלקה ציבורית ProfiledMiningConfig {@Bean @Profile ("! כורה ניסיוני") BitcoinMiner defaultMiner () {להחזיר DefaultBitcoinMiner חדש (); } @Bean @Profile ("כורה ניסיוני") BitcoinMiner experimentalMiner ציבורי () {להחזיר ExperimentalBitcoinMiner חדש (); }}

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

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

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

ברצוננו לאפשר את שתי התכונות בסביבת הקבלה שלנו (UAT). נוכל ליצור יישום- uat.yml קוֹבֶץ:

אביב: פרופילים: כוללים: כורה ניסיוני, כרטיסי ממשק U - עוד תצורה כאן

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

חשוב גם להבין כיצד לנצל זאת אביב.פרופילים.כלול. לְעוּמַת spring.profiles.active, הראשון מאפשר לנו לכלול פרופילים באופן תוסף.

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

3.2. תכונות דגלים באמצעות מאפיינים מותאמים אישית

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

עבור תרחישים אלה, מאפיינים מותאמים אישית עשויים להיות אופציה רצויה.

בוא נשכתב את הדוגמה הקודמת שלנו תוך ניצול @ConditionalOnProperty ומרחב השמות שלנו:

@Configuration מחלקה ציבורית CustomPropsMiningConfig {@Bean @ConditionalOnProperty (name = "features.miner.experimental", matchIfMissing = true) BitcoinMiner defaultMiner () {להחזיר DefaultBitcoinMiner חדש (); } @Bean @ConditionalOnProperty (name = "features.miner.experimental") ציבורי BitcoinMiner experimentalMiner () {להחזיר ExperimentalBitcoinMiner חדש (); }}

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

התוצאה דומה מאוד לזו שב -3.1, אך כעת, יש לנו את מרחב השמות שלנו. קיום מרחב השמות שלנו מאפשר לנו ליצור קבצי YAML / מאפיינים משמעותיים:

# [...] כמה תכונות תצורת אביב: כורה: ניסיוני: ממש ממשק משתמש: קלפים: נכון # [...] דגלי תכונה אחרים

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

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

בואו נדבר על יתרונות אחרים בגישה זו.

3.3. באמצעות @ConfigurationProperties

ברגע שנקבל קבוצה מוקדמת של מאפיינים, אנו יכולים ליצור POJO מעוטר ב- @ConfigurationProperties כדי לקבל טיפול פרוגרמטי בקוד שלנו.

בעקבות הדוגמה המתמשכת שלנו:

@Component @ConfigurationProperties (קידומת = "תכונות") ציבורי ConfigProperties {כורה MinerProperties פרטי; ממשקי משתמש פרטיים של UIP; // תקנים וקובעים סטנדרטיים מחלקה סטטית ציבורית MinerProperties {ניסיוני בוליאני פרטי; // גטררים וקובעים סטנדרטיים} UIProperties בכיתה סטטית ציבורית {כרטיסים בוליאניים פרטיים; // גטרים וקובעים סטנדרטיים}}

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

3.4. תצורת תכונות חשיפה

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

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

בואו ליצור נקודת קצה פשוטה שתשרת את התצורה שלנו כך שממשק המשתמש שלנו יוכל לשאול את ה- backend במידת הצורך:

@RestController מחלקה ציבורית FeaturesConfigController {מאפייני פרטי ConfigProperties; // constructor @GetMapping ("/ feature-flags") ציבורי ConfigProperties getProperties () {נכסי החזרה; }}

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

3.5. שמירה על ניקיון המחנה

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

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

4. דגלי תכונה גרגירים יותר

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

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

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

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

Togglz תומכת באסטרטגיות הפעלה שונות:

  1. שם משתמש: דגלים המשויכים למשתמשים ספציפיים
  2. השקה הדרגתית: דגלים מופעלים עבור אחוז מבסיס המשתמשים. זה שימושי עבור מהדורות קנריות, למשל כאשר אנו רוצים לאמת את התנהגות התכונות שלנו
  3. תאריך הוצאה: נוכל לתזמן הפעלת דגלים בתאריך ובשעה מסוימים. זה עשוי להיות שימושי עבור השקת מוצר, מהדורה מתואמת או הצעות והנחות
  4. לקוח IP: תכונות מסומנות מבוססות על כתובות IP של לקוחות. אלה עשויים להיות שימושיים בעת החלת התצורה הספציפית על לקוחות ספציפיים, בהתחשב בכך שיש להם כתובות IP סטטיות
  5. שרת IP: במקרה זה, ה- IP של השרת משמש כדי לקבוע אם יש להפעיל תכונה או לא. זה עשוי להיות שימושי גם לשחרורים של כנריות, עם גישה שונה במקצת מההשקה ההדרגתית - כמו כשאנחנו רוצים להעריך את השפעת הביצועים במקרים שלנו.
  6. מנוע Script: אנו יכולים לאפשר דגלי תכונות המבוססים על סקריפטים שרירותיים. זו ללא ספק האפשרות הגמישה ביותר
  7. מאפייני מערכת: נוכל להגדיר מאפייני מערכת מסוימים כדי לקבוע את מצבו של דגל התכונה. זה יהיה די דומה למה שהשגנו בגישה הכי פשוטה שלנו

5. סיכום

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

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

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

למטה השווינו כמה אלטרנטיבות. עוברים מהפתרון הפשוט ופחות גמיש לתבנית מתוחכמת יותר, אם כי מורכבת יותר.

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