בדיקות עומס עם Gatling: Scala, CI/CD ומדדי ביצועים

כאשר גרסה חדשה קורסת את מערכת הייצור בעומס שיא והצוות אינו יכול לשחזר את התרחיש ידנית, הגיע הזמן לשקול בדיקות עומס. אנו מגדירים זאת עם Gatling: אנו מתארים תרחישים מורכבים ב-Scala, משלבים אותם ב-CI/CD ומקבלים דוחות HTML ברורים. הצוות שלנו מספק את הפרויקט במפתח מלא—מביקורת ועד תמיכה—ומבטיח פעולה אמינה ועוזר לזהות צווארי בקבוק לפני שהם הופכים לבעיה.

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

שפרו ביצועים עם מבחני עומס של Gatling

דמיינו שאתם מפרסמים גרסה חדשה, ושעה לאחר מכן הייצור קורס תחת עומס שיא. הצוות מנסה לשחזר את התרחיש ידנית—ללא הצלחה. נשמע מוכר? זה בדיוק הרגע שבו אתם צריכים מבחני עומס עם Gatling. אנו מגדירים אותו עבור התשתית שלכם: מתארים תרחישים עם מצב (stateful) ב-Scala, משתלבים ב-CI/CD, ומייצרים דוחות HTML עם אחוזונים. עם ניסיון של למעלה מעשור בתחום, סיפקנו 50+ פרויקטים במסחר אלקטרוני, פינטק ו-SaaS. מקרה אחד: לאחר הגדרת Gatling, לקוח צמצם את זמן זיהוי צוואר הבקבוק ב-40% ומנע שתי תקלות משמעותיות, וחסך לפחות 15,000 דולר באובדן הכנסות פוטנציאלי.

למה Gatling על פני JMeter או k6

JMeter נוח לאב-טיפוס מהיר עם GUI, אבל קובצי XML לתרחישים מורכבים הופכים לסיוט בסקירת קוד. k6 מצוין לבדיקות ממוקדות מפתחים ב-JavaScript. Gatling מצטיין בתרחישים הדורשים: תרחישים מורכבים עם מצב (stateful) וקורלציית טוקנים, מקביליות גבוהה (עשרות אלפי משתמשים וירטואליים למכונה באמצעות Akka/Netty), ודוחות HTML מובנים עם אחוזונים ופירוט לפי בקשה. לפי התיעוד הרשמי של Gatling (תיעוד Gatling), מופע בודד יכול להתמודד עם עד 100 אלף משתמשים במקביל, בעוד JMeter בדרך כלל מוגבל לכ-30 אלף. זה הופך את Gatling ליעיל פי 2-3 בטיפול במשתמשים במקביל—בנצ'מרקים מאשרים זאת. מעבר ל-Gatling מקצר את זמן זיהוי צוואר הבקבוק ב-30–50% בהשוואה לסקריפטים של JMeter.

איך Gatling פותר קורלציית טוקנים

בפרויקט מסחר אלקטרוני, בדקנו את הזרימה: חיפוש → דף מוצר → הוספה לעגלה → תשלום. JMeter התקשה עם קורלציית טוקני CSRF בין בקשות. Gatling טיפל בזה באלגנטיות עם css("#csrf-token").ofType[String].saveAs("csrfToken") ו-header("X-CSRF-Token", "#{csrfToken}") הכל בתוך תרחיש אחד.

מבנה הפרויקט והתרחיש

מבנה פרויקט Gatling סטנדרטי:

gatling-tests/
├── src/test/scala/
│   ├── simulations/
│   │   └── CheckoutSimulation.scala
│   └── config/
│       └── Config.scala
├── src/test/resources/
│   ├── gatling.conf
│   ├── feeders/
│   │   └── users.csv
│   └── bodies/
│       └── checkout-payload.json
└── pom.xml # или build.sbt

תרחיש בסיסי עם פרופיל עומס ריאלי:

class CheckoutSimulation extends Simulation {
  val httpProtocol = http
    .baseUrl("https://api.example.com")
    .acceptHeader("application/json")
    .contentTypeHeader("application/json")
    .shareConnections

  val userFeeder = csv("feeders/users.csv").circular

