19,162
הודעות תקועות בתור
Worker queue — עכשיו
60%
שיא שגיאות 5xx
בשעות העבודה
6/6
שרתים בשיא היום
ASG — הגיע למקסימום בשעות העומס
1,004
מול 1,000 מוקצים — פגע בתקרה
שורש הבעיה
שאילתות כבדות (10+ טבלאות ב-JOIN עם 6 תת-שאילתות) פוגעות בשרת RDS יחיד עם מטמון מנוטרל (Redis קיים אך מושבת בקוד), ללא ניהול חיבורים, וללא רפליקת קריאה. כל טעינת עמוד פונה ישירות למסד הנתונים. ה-IOPS פוגעים בתקרה המוקצית.
ארכיטקטורה נוכחית — לחצו על כל רכיב לפרטים
🔍משתמשים (app.candi.ai)
Vue 3 SPA + Chrome Extension
פרונטאנד — תקין
טכנולוגיה
Vue 3.2 + Vite 2.7 + Tailwind CSS
Chrome Extension
Manifest V3, LinkedIn injection
סטטוס
תקין — לא תלוי ב-backend
▼
🔍CloudFront CDN
2 הפצות — prod + dev — תקין
CloudFront — תקין
Prod
E2072E3OW33GOR → app.candi.ai
Dev
ECJCZI20BD5PG → devapp.candi.ai
Origin
S3 buckets (eu-west-2)
▼
🔍Classic
ELBבדיקת TCP:80 בלבד — לא מזהה 5xx
Classic ELB — בעייתי
שם
awseb-e-j-AWSEBLoa-1SYSHGALGDI3D
סוג
Classic (legacy — צריך ALB)
Health Check
TCP:80 — לא בודק אם האפליקציה עובדת
Unhealthy Threshold
5 כשלונות
HTTPS
Port 443 + ACM Certificate
Instances
כרגע 2 (היה 6 בשיא) — כולם InService
בעיה
TCP health check לא מזהה 5xx — מנתב לשרתים שבורים
▼
🔍EB — שרתים (max 6, הגיע ל-6/6 בשיא)
Flask 1.1.2 + Gunicorn (3 workers, 120s timeout) — Python 3.7 (EOL)
Elastic Beanstalk portal-prod
סביבה
portal-prod (eu-west-2)
פלטפורמה
Python 3.7, Amazon Linux 2 v3.5.6
ASG
min=1, max=6 — הגיע ל-6/6 בשיא היום, כרגע 2
Scaling metric
NetworkOut 6MB — חסר משמעות
Gunicorn
3 workers, timeout 120s
nginx
buffer 256MB, timeout 600s
CPU שרתים
~0.2% — ממתינים ל-DB
Health
Flapping Ok↔Severe כל 2 דקות
AZs
eu-west-2a, 2b (כרגע 2 instances)
⚡ ▼ ⚡
🔍מטמון Redis
קיים אבל מנוטרל בקוד!
ElastiCache Redis — קיים אבל לא בשימוש!
סטטוס
Cluster פעיל — portal-test-redis
סוג
cache.t4g.medium × 2 nodes, Redis 7.0.7
Endpoint
portal-test.vnzpci.ng.0001.euw2.cache.amazonaws.com
בעיה
הקוד מסומן כהערה — CACHE_TYPE='SimpleCache'
תוצאה
משלמים על Redis אבל לא משתמשים. כל בקשה הולכת ל-DB
תיקון
להסיר הערה מ-CACHE_REDIS_URL — דקות בודדות
🔍RDS Proxy
חסר — אין pooling
RDS Proxy — לא קיים
Log group
קיים (candirdsproxy) — הוסר?
תוצאה
סערת חיבורים בזמן scaling
תיקון
יצירת proxy + IAM — 3-4 שעות
🔍Read Replica
חסר — DB יחיד
Read Replica — לא קיים
תוצאה
SELECT כבד חוסם כתיבות
תיקון
יצירת replica — 2-3 שעות (30 דק sync)
⚡ ▼ ⚡
🔍MySQL 8.0 RDS (db.r6g.xlarge) — Multi-AZ
CPU: 99.7% | כתיבה: 465ms | חיבורים: 96 | IOPS: 1,004/1,000
RDS portal-prod-2-1 — צוואר הבקבוק
Instance
db.r6g.xlarge (4 vCPU, 32GB RAM)
Storage
100GB io1, 1,000 IOPS מוקצים
Parameter Group
default.mysql8.0 (לא מותאם)
Endpoint
portal-prod-2-1.c1cigjfemjsc.eu-west-2.rds.amazonaws.com
מדדים — שיא היום
Write Latency
674ms (בסיס: 1.3ms)
Read IOPS
1,004 / 1,000 — תקרה!
זיכרון פנוי
4.0 GB (מתוך 32GB)
🔍Worker — מת
19K הודעות, 100% שגיאות
portal-worker — קריסה מלאה
סוג
EB Worker Tier (SQS/HTTP)
Instance
m5a.large × 1 (ASG max=4)
Threads
1 process, 1 thread
VisibilityTimeout
43,200s (12 שעות!)
מקורות
EventBridge: send-emails, prod-contactout
תוצאה
מיילים לא נשלחים, משימות רקע תקועות
🔍Search ML
Flask + Flair + Transformers
Search Backend — תקין
Gunicorn
1 worker, 4 threads, 600s timeout
ML Stack
Flair, Sentence-Transformers, Gensim
🔍Lambda (Zappa)
Python 3.7 / Node 14 — EOL
Lambda Functions — EOL
portal-zappa-dev
Python 3.7, 512MB, 60s
proxyProd
Node 14, 128MB, 30s
queryTest
Node 14, 128MB, 30s
updateUsersCache
Node 14, 128MB, 3s
מדדי מסד הנתונים — 24 שעות אחרונות (כל 30 דקות)
CPU (%) — ממוצע ומקסימום
חיבורים למסד הנתונים
זמן כתיבה (Write Latency, ms)
זיכרון פנוי (GB)
CPU מסד הנתונים — מבט שבועי (כל שעה)
ממוצע שעתי — 7 ימים (15-22 מרץ)
IOPS — קריאה וכתיבה (שעתי)
Read IOPS — תקרה: 1,000
Write IOPS
פירוט נוסף
מעברי סטטוס — portal-prod היום (09:14–14:00 UTC)
תקיןמושפל (5-30%)חמור (33-100%)
60+ מעברי סטטוס — ממוצע מעבר כל 2 דקות
אזהרות EB לפי שעה — השבוע
השאילתה הבעייתית — מה רץ בכל טעינת עמוד
SELECT ... -- 30+ שדות
FROM job_applicant ja
LEFT JOIN job j
LEFT JOIN placement pl
LEFT JOIN (SELECT ... FROM interview GROUP BY ...) -- subquery 1: אגרגציית ראיונות
LEFT JOIN time_to_hire_view -- VIEW
LEFT JOIN contract co
LEFT JOIN candidate c
LEFT JOIN linkedin_profile p
LEFT JOIN (SELECT ... FROM job_applicant_history WHERE stage_change=1) -- subquery 2
LEFT JOIN (CTE: italent_blacklist_view + candidate + linkedin_profile) -- subquery 3: blacklist חברה
LEFT JOIN (job_applicant + job + contract + contract_blacklist + candidate + linkedin_profile) -- subquery 4: צירוף 6 טבלאות
LEFT JOIN (placement + job_applicant + candidate + job + contract) -- subquery 5: צירוף 5 טבלאות
LEFT JOIN (candidate + job_applicant + job_applicant_history) -- subquery 6: מועמדים פעילים
WHERE ... -- LIKE + JSON_EXTRACT + חיפוש skills
-- 8 צירופים + 6 תת-שאילתות + N+1 lazy loading
-- רץ בכל טעינת עמוד. בלי Cache. מול DB אחד. ה-IOPS פוגעים בתקרה.
מדדים עכשיו (Live) — portal-prod
בקשות (10 שניות)
10 (2xx בלבד)
Worker סטטוס
Severe — 1 שרת, 100% שגיאות
השוואת מדדים — לילה מול שיא
עלייה של פי 230 בזמן הכתיבה | IOPS פגע בתקרת 1,000 המוקצים
פערים מול ארכיטקטורת פרודקשן תקנית
| פער | פירוט | קטגוריה | חומרה |
| מטמון (Cache) | Redis קיים (portal-test-redis, 2 nodes) אבל מנוטרל בקוד — CACHE_TYPE='SimpleCache'. משלמים בלי להשתמש | ביצועים | קריטי |
| RDS Proxy | 18+ חיבורים ישירים ל-DB ללא pooling. סערת חיבורים בזמן scaling | ביצועים | קריטי |
| Read Replica | DB יחיד לקריאה+כתיבה. שאילתות SELECT כבדות (10+ JOINs) יכולות לעבור לרפליקה | ביצועים | קריטי |
| IOPS | io1 עם 1,000 מוקצים — היום הגענו ל-1,004. פגענו בתקרת הדיסק | ביצועים | קריטי |
| אפס התראות | לא מוגדרת אף התראת CloudWatch. בעיות מתגלות רק מדיווחי משתמשים | תפעול | קריטי |
| Worker | שרת 1, thread 1, 19K הודעות תקועות. VisibilityTimeout של 12 שעות. מיילים ומשימות תקועים | תפעול | קריטי |
| סיסמאות בקוד | DB password, SendGrid, OpenAI, Auth0, Metabase — הכל ב-config.py. גישה ל-Git = גישה לפרודקשן | אבטחה | קריטי |
| Python 3.7 | EOL יוני 2023. portal-prod רץ על גרסה ללא תמיכה כבר 3 שנים | אבטחה | קריטי |
| Node.js 14 | EOL אפריל 2023. 4 פונקציות Lambda ללא תמיכה | אבטחה | קריטי |
| Health Check | TCP:80 בלבד — בודק אם הפורט פתוח, לא אם האפליקציה עובדת. תעבורה מגיעה לשרתים שבורים | ביצועים | בינוני |
| Auto-scaling | מדד NetworkOut חסר משמעות. צוואר הבקבוק הוא DB, לא רשת | ביצועים | בינוני |
| Classic ELB | Legacy. חסר HTTP health checks, path routing, WebSocket. צריך ALB | תפעול | בינוני |
| Python 3.8 | EOL אוקטובר 2024. Workers רצים על גרסה ללא תמיכה | אבטחה | בינוני |
| Amazon Linux 2 | EOL יוני 2025 — בעוד 3 חודשים | אבטחה | בינוני |
| Gunicorn | 3 workers, timeout 120s. בקשה איטית חוסמת 1/3 מהשרת. nginx: 600s timeout | תפעול | בינוני |
| CI/CD | פריסה ידנית eb deploy לפרודקשן. אין בדיקות, staging או rollback | תפעול | בינוני |
| Flask + SQLAlchemy | גרסאות 1.x ישנות. גרסאות 3.x/2.x עם שיפורי ביצועים ואבטחה | אבטחה | בינוני |
| APScheduler | Cron jobs בתוך תהליך הווב. 6 שרתים = אותה משימה רצה 6 פעמים | תפעול | נמוך |
תוכנית פעולה
שלב 1 — עצירת הדימום 2-3 ימים ~$430/חודש
תשתית חירום — להחזיר את המערכת לעבודה
1
הפעלת מטמון Redis (כבר קיים!)
Cluster פעיל ומשלמים עליו. צריך רק להסיר הערה מ-CACHE_REDIS_URL בקוד ולפרוס. יספוג 50-80% מהשאילתות.
דקות בודדות — כבר משלמים על ה-cluster
2
הוספת RDS ProxyConnection pooling מנוהל. מונע סערת חיבורים בזמן scaling ומגן על ה-DB.3-4 שעות · $30/חודש
3
רפליקת קריאה + הגדלת IOPSRead replica לפיזור שאילתות SELECT כבדות. העלאת IOPS מ-1,000 ל-3,000+ (או מעבר ל-gp3).2-3 שעות · $350/חודש
4
תיקון Worker
הגדלת ASG ל-2+ שרתים, threads ל-4, הורדת VisibilityTimeout מ-12 שעות ל-5 דקות. פינוי 19K הודעות.
1-2 שעות · $60/חודש
5
בדיקת בריאות HTTPהוספת endpoint /health קליל (בלי DB). מעבר מ-TCP:80 ל-HTTP:80/health כדי לעצור ניתוב לשרתים שבורים.2-3 שעות · $0
6
התראות CloudWatchהגדרת 6 התראות: CPU>80%, חיבורים>50, שגיאות 5xx>10, עומק תור>100, זיכרון נמוך, IOPS>800.2-3 שעות · $0
שלב 2 — ייצוב 2-3 שבועות
אופטימיזציה, ניטור ואבטחה
7
Performance Insights + אינדקסיםהפעלת PI, איסוף נתונים 48 שעות, זיהוי Top 10 שאילתות איטיות, הוספת אינדקסים על עמודות JOIN ו-WHERE.3-5 ימים · $0
8
מעבר ל-ALBיצירת ALB + target group, הגדרת listeners HTTP/HTTPS, עדכון Route53, בדיקת SSL. תמיכה ב-HTTP health checks.1-2 ימים · $0 (מחליף את Classic)
9
העברת סיסמאות ל-Secrets Managerיצירת secrets ל-DB, SendGrid, OpenAI, Auth0. עדכון קוד לקרוא מ-SM. עדכון IAM roles.1-2 ימים · ~$5/חודש
10
תיקון Auto-scaling + Gunicorn
מדד: latency במקום NetworkOut. הגדלת workers ל-5, הורדת timeout ל-30 שניות. nginx timeout ל-60 שניות.
3-4 שעות · $0
שלב 3 — שורש הבעיה 2-3 חודשים
אופטימיזציית שאילתות ומודרניזציה
11
ריפקטור שאילתות כבדות
פירוק שאילתת ה-applicant (8 JOINs + 6 subqueries). Materialized Views ל-blacklists. Eager loading במקום N+1. דנורמליזציה של נתיבים חמים.
2-4 שבועות
12
שדרוג Python 3.7 → 3.11+
בדיקת תאימות dependencies, תיקון syntax שהוצא משימוש, שדרוג פלטפורמת EB. כולל Flask 1.x → 3.x ו-SQLAlchemy 2.x.
1-2 שבועות
13
שדרוג Lambda (Node 14 → 20)
עדכון runtime, בדיקת כל פונקציה, פריסה מחדש. 5 פונקציות — proxy, proxyProd, queryTest, updateUsersCache, portal-zappa-dev.
1-2 ימים
14
בחינת מעבר EB → ECS FargateDockerization, task definitions, ALB integration, CI/CD pipeline, DNS cutover. שליטה טובה יותר, פריסות מהירות יותר.2-4 שבועות
15
WAF + Rate Limitingהגנה מפני DDoS, הגבלת קצב בקשות, חסימת תבניות זדוניות. חיבור ל-ALB.1-2 ימים · ~$10/חודש
16
CI/CD PipelineGitHub Actions: build → test → deploy-to-staging → approve → deploy-to-prod. Rollback אוטומטי. לא יותר eb deploy ידני.2-3 ימים