שימור בexcutioner במקום בטיימר

TakeCtrl

New member
שימור בexcutioner במקום בטיימר

(השגיאה בכוונה ,חייב הומור מהתסכול)

יש לנו מנגנון דבילי שמסכרנן בין 2 Nodes כאשר כל 15 שניות כל אחד שולח לשני הודעה, אם אחד מהם לא מקבל אותה בזמן הוא מרכיז על השני כבר-מינן ותופס את מקומו ( active-passive) שמתי לב שאל אחד הלקוחות ההודעות האלה לא תמיד נשלחות בinterval של 15 שניות אלא לעיתים 20 שניות (יש לנו tolerance אבל ראבק כמה אפשר), בקוד ראיתי ש2 ההודעות נשלחות בעזרת TimerTask שיושב על אותו Timer
קראתי קצת וזה נראה עסק די שביר (מתבסס על thread אחד, ורגיש לשינויים בשעון). אז נראה לי הגיוני להשתמש בScheduledPoolExcuter
אין לנו אפשרות לשחזר את הזהו אצלנו.
 

selalerer

New member
זה נשמע מנגנון נורא שביר.

גם לא בטוח ש-Java זו השפה הנכונה למנגנון הזה, בהתחשב שה-GC יכול לעקב אותך פה ושם.
&nbsp
הייתי מגדיל משמעותית את ה-fault tolerance שלך. אם ה-15 שניות זה קריטי לך, אז תשלח הודעה כל 2 שניות ואם ב-15 שניות האחרונות לא קיבלת שום הודעה אז תניח שהשני מת.
&nbsp
אל תניח אחרי הודעה אבודה אחת בלבד שהשרת מת.
&nbsp
לא כתבת גם איך אתה שולח את ההודעה ואיך השרתים מתקשרים. TCP כנראה לא מומלץ לשימוש הזה.
 

TakeCtrl

New member
אכן, TCP עם ObjectOutputStream

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

selalerer

New member
ב-TCP ההודעות ניתנות לאפליקציה על פי הסדר שהן נשלחו.

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

choo

Active member
המנגנון שלך שגוי ביסודו בגלל הסימטריה שבו

&nbsp
כדי שמנגנון כזה יעבוד בצורה אמינה יותר, צריך לבנות לתוכו חוסר סימטריה, ולבנות לתוכו עוד ערוצי תקשורת.
&nbsp
לגבי חוסר סימטריה - הצד האקטיבי ישלח הודעה כל 3 שניות עם timeout קצר יותר, והצד הפאסיבי ישלח הודעה כל 5 שניות עם timeout ארוך יותר. כך, אגב, מקובל התוכנות מהסוג הזה.
&nbsp
שנית, אתה זקוק למנגנון fencing שיאפשר למנוע משני הצדדים להשתלט בו זמנית. לדוגמא, אם שני השרתים משתמשים באותו התקן איחסון (או לחליפין שניהם עובדים מול אותו בסיס נתונים) - אחרי שהצד הפאסיבי קיבל timeout, הוא מסמן על ההתקן המשותף שהוא עומד להשתלט, אבל נותן לשרת השני הזדמנות לסמן שהוא עדיין חי, דרך ההתקן המשותף. זה נועד לטפל במצב של split brain באמת התקשורת (ששני הצדדים איבדו את התקשורת הישירה ביניהם, אבל עדיין לשניהם יש גישה למשאב המשותף).
&nbsp
שיטה אחרת ל-fencing מכונה בשם STONISH:
Shoot The Other Node In The Head.
&nbsp
בשיטה הזו מנהלים ערוץ תקשורת נוסף (למשל באמצעות מנגנון IPMI) שמאפשר לשרת הראשון לכבות את השרת השני לפני שהוא משתלט. זה מונע מצב שבו שני השרתים הופכים לאקטיביים באותו זמן - במחיר של סיכון ששניהם יכבו אחד את השני באותו זמן.
&nbsp
בסופו של דבר, אין דרך מתמטית לפתור את בעית הסינכרון בקלאסטר שתבטיח שתמיד מישהו יתן שרות אבל אף פעם לא שניים יתנו שירות ותוך זמן מוגבל. צריך לבצע tuning בהתאם לצרכים הספציפיים ול-tolerance של הלקוחות של השירות שלך.
&nbsp
אחת הדרכים היעילות היא להשתמש בתוכנת cluster קיימת, במקום לפתח אחת כזו בעצמך. כמובן, גם בתוכנה כזו צריך לדעת להשתמש.
 

TakeCtrl

New member
ה stonish כבר ממומש אצלנו זו הסיבה שכל צד שולח לשני את המצב