  val checkoutScenario = scenario("Checkout Flow")
    .feed(userFeeder)
    .exec(
      http("Login")
        .post("/auth/login")
        .body(StringBody("""{"email":"#{email}","password":"#{password}"}"""))
        .check(jsonPath("$.token").saveAs("authToken"))
        .check(status.is(200))
    )
    .pause(1, 3)
    .exec(
      http("Add to Cart")
        .post("/cart/items")
        .header("Authorization", "Bearer #{authToken}")
        .body(ElFileBody("bodies/checkout-payload.json"))
        .check(status.is(201))
        .check(jsonPath("$.cartId").saveAs("cartId"))
    )
    .pause(2, 5)
    .exec(
      http("Checkout")
        .post("/orders")
        .header("Authorization", "Bearer #{authToken}")
        .body(StringBody("""{"cartId":"#{cartId}","payment":"card"}"""))
        .check(status.in(200, 201))
    )

  setUp(
    checkoutScenario.inject(
      rampUsersPerSec(1).to(50).during(2.minutes),
      constantUsersPerSec(50).during(5.minutes),
      rampUsersPerSec(50).to(1).during(1.minute)
    )
  ).protocols(httpProtocol)
    .assertions(
      global.responseTime.percentile(95).lt(500),
      global.failedRequests.percent.lt(1)
    )
}

פרופיל ה-gatling-tests/ ├── src/test/scala/ │ ├── simulations/ │ │ └── CheckoutSimulation.scala │ └── config/ │ └── Config.scala ├── src/test/resources/ │ ├── gatling.conf │ ├── feeders/ │ │ └── users.csv │ └── bodies/ │ └── checkout-payload.json └── pom.xml # или build.sbt הוא סטנדרטי לבדיקות דמויות ייצור. עומס מדורג של "רמה" (plateau) מאפשר ליישומי JVM ולמטמוני מסדי נתונים להתחמם, מה שקרוב יותר לתעבורה אמיתית מאשר קפיצה מיידית.

איך להגדיר מבחני עומס של Gatling

  1. הגדירו זרימות משתמש על בסיס לוגי ייצור או אנליטיקה.
  2. כתבו תרחישי Scala באמצעות ה-DSL של Gatling.
  3. הגדירו מזיני נתונים (CSV, JSON) עם נתוני בדיקה ריאליסטיים.
  4. הקימו צינור CI/CD עם ריצות מתוזמנות.
  5. הריצו בדיקות ונתחו דוחות HTML.
  6. בצעו איטרציות על צווארי בקבוק ובצעו אופטימיזציה.

אילו מדדים מבטיחים יציבות בייצור?

דוח ה-HTML של Gatling הוא מהטובים בתעשייה. מדדים מרכזיים: חביון p50/p75/p95/p99 לכל בקשה, תפוקה (בקשות/שנייה), משתמשים פעילים לאורך זמן. דפוס שאנו רואים באופן קבוע: p50 = 120ms, p99 = 4500ms. זהו "זנב ארוך"—בקשות איטיות שאינן נראות בממוצע. נגרם בדרך כלל מדלדול מאגר חיבורי מסד נתונים, שאילתות N+1 תחת עומס, או השהאות GC ביישומי JVM.

מדד מה הוא מראה פעולה בחריגה
חביון p50 מהירות תגובה טיפוסית אם > 1 שנייה—בעיה בקוד או בתשתית
חביון p99 1% הגרוע ביותר של הבקשות גידול יחסית ל-p50 פי 5 ומעלה—בדקו מאגר חיבורים, GC, הגבלת קצב
תפוקה (בקשות/שנייה) רוחב פס ירידה תחת עומס קבוע—צוואר בקבוק ביישום
משתמשים פעילים מספר משתמשים וירטואליים אם לא עולה עם הגדלת ההזרקה—שגיאת תרחיש או מגבלת משאבים

אם class CheckoutSimulation extends Simulation { val httpProtocol = http .baseUrl("https://api.example.com") .acceptHeader("application/json") .contentTypeHeader("application/json") .shareConnections val userFeeder = csv("feeders/users.csv").circular val checkoutScenario = scenario("Checkout Flow") .feed(userFeeder) .exec( http("Login") .post("/auth/login") .body(StringBody("""{"email":"#{email}","password":"#{password}"}""")) .check(jsonPath("$.token").saveAs("authToken")) .check(status.is(200)) ) .pause(1, 3) .exec( http("Add to Cart") .post("/cart/items") .header("Authorization", "Bearer #{authToken}") .body(ElFileBody("bodies/checkout-payload.json")) .check(status.is(201)) .check(jsonPath("$.cartId").saveAs("cartId")) ) .pause(2, 5) .exec( http("Checkout") .post("/orders") .header("Authorization", "Bearer #{authToken}") .body(StringBody("""{"cartId":"#{cartId}","payment":"card"}""")) .check(status.in(200, 201)) ) setUp( checkoutScenario.inject( rampUsersPerSec(1).to(50).during(2.minutes), constantUsersPerSec(50).during(5.minutes), rampUsersPerSec(50).to(1).during(1.minute) ) ).protocols(httpProtocol) .assertions( global.responseTime.percentile(95).lt(500), global.failedRequests.percent.lt(1) ) } גדל ליניארית עם העומס—צוואר בקבוק ביישום. אם הוא קופץ ב-RPS מסוים—פגיעה במשאב ספציפי: CPU, I/O, מאגר חיבורים.

