ארכיטקטורת יישומי ווב: מהרעיון לייצור
דמיינו שהסטארטאפ שלכם גדל, העומס מוכפל כל שלושה חודשים, ומסד הנתונים מתחיל לפגר. היישום המונוליטי שבניתם על הברך כבר לא עומד בקצב. במקום לשכתב הכל מאפס, אתם שוכרים ארכיטקט. הם מסתכלים על הקוד הנוכחי, מזהים צווארי בקבוק, ומציעים תוכנית ריפקטורינג. אנחנו עושים את אותו הדבר — אבל לפני שהמערכת קורסת.
ארכיטקטורה היא קבוצה של החלטות שקשה לשנות מאוחר יותר. בחירת מסד נתונים, ארגון שירותים, אסטרטגיית קנה מידה — כל החלטה מציבה גבולות למה שניתן לבנות בעוד שנה בלי לשכתב. החלטה ארכיטקטונית טובה מתחשבת באילוצים אמיתיים: גודל הצוות, עומס צפוי, תקציב תפעול, ומהירות איטרציה של המוצר.
הניסיון שלנו הוא 12 שנים בעיצוב ארכיטקטורת ווב ולמעלה מ-50 פרויקטים מוצלחים. אנו מבטיחים פתרונות מתועדים עם ADRs ותוכניות מיגרציה. ארכיטקטורה מתוכננת היטב חוסכת עד 40% בעלויות תפעול ומחזירה את ההשקעה תוך 2–3 חודשים. שירות סקירת הארכיטקטורה שלנו מתחיל ב-$3,000 ומספק תוכנית מתועדת תוך 5 ימים. לקוחות בדרך כלל חוסכים $20,000–$100,000 בשנה בעלויות תפעול מופחתות.
היכן מתחיל העיצוב
לפני בחירת טכנולוגיות, עליכם לענות על שאלות מבניות:
- אופי העומס קובע את אסטרטגיית הקאש. עומס קריאה כבד (פורטל חדשות) — אסטרטגיה אחת, עומס כתיבה כבד (בורסה) — אחרת, מעורב (מסחר אלקטרוני) — שלישית.
- זמן השהיה מקובל. עבור פלטפורמת מסחר, 100ms הוא אסון; עבור CMS, זה מקובל.
- קפיצות תנועה. בלאק פריידי נותן עומס פי 100 — צריך autoscaling או ביצוע באמצעות תורים.
- גבולות הטרנזקציונליות קובעים אם ניתן לפצל את מסד הנתונים או שחייבים לשמור הכל קשור ל-ACID.
שכבות של יישום ווב טיפוסי
דיאגרמת ארכיטקטורה (לחצו להרחבה)
``` [Client] ↓ HTTPS [CDN / Edge Cache] ↓ Cache Miss [Load Balancer] ↓ [Application — N instances] ├── [Cache — Redis/Memcached] ├── [Queue — RabbitMQ/Kafka] └── [Database — Primary + Replica] ↓ [Object Storage — S3] ```כל שכבה פותרת בעיה אחת. CDN — נכסים סטטיים וקאש קצה. Load Balancer — חלוקה וסיום TLS. יישום — לוגיקה עסקית. Redis — נתונים חמים וסשנים. תור — משימות אסינכרוניות שלא ניתן לבצע בתוך בקשת HTTP.
מונולית מול מיקרוסרוויסים: באיזו גישה לבחור?
שאלה סטנדרטית שלעתים קרובות מקבלת תשובה שגויה. מונולית היא הבחירה הנכונה עבור רוב הפרויקטים החדשים עם צוותים של עד 15–20 אנשים. סיבות:
- טרנזקציה אחת על פני מספר אגרגטים ללא דפוסי saga.
- פריסה וניטור פשוטים (תהליך אחד, לוג אחד).
- ריפקטורינג ללא חוזי רשת.
- אין בעיות עקביות בנתונים מבוזרים.
מעבר למיקרוסרוויסים מוצדק כאשר צוותים עובדים על תחומים עצמאיים, פריסות מתחילות להפריע זו לזו, ושירותים ספציפיים דורשים קנה מידה שונה (למשל, שירות עיבוד תמונות מול API של CRUD). לפי ההערכות שלנו, מיקרוסרוויסים נותנים שיפור ביצועים של פי 1.5–2 עם פירוק נכון.
| קריטריון | מונולית | מיקרוסרוויסים |
|---|---|---|
| גודל צוות | עד 20 אנשים | 20+ אנשים |
| מורכבות פריסה | נמוכה | גבוהה (פריסת כל שירות) |
| טרנזקציונליות | פשוטה (ACID) | מורכבת (Saga, 2PC) |
| קנה מידה | אנכי | אופקי (לכל שירות) |
| עלות תפעול | נמוכה יותר | גבוהה יותר (אורקסטרציה, ניטור) |
[Клиент] ↓ HTTPS
[CDN / Edge Cache] ↓ Cache Miss
[Load Balancer] ↓
[Приложение — N инстансов]
├── [Кэш — Redis/Memcached]
├── [Очередь — RabbitMQ/Kafka]
└── [База данных — Primary + Replica]
↓
[Object Storage — S3]מבנה זה מאפשר לחלץ מודול לשירות בעת הצורך — הגבולות כבר מסומנים.
PostgreSQL: הבחירה הנכונה עבור רוב הפרויקטים
PostgreSQL פותר 90% מהמשימות. מודל רלציוני, JSONB לנתונים גמישים, חיפוש טקסט מלא, חלוקה, שכפול — הכל מובנה. להתחיל עם PostgreSQL ולשנות רק כאשר מתעוררות בעיות ספציפיות היא אסטרטגיה נכונה. לדוגמה, PostgreSQL עם JSONB מעבד שאילתות פי 2–3 ביעילות רבה יותר מ-MySQL תחת אותו עומס.
מאגרים נוספים לפי מטרה:
| משימה | כלי |
|---|---|
| סשנים, קאש, הגבלת קצב | Redis (עד פי 10 מהיר יותר משאילתות מסד נתונים) |
| חיפוש טקסט מלא עם פאקטות | Elasticsearch / OpenSearch |
| אנליטיקה ו-OLAP | ClickHouse |
| נתוני גרף | Neo4j / PostgreSQL עם CTE רקורסיבי |
| תורי הודעות | Redis Streams, RabbitMQ, Kafka |
כיצד לתכנן את סכמת הנתונים שלכם?
טעויות מוקדמות בסכמת הנתונים הן היקרות ביותר. כמה עקרונות:
השתמשו ב-UUID במקום serial/bigint עבור מזהים אם מתוכנן קנה מידה אופקי או API ציבורי. UUID v7 ניתן למיון ועובד היטב כאינדקס מקבץ.
Монолит с чёткими границами модулей:
src/
├── modules/
│ ├── catalog/ # продукты, категории, поиск
│ │ ├── domain/
│ │ ├── application/
│ │ └── infrastructure/
│ ├── orders/ # заказы, корзина, checkout
│ ├── users/ # аутентификация, профили
│ └── notifications/ # email, push, sms
└── shared/
├── events/ # доменные события (для будущей декомпозиции)
└── infrastructure/ # HTTP клиент, логгерמיגרציות — רק קדימה, לא תואמות לאחור. מחזור: הוספת עמודה (ניתנת ל-null) → פריסת קוד שכותב אותה → הפיכתה ל-NOT NULL עם DEFAULT → מחיקת העמודה הישנה.
קאש
שלוש רמות:
קאש HTTP — עבור משאבים ציבוריים. Cache-Control: public, max-age=3600, stale-while-revalidate=86400. CDN מאחסן בקצה, דפדפן — מקומית.
קאש יישום — Redis עבור נתונים שיקרים לחישוב. דפוס Cache-Aside:
-- UUID v7 генерируется в приложении
CREATE TABLE orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id),
status TEXT NOT NULL DEFAULT 'draft',
total_cents INTEGER NOT NULL,
currency CHAR(3) NOT NULL DEFAULT 'RUB',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- Триггер для updated_at (лучше чем в ORM)
CREATE TRIGGER set_updated_at
BEFORE UPDATE ON orders
FOR EACH ROW
EXECUTE FUNCTION trigger_set_timestamp();
קאש שאילתות — PostgreSQL מאחסן תוכניות שאילתות בעצמו. אינדקסים נכונים חשובים יותר מכל קאש ברמת היישום. בממוצע, קאש נכון מפחית את עומס מסד הנתונים ב-80% ומקצר את זמן התגובה ב-60%. זה מוביל להפחתה של 50% בעלויות התשתית עבור יישומים עם תנועה גבוהה.
עיבוד אסינכרוני
כל מה שלוקח יותר מ-200ms או עלול להיכשל צריך להיכנס לתור:
- שליחת דוא"ל
- יצירת PDF/תמונות
- אינטגרציות עם שירותים חיצוניים
- ייבוא נתונים
- חישוב מחדש של אגרגטים
async function getProduct(id: string): Promise<Product> {
const cached = await redis.get(`product:${id}`);
if (cached) return JSON.parse(cached);
const product = await db.product.findUniqueOrThrow({ where: { id } });
await redis.set(`product:${id}`, JSON.stringify(product), 'EX', 3600);
return product;
}
// Инвалидация при обновлении
async function updateProduct(id: string, data: Partial<Product>) {
const updated = await db.product.update({ where: { id }, data });
await redis.del(`product:${id}`);
// Инвалидируем зависимые ключи
await redis.del(`category:products:${updated.categoryId}`);
return updated;
}שימוש בתורים מפחית את שיעורי השגיאות ב-90% ומשפר את חוויית המשתמש.
ניטור
שלושה עמודים: לוגים, מדדים, טרייסים.
לוגים מובנים (Pino). צרפו request-id לכל הלוגים בתוך בקשה. מדדים בפורמט Prometheus: נקודת קצה /metrics עם מדדי RED (Rate, Errors, Duration) עבור כל נתיב.
טעויות אופייניות בעיצוב
- בחירת מיקרוסרוויסים "לעתיד" ללא צורך אמיתי.
- חוסר ב-ADRs — החלטות לא מתועדות, קשה לחזור אליהן.
- התעלמות מאילוצי צוות ותקציב.
- הבנה מאוחרת מדי של הצורך בקאש.
מה כלול בשירות עיצוב הארכיטקטורה
עיצוב ארכיטקטורה הוא תהליך איטרטיבי. השירות שלנו כולל:
- ניתוח דרישות ואילוצים (יומיים).
- בחירת מחסנית טכנולוגית עם נימוקים (ADRs).
- עיצוב סכמת נתונים ומיגרציות.
- תיעוד של פשרות והחלטות הניתנות לאימות.
- תוכנית קנה מידה וקאש.
- המלצות ניטור (לוגים, מדדים, טרייסים).
- גישה לדיאגרמות ארכיטקטורה ותבניות קוד.
- מפגש הדרכה לצוותכם על המחסנית הנבחרת.
- חודש תמיכה לאחר מסירה.
התוצאה אינה דיאגרמת Visio, אלא קבוצה של החלטות הניתנות לאימות עם נימוקי פשרה. סקירה ארכיטקטונית של פרויקט קיים אורכת 3–5 ימים.
צרו קשר כדי לקבל הערכה ראשונית של הארכיטקטורה של היישום שלכם. הזמינו סקירה ארכיטקטונית — היא תימשך 3–5 ימים, ותקבלו תוכנית ריפקטורינג מתועדת.







