פיתוח אתר מועדון כושר בעומס גבוה על 1С-Bitrix
לקוח מבקר באתר מועדון הכושר שלך ביום שני בערב, בוחר שיעור, לוחץ על "הזמן עכשיו" — ורואה "שגיאת שרת." או שלוח הזמנים נטען תוך 5 שניות. הארכיטקטורה לא מתוכננת לעומסי שיא. אנחנו צוות של מהנדסי 1С-Bitrix מוסמכים עם ניסיון של 8+ שנים, הפותר בעיות אלה במפתח אחד. אנחנו מתכננים מבנים בעלי עומס גבוה, מגדירים מטמון, משתלבים עם מערכות תשלום ו-CRM. אנחנו מבטיחים זמינות של 99.9% בשעות השיא. בואו נבחן את הפרויקט שלכם תוך יומיים עם בדיקה חינמית.
בעיות שאנחנו פותרים
תרחיש טיפוסי: לוח זמנים שבועי עם 300 שיעורים, 15 אולמות, 40 מאמנים. ללא אופטימיזציה נכונה, הסינון לוקח 800–1200 אלפיות השנייה. אנחנו מעבירים נתונים לבלוקים Highload — טבלאות שטוחות עם אינדקסים. זמן הסינון יורד ל-20–30 אלפיות השנייה — שיפור של פי 45 בהשוואה לבלוקי מידע רגילים. להלן נפרט את הצמתים המרכזיים של פרויקט כזה.
איך אנחנו מתכננים את לוח הזמנים לעומס גבוה
לוח הזמנים הוא האלמנט המרכזי של האתר. אם הוא איטי, הלקוח עובר לבוט טלגרם של המתחרה.
לאחסון לוח הזמנים, אנו משתמשים בבלוקים HL. בלוק מידע רגיל (מודל EAV) עם 300 שיעורים, 15 אולמות ו-40 מאמנים מייצר עשרות אלפי שורות בטבלת המאפיינים. סינון לפי שילוב של "אולם + יום + מאמן + כיוון" מביא לסדרה של JOINs שלוקחת 800–1200 אלפיות השנייה.
בלוק Highload הוא טבלת MySQL שטוחה. שורה אחת = שיעור אחד, כל השדות הם עמודות. הסינון משתמש באינדקסים רגילים.
מבנה HL FitnessSchedule:
| שדה | סוג | מטרה |
|---|---|---|
| UF_DATE | תאריך | תאריך השיעור |
| UF_TIME_START | מחרוזת | שעת התחלה (HH:MM) |
| UF_TIME_END | מחרוזת | שעת סיום |
| UF_HALL_ID | מספר שלם | מזהה אולם (קישור ל-HL FitnessHalls) |
| UF_TRAINER_ID | מספר שלם | מזהה מאמן |
| UF_DIRECTION_ID | מספר שלם | כיוון: יוגה, קרוספיט, בריכה... |
| UF_CAPACITY | מספר שלם | מספר משתתפים מקסימלי |
| UF_BOOKED | מספר שלם | מספר מוזמנים נוכחי |
| UF_STATUS | ספירה | פעיל / מבוטל / מלא |
| UF_IS_RECURRING | בוליאני | חוזר לפי תבנית |
| UF_TEMPLATE_ID | מספר שלם | קישור לתבנית לוח זמנים |
עבור שיעורים חוזרים, אנו משתמשים ב-HL נפרד ScheduleTemplate. סוכן cron מייצר שיעורים ספציפיים פעם בשבוע. זה מאפשר למאמן לבטל שיעור ספציפי מבלי לשבור את כל לוח הזמנים.
סינון בצד הלקוח דרך DataManager::getList():
$result = $entityClass::getList([
'filter' => [
'UF_DATE' => $selectedDate,
'UF_HALL_ID' => $hallId,
'UF_STATUS' => 'active',
],
'order' => ['UF_TIME_START' => 'ASC'],
]);בצד הלקוח, אנו משתמשים בגריד: אולמות על הציר האופקי, משבצות זמן על האנכי. בקשות AJAX דרך נקודת קצה REST מותאמת אישית.
למה בלוקים Highload עדיפים על בלוקי מידע
עם 50,000 רשומות, בלוק HL מעבד סינון תוך 20 אלפיות השנייה, בעוד בלוק מידע לוקח 900 אלפיות השנייה — הפרש של פי 45. זה נובע מהיעדר שכבות EAV ומהשימוש באינדקסים ישירים. בלוקים HL תומכים ב-$result = $entityClass::getList([ 'filter' => [ 'UF_DATE' => $selectedDate, 'UF_HALL_ID' => $hallId, 'UF_STATUS' => 'active', ], 'order' => ['UF_TIME_START' => 'ASC'], ]); , קריטי לכתיבות טרנזקציוניות. ארכיטקטורה זו יעילה פי 3 משימוש בבלוקי מידע רגילים להזמנות במקביל.
הזמנה מקוונת עם מגבלות קיבולת ורשימת המתנה
הזמנת שיעור היא פעולה טרנזקציונית שבודקת מגבלות, מטפלת בגישה במקביל ומספקת מנגנון רשימת המתנה.
תרחיש:
- הלקוח לוחץ על "הזמן עכשיו"
- המערכת בודקת:
SELECT ... FOR UPDATE - אם כן — יוצרת רשומה ב-HL
UF_BOOKED < UF_CAPACITY, מגדילה אתFitnessBooking - אם לא — מציעה להצטרף לרשימת ההמתנה
גישה במקביל נפתרת באמצעות טרנזקציה עם נעילת שורות. שני לקוחות הלוחצים בו-זמנית על שיעור עם מקום פנוי אחד יקבלו אישור ללא נעילה.
פתרון — SQL גולמי עם UF_BOOKED:
$connection = \Bitrix\Main\Application::getConnection();
$connection->startTransaction();
$row = $entityClass::getList([
'filter' => ['ID' => $scheduleId],
'select' => ['UF_BOOKED', 'UF_CAPACITY'],
// FOR UPDATE через raw SQL
])->fetch();
if ($row['UF_BOOKED'] < $row['UF_CAPACITY']) {
// создаём бронирование
$connection->commitTransaction();
} else {
$connection->rollbackTransaction();
// предлагаем waitlist
}ה-ORM של Bitrix אינו תומך ב-SELECT ... FOR UPDATE, לכן אנו עוטפים את הקטע הקריטי ב-SQL גולמי.
רשימת ההמתנה מיושמת דרך HL נפרד $connection = \Bitrix\Main\Application::getConnection(); $connection->startTransaction(); $row = $entityClass::getList([ 'filter' => ['ID' => $scheduleId], 'select' => ['UF_BOOKED', 'UF_CAPACITY'], // FOR UPDATE через raw SQL ])->fetch(); if ($row['UF_BOOKED'] < $row['UF_CAPACITY']) { // создаём бронирование $connection->commitTransaction(); } else { $connection->rollbackTransaction(); // предлагаем waitlist } . כשמישהו מבטל הזמנה, סוכן בודק את רשימת ההמתנה ומעביר את האדם הראשון בתור, שולח SMS/push. זה מפחית אי-הגעה ב-30%.
ביטול: המועדון מאפשר ביטול 2–4 שעות לפני ההתחלה. הלוגיקה במטפל האירועים משווה את זמן הביטול.
מכירת מנויים דרך מודול המכירות
מנויים אינם מוצרים פשוטים. יש להם תקופת תוקף, מגבלת ביקורים ויכולת הקפאה.
סוגי מנויים מיושמים כאלמנטים של בלוק מידע עם מאפיינים:
-
SELECT ... FOR UPDATE,FitnessWaitlist,DURATION_DAYS,VISIT_LIMIT,TYPE
ברכישה דרך FREEZE_ALLOWED, המנוי מתווסף לעגלה. לאחר התשלום, מטפל FREEZE_MAX_DAYS יוצר רשומה ב-HL Order::create() עם שדות: OnSaleOrderPaid, UserSubscription, UF_USER_ID, UF_START_DATE, UF_END_DATE, UF_VISITS_LEFT.
הקפאה: הלקוח לוחץ על "הקפא," המערכת בודקת מגבלות ומגדירה UF_IS_FROZEN. בביטול הקפאה, היא מחשבת מחדש UF_FREEZE_START.
אינטגרציה עם מערכות CRM של מועדונים
מועדוני כושר משתמשים ב-1С:Fitness Club או Mobifitness.
1С:Fitness Club — החלפה דרך CommerceML או REST API. אנו מסנכרנים שירותים, לוחות זמנים, לקוחות ומכירות. ההחלפה רצה דרך cron כל 15–30 דקות.
Mobifitness — REST API עם הרשאת טוקן. Bitrix משמש כחזית, Mobifitness כמערכת ראשית. HL UF_IS_FROZEN מאוכלס דרך סנכרון.
בחירת הארכיטקטורה תלויה במערכת הראשית.
חשבון אישי ללקוח
בנוי על מודול UF_END_DATE עם הרחבות:
- היסטוריית ביקורים — שאילתה מ-
FitnessSchedule - ביקורים שנותרו —
mainמ-FitnessBooking - חידוש מנוי — כפתור שיוצר הזמנה
- הקפאה/ביטול הקפאה
אימות דרך טלפון עם קוד SMS (מודול UF_VISITS_LEFT).
פרופילי מאמנים
מאמנים הם בלוק מידע עם קישור לכיוונים. בעמוד הפרטים, אנו מציגים את לוח השיעורים של השבוע הנוכחי (בקשת AJAX ל-UserSubscription).
לוחות זמנים ועלויות יישום
| היקף הפרויקט | הרכב | לוח זמנים | עלות משוערת |
|---|---|---|---|
| מועדון קטן (אולם 1, 5–7 כיוונים) | לוח זמנים, הזמנות, מנויים, חשבון אישי | 8–10 שבועות | $15,000–$25,000 |
| רשת של 3–5 מועדונים | רב-אתר, מסד נתונים מאוחד, אינטגרציה עם Mobifitness | 14–18 שבועות | $40,000–$60,000 |
| רשת גדולה (10+ מועדונים) | פורטל B2B, אפליקציה ניידת דרך Bitrix REST, תמחור מדורג מורכב | 20–28 שבועות | $80,000+ |
מה כלול בעבודה
- בדיקה חינמית של הארכיטקטורה והעומסים הנוכחיים
- תכנון מבנים בעלי עומס גבוה (בלוקים HL, אינדקסים, טריגרים) — שיפור ביצועים מובטח של פי 45
- פיתוח לוח זמנים, הזמנות מקוונות עם רשימת המתנה, חשבון אישי
- אינטגרציה עם 1С:Fitness Club או Mobifitness (מפתחים מוסמכים)
- הגדרת מטמון מתויג ומצב מרוכב
- חיבור שערי תשלום (YuKassa, Sber, ATOL) עם SLA של 99.9% זמינות
- הכשרת מנהלים והעברת תיעוד
- 3 חודשי תמיכה טכנית לאחר ההשקה
טעויות נפוצות בתכנון לוח זמנים
- שימוש בבלוקי מידע ללוח השיעורים — מוביל להאטות עם 300+ שיעורים.
- חוסר נעילות
messageservice— הזמנות כפולות. - אחסון רשימת ההמתנה באותו בלוק מידע — מסבך את הלוגיקה ומאט את הביצועים.
- התעלמות ממטמון — השרת קורס בעומס שיא.
- אין מערכת ראשית — קונפליקטים בנתונים בין האתר ל-CRM.
לצוות שלנו ניסיון מוסמך של 8+ שנים עם 1С-Bitrix, 15+ פרויקטים למועדוני כושר, ורקורד של 5 שנים. תזמון בעומס גבוה הוא המומחיות שלנו. לפני ההתחלה, הגדירו את מערכת התזמון הראשית ושער התשלום — אלה משפיעים על הארכיטקטורה. צרו קשר כדי לדון בפרטים ונתאים את הפתרון.