איך להגדיר השקה מבוזרת ל-100 אלף משתמשים ומעלה

לעומסים כבדים (100 אלף משתמשים וירטואליים ומעלה), נדרשת הרצה מבוזרת. Gatling Enterprise תומך בכך באופן מובנה; הגרסה בקוד פתוח דורשת תיאום ידני: מספר מופעים, איחוד קבצי rampUsersPerSec → constantUsersPerSec → rampDown באמצעות responseTime.percentile(95). לרוב המשימות, מכונה אחת עם 8+ ליבות CPU ו-16GB RAM מספיקה—Gatling מתמודד עם 50-100 אלף משתמשים במקביל על חומרה כזו.

אינטגרציית CI/CD ותשתית השקה

עבור GitLab CI עם פרסום דוחות:

---
# .gitlab-ci.yml
load-test:
  stage: performance
  image: gatling/gatling:3.10.3
  script:
    - gatling.sh -sf src/test/scala -rf target/gatling -s simulations.CheckoutSimulation
  artifacts:
    paths:
      - target/gatling/
    reports:
      performance:
        - target/gatling/**/simulation.log
  only:
    - schedules # запуск по расписанию, не на каждый коммит

התצורה של GitHub Actions דומה: השתמשו ב-action simulation.log או בתמונת Docker מותאמת. חשוב: אל תריצו מבחני עומס על כל commit—זה מעמיס על הצינור ומעוות תוצאות. אופטימלי: מתוזמן או לפני שחרור.

ניתוח תוצאות וממצאים טיפוסיים

הדוח של Gatling חושף חריגות במהירות. לדוגמה, אם p95 גדל בצורה חלקה—בעיית קנה מידה ביישום. אם יש קפיצה חדה ב-RPS מסוים—חפשו דלדול מאגר חיבורים או GC. המהנדסים שלנו מבטיחים שאחרי הגדרת Gatling, תקבלו רשימה ברורה של צווארי בקבוק עם המלצות. החיסכון ממניעת תקלה אחת יכול לעלות על עלות ההגדרה כולה פי עשרה.

מה כלול בשירות הגדרת Gatling שלנו

  • פיתוח 1-5 תרחישי זרימת משתמש ריאליסטיים
  • הגדרת מזיני נתונים (CSV, JSON)
  • אינטגרציה עם GitLab CI או GitHub Actions
  • הצהרות מותאמות אישית וספי מעבר/כישלון
  • ביצוע בדיקה ראשונה וניתוח דוח מפורט
  • תיעוד ממצאים והמלצות
  • הדרכה של שעה לצוות שלכם
  • שבועיים של תמיכה לאחר ההגדרה

מה ההגדרה שלנו כוללת

הגדרת Gatling שלנו לפרויקט שלכם כוללת: פיתוח תרחישים לזרימות משתמש אמיתיות (בהתבסס על לוגי גישה או אנליטיקה), הגדרת מזיני נתונים, אינטגרציה לצינור CI/CD, הגדרת הצהרות והתראות על הידרדרות, וריצה ראשונה עם ניתוח והמלצות. צרו קשר לבדיקת תשתית—קבלו תוכנית מבחני עומס מוכנה. קבלו ייעוץ על הגדרת מבחני עומס—זה עוזר למנוע השבתות ולחסוך בתקציב.

היקף המשימה לוח זמנים עלות
1-2 תרחישים פשוטים, ללא אינטגרציית CI 1-2 ימים החל מ-$1,000
3-5 תרחישים, אינטגרציית GitLab/GitHub CI 3-5 ימים החל מ-$3,000
תרחישים מורכבים עם מצב + השקה מבוזרת 1-2 שבועות החל מ-$5,000

העלות מחושבת באופן אישי לאחר בדיקת התשתית ודרישות הבדיקה שלכם.