שלו.. (active / passive) ואז השני מכבה את עצמו (או עולה במצב פאסיבי)
אני התכוונתי למצב שבו אין תקשורת פיזית בין השניים (בעיית רשת), אין שום דבר משותף (אחסון / db וכו') הם רק עובדים מול LB אבל אנחנו משתמשים בו רק לvip.
וזה לא נועד להיות cluster, רק אחד מהמכונות יכולה להיות פעילה. (כי הם מדברים עם מכשירים אמיתיים)
 

choo

Active member
זה בדיוק active-passive cluster

&nbsp
https://en.wikipedia.org/wiki/High-availability_cluster
&nbsp
ואם יש לכם שימוש ב-load balancer - הוא אמור להיות מסוגל לספק לכם את השירות הרלונטי של ה-failover בצורה דטרמיניסטית (כולל כיבוי של השרת ההיה אקטיבי, בעת ביצוע fail over)
&nbsp
להסתמך על כך שהשרת יכבה את עצמו נותן לך פתרון מאוד חלקי, שלא יעבוד ביותר מדי מצבים
 

TakeCtrl

New member
הlb לא בשליטה שלנו...

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

choo

Active member
בלי תמיכה חומרית מתאימה - לא תקבל fencing אמיתי

&nbsp
"השרת מכבה את עצמו" - זה לא stonish, וזה לא מספק אמצעי fencing של ממש.
שימוש ב-LB הוא דרך אחת להשיג את זה. שימוש ב-ipmi הוא דרך אחרת. שימוש ב-storage משותף הוא דרך שלישית.
&nbsp
אבל אי אפשר להשיג את זה בלי שום אמצעי חומרתי.
&nbsp
אתה צריך להבין את זה, ואז אתה צריך להסביר למנהלים שלך את זה, ואז אתם צריכים להציב דרישות מינימום כדי שתוכלו לספק שירות אמין ללקוחות. צוות התמיכה לא אמור להתקין תוכנה בצורה שלא מותאמת לדרישות המינימום, ואחרי שהמנהלים שלך יסבירו להם את זה, או שהם לא יעשו את זה, או שהלקוח יבין שהוא מקבל שירות חלקי ולא יצפה ל-HA של ממש.
 

TakeCtrl

New member
כשניסיתי להסביר שהמנגנון שלנו היום הוא שביר

אמרו לי שהם לא מקבלים מהשטח כל כך הרבה בעיות. יש להם עדיפות יותר גבוהה.. גם הQA ניסו להסביר להם, לא עזר.
למערכת שלנו אין אפילו DB, אע"פ שהיא צריכה כזה.
כשאני מדבר על כיבוי שרת , זה לא מדויק, זה לא כיבוי פיזי, הוא פשוט הופך את עצמו לpassive בגלל שהוא קיבל הודעה מהשני שהוא עבר להיות active.
&nbsp
אגב, כל המכונות האלו הן בכלל virtual appliance
 

choo

Active member
אז אם כך - חכה שתתחלנה להיות הרבה בעיות (אם וכאשר):

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

TakeCtrl

New member
לפי מה שנראה לי בנתיים זה מתמקד בבעיה של שליחה...

עוד לפני TCP יש thread אחד ששולח ל LinkBlockingQueue והשני שרץ כל הזמן ולקוח אותו, לפי הלוגים נראה שהוא לא בדיוק רץ בלולאה כל הזמן והtake לא מתעורר מייד.
&nbsp
מה שיותר גרוע כשהוא מואיל בטובו לשלוח הוא מעדכן שדה שמתי נשלח לאחרונה וthread השני שעושה את כל הבדיקות קורא מתי הפעם אחרונה שזה נשלח .. הבעיה השדה אפילו לא volatile כך שראיתי מקרים בלוג שהבדיקה והשליחה מתרחשים בדיוק באותה ms...
 

choo

Active member
אל תאשים אותו - האשמה תמיד של המפתחים (אתה אחד מהם)

&nbsp
אתה צריך להבין שהקוד הזה היום שלך, ללא קשר לשאלה אם אתה כתבת אותו או מישהו אחר כתב אותו. אי לכך - האחריות היא שלך, והבאגים הם שלך - לא של "החוט שמואיל בטובו".
 

TakeCtrl

New member
עזוב , אני צוחק,, זה מפלטי וזה כפרתי...

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

 

Grosseto

New member
וכל הזוועה הזאת בגלל ש NETBUI לא עובר ראוטר

אני הייתי ממליץ לך שהמרווח יהיה מספר ראשוני,
אולי זה יפתור את הבעיה
 

TakeCtrl

New member
לא, מה שיפתור את הבעיה הוא "החלפת דיסקט"

בנתיים אני ממשיך לגלות עוד בורות שם...
 
למעלה