הערכת תשתיות — פלטפורמת Candi

ניתוח יציבות, ביצועים ותוכנית שיקום
22 במרץ 2026 — candi.ai — AWS eu-west-2 (לונדון) — חשבון 855135735051
API — לא יציב, 5xx כל 2 דקות, health flapping Worker — קריסה מלאה, 19K הודעות תקועות פרונטאנד — תקין
99.7%
שיא CPU במסד הנתונים
כל יום השבוע האחרון
19,162
הודעות תקועות בתור
Worker queue — עכשיו
60%
שיא שגיאות 5xx
בשעות העבודה
6/6
שרתים בשיא היום
ASG — הגיע למקסימום בשעות העומס
1,004
Read IOPS שיא
מול 1,000 מוקצים — פגע בתקרה

שורש הבעיה

שאילתות כבדות (10+ טבלאות ב-JOIN עם 6 תת-שאילתות) פוגעות בשרת RDS יחיד עם מטמון מנוטרל (Redis קיים אך מושבת בקוד), ללא ניהול חיבורים, וללא רפליקת קריאה. כל טעינת עמוד פונה ישירות למסד הנתונים. ה-IOPS פוגעים בתקרה המוקצית.

ארכיטקטורה נוכחית — לחצו על כל רכיב לפרטים
🔍משתמשים (app.candi.ai)Vue 3 SPA + Chrome Extension
פרונטאנד — תקין
טכנולוגיה
Vue 3.2 + Vite 2.7 + Tailwind CSS
אחסון
S3 → CloudFront
אימות
Auth0 (JWT RS256)
Prod URL
app.candi.ai
Dev URL
devapp.candi.ai
Chrome Extension
Manifest V3, LinkedIn injection
סטטוס
תקין — לא תלוי ב-backend
🔍CloudFront CDN2 הפצות — prod + dev — תקין
CloudFront — תקין
Prod
E2072E3OW33GOR → app.candi.ai
Dev
ECJCZI20BD5PG → devapp.candi.ai
Origin
S3 buckets (eu-west-2)
סטטוס
Deployed — תקין
🔍Classic ELBבדיקת TCP:80 בלבד — לא מזהה 5xx
Classic ELB — בעייתי
שם
awseb-e-j-AWSEBLoa-1SYSHGALGDI3D
סוג
Classic (legacy — צריך ALB)
Health Check
TCP:80 — לא בודק אם האפליקציה עובדת
HC Interval
10 שניות
Unhealthy Threshold
5 כשלונות
Cross-Zone
כן
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
Instance type
m6i.large
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 — לא קיים
סטטוס
DB אחד לכל התעבורה
תוצאה
SELECT כבד חוסם כתיבות
תיקון
יצירת replica — 2-3 שעות (30 דק sync)
⚡ ▼ ⚡
🔍MySQL 8.0 RDS (db.r6g.xlarge) — Multi-AZCPU: 99.7% | כתיבה: 465ms | חיבורים: 96 | IOPS: 1,004/1,000
RDS portal-prod-2-1 — צוואר הבקבוק
Engine
MySQL 8.0.42
Instance
db.r6g.xlarge (4 vCPU, 32GB RAM)
Storage
100GB io1, 1,000 IOPS מוקצים
Multi-AZ
כן
Encrypted
כן
Perf. Insights
כבוי
Parameter Group
default.mysql8.0 (לא מותאם)
Backup
7 ימים
Endpoint
portal-prod-2-1.c1cigjfemjsc.eu-west-2.rds.amazonaws.com
מדדים — שיא היום
CPU
99.7% (בסיס: 15%)
חיבורים
96 (בסיס: 11)
Write Latency
674ms (בסיס: 1.3ms)
Read IOPS
1,004 / 1,000 — תקרה!
Write IOPS
871
זיכרון פנוי
4.0 GB (מתוך 32GB)
🔍Worker — מת19K הודעות, 100% שגיאות
portal-worker — קריסה מלאה
סטטוס
Red / Severe
סוג
EB Worker Tier (SQS/HTTP)
Instance
m5a.large × 1 (ASG max=4)
Threads
1 process, 1 thread
בתור (SQS)
19,162 הודעות
DLQ
1 הודעה
VisibilityTimeout
43,200s (12 שעות!)
מקורות
EventBridge: send-emails, prod-contactout
תוצאה
מיילים לא נשלחים, משימות רקע תקועות
🔍Search MLFlask + Flair + Transformers
Search Backend — תקין
סביבה
search-test (EB)
Instance
m6i.xlarge
Gunicorn
1 worker, 4 threads, 600s timeout
ML Stack
Flair, Sentence-Transformers, Gensim
Data
S3 + DynamoDB
URL
devsearch.candi.ai
סטטוס
Health: Green
🔍Lambda (Zappa)Python 3.7 / Node 14 — EOL
Lambda Functions — EOL
portal-zappa-dev
Python 3.7, 512MB, 60s
proxy
Node 14, 128MB, 30s
proxyProd
Node 14, 128MB, 30s
queryTest
Node 14, 128MB, 30s
updateUsersCache
Node 14, 128MB, 3s
בעיה
כל הרantimes ב-EOL
מדדי מסד הנתונים — 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
סטטוס כללי
OK (3 שרתים)
P50 Latency
21ms
P95 Latency
2,173ms
P99 Latency
2,879ms
בקשות (10 שניות)
10 (2xx בלבד)
Worker סטטוס
Severe — 1 שרת, 100% שגיאות
הודעות בתור
19,162
השוואת מדדים — לילה מול שיא
CPU
~15%
לילה
99.7%
שיא
חיבורים
11
לילה
96
שיא
Write Latency
1.3ms
לילה
674ms
שיא
Read IOPS
0.3
לילה
1,004
שיא (תקרה!)
Write IOPS
0.8
לילה
871
שיא
זיכרון פנוי
4.4 GB
לילה
4.0 GB
שיא
שגיאות 5xx
0%
לילה
60%
שיא
עלייה של פי 230 בזמן הכתיבה | IOPS פגע בתקרת 1,000 המוקצים
פערים מול ארכיטקטורת פרודקשן תקנית
פערפירוטקטגוריהחומרה
מטמון (Cache)Redis קיים (portal-test-redis, 2 nodes) אבל מנוטרל בקוד — CACHE_TYPE='SimpleCache'. משלמים בלי להשתמשביצועיםקריטי
RDS Proxy18+ חיבורים ישירים ל-DB ללא pooling. סערת חיבורים בזמן scalingביצועיםקריטי
Read ReplicaDB יחיד לקריאה+כתיבה. שאילתות SELECT כבדות (10+ JOINs) יכולות לעבור לרפליקהביצועיםקריטי
IOPSio1 עם 1,000 מוקצים — היום הגענו ל-1,004. פגענו בתקרת הדיסקביצועיםקריטי
אפס התראותלא מוגדרת אף התראת CloudWatch. בעיות מתגלות רק מדיווחי משתמשיםתפעולקריטי
Workerשרת 1, thread 1, 19K הודעות תקועות. VisibilityTimeout של 12 שעות. מיילים ומשימות תקועיםתפעולקריטי
סיסמאות בקודDB password, SendGrid, OpenAI, Auth0, Metabase — הכל ב-config.py. גישה ל-Git = גישה לפרודקשןאבטחהקריטי
Python 3.7EOL יוני 2023. portal-prod רץ על גרסה ללא תמיכה כבר 3 שניםאבטחהקריטי
Node.js 14EOL אפריל 2023. 4 פונקציות Lambda ללא תמיכהאבטחהקריטי
Health CheckTCP:80 בלבד — בודק אם הפורט פתוח, לא אם האפליקציה עובדת. תעבורה מגיעה לשרתים שבוריםביצועיםבינוני
Auto-scalingמדד NetworkOut חסר משמעות. צוואר הבקבוק הוא DB, לא רשתביצועיםבינוני
Classic ELBLegacy. חסר HTTP health checks, path routing, WebSocket. צריך ALBתפעולבינוני
Python 3.8EOL אוקטובר 2024. Workers רצים על גרסה ללא תמיכהאבטחהבינוני
Amazon Linux 2EOL יוני 2025 — בעוד 3 חודשיםאבטחהבינוני
Gunicorn3 workers, timeout 120s. בקשה איטית חוסמת 1/3 מהשרת. nginx: 600s timeoutתפעולבינוני
CI/CDפריסה ידנית eb deploy לפרודקשן. אין בדיקות, staging או rollbackתפעולבינוני
Flask + SQLAlchemyגרסאות 1.x ישנות. גרסאות 3.x/2.x עם שיפורי ביצועים ואבטחהאבטחהבינוני
APSchedulerCron jobs בתוך תהליך הווב. 6 שרתים = אותה משימה רצה 6 פעמיםתפעולנמוך
תוכנית פעולה
שלב 1 — עצירת הדימום 2-3 ימים ~$430/חודש

תשתית חירום — להחזיר את המערכת לעבודה

1
הפעלת מטמון Redis (כבר קיים!)
Cluster פעיל ומשלמים עליו. צריך רק להסיר הערה מ-CACHE_REDIS_URL בקוד ולפרוס. יספוג 50-80% מהשאילתות.
דקות בודדות — כבר משלמים על ה-cluster
2
הוספת RDS Proxy
Connection pooling מנוהל. מונע סערת חיבורים בזמן scaling ומגן על ה-DB.
3-4 שעות · $30/חודש
3
רפליקת קריאה + הגדלת IOPS
Read 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
בחינת מעבר EBECS Fargate
Dockerization, task definitions, ALB integration, CI/CD pipeline, DNS cutover. שליטה טובה יותר, פריסות מהירות יותר.
2-4 שבועות
15
WAF + Rate Limiting
הגנה מפני DDoS, הגבלת קצב בקשות, חסימת תבניות זדוניות. חיבור ל-ALB.
1-2 ימים · ~$10/חודש
16
CI/CD Pipeline
GitHub Actions: build → test → deploy-to-staging → approve → deploy-to-prod. Rollback אוטומטי. לא יותר eb deploy ידני.
2-3 ימים