हमारी Performance & Scalability श्रृंखला का हिस्सा
पूरी गाइड पढ़ेंk6 लोड परीक्षण: लॉन्च से पहले अपने एपीआई का तनाव-परीक्षण करें
लोड परीक्षण के बिना किसी उत्पाद की शिपिंग एक जुआ है। आप अपने ब्रेकिंग पॉइंट को तब तक नहीं जानते जब तक कि उपयोगकर्ता इसे आपके लिए नहीं ढूंढ लेते - आमतौर पर किसी उत्पाद लॉन्च के दौरान, किसी वायरल पल या बिक्री में बढ़ोतरी के दौरान। k6 एक आधुनिक लोड परीक्षण उपकरण है जो आपको जावास्क्रिप्ट में परीक्षण लिखने, उन्हें सीआई से चलाने और उपयोगकर्ताओं से पहले अपनी प्रदर्शन सीमा का पता लगाने की सुविधा देता है। यह डेवलपर-अनुकूल, संसाधन-कुशल है (k6 गोरआउट्स का उपयोग करता है, थ्रेड्स का नहीं), और वास्तविक समय मेट्रिक्स के लिए ग्राफाना और प्रोमेथियस के साथ स्पष्ट रूप से एकीकृत होता है।
यह मार्गदर्शिका जटिल बहु-परिदृश्य लोड परीक्षणों, कस्टम मेट्रिक्स, थ्रेशोल्ड, सीआई एकीकरण और Node.js/NestJS API के लिए उत्पादन-सुरक्षित परीक्षण पैटर्न के माध्यम से पहली स्क्रिप्ट से k6 को कवर करती है।
मुख्य बातें
- k6 स्क्रिप्ट जावास्क्रिप्ट हैं लेकिन गो रनटाइम में चलती हैं - कोई Node.js API नहीं (कोई
requireनहीं, कोईfsनहीं, कोईsetTimeoutनहीं)- वर्चुअल उपयोगकर्ता (वीयू) समवर्ती सिम्युलेटेड उपयोगकर्ता हैं; पुनरावृत्तियाँ व्यक्तिगत स्क्रिप्ट निष्पादन हैं
- दौड़ने से पहले हमेशा थ्रेसहोल्ड सेट करें - थ्रेसहोल्ड विफल होने पर परीक्षण रुक जाता है और सीआई विफल हो जाता है
- वास्तविक ट्रैफ़िक पैटर्न को मॉडल करने के लिए परिदृश्यों (स्थिर-वस, रैंपिंग-वस, निरंतर-आगमन-दर) का उपयोग करें
- ऑप्स के साथ समन्वय किए बिना परीक्षण उत्पादन को कभी भी लोड न करें - स्टेजिंग या उत्पादन क्लोन के विरुद्ध परीक्षण करें
http_req_durationमीट्रिक आपकी प्राथमिक SLA मीट्रिक है - p95 और p99 औसत से अधिक मायने रखते हैं- अपने k6 धावकों की दर सीमित करें - लोड परीक्षण ट्रैफ़िक से आपकी दर सीमा का बजट समाप्त नहीं होना चाहिए
- भौगोलिक क्षेत्रों में वितरित लोड परीक्षण के लिए k6 क्लाउड या ग्राफाना k6 का उपयोग करें
इंस्टालेशन और पहली स्क्रिप्ट
# macOS
brew install k6
# Ubuntu/Debian
sudo gpg -k && sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update && sudo apt-get install k6
# Windows (via Chocolatey)
choco install k6
आपकी पहली k6 स्क्रिप्ट:
// k6/homepage-load.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
// Custom metric: error rate
const errorRate = new Rate('error_rate');
export const options = {
// Ramp up to 50 VUs over 1 minute, hold 2 minutes, ramp down
stages: [
{ duration: '1m', target: 50 },
{ duration: '2m', target: 50 },
{ duration: '1m', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500', 'p(99)<1000'], // 95th pct < 500ms
http_req_failed: ['rate<0.01'], // Less than 1% errors
error_rate: ['rate<0.01'],
},
};
const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';
export default function () {
const res = http.get(`${BASE_URL}/`);
const ok = check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
'body contains ECOSIRE': (r) => r.body.includes('ECOSIRE'),
});
errorRate.add(!ok);
sleep(1); // 1 second think time between iterations
}
इसे चलाएँ:
k6 run k6/homepage-load.js
k6 run --env BASE_URL=https://staging.ecosire.com k6/homepage-load.js
k6 run --vus 100 --duration 30s k6/homepage-load.js # Quick smoke test
प्रमाणीकरण के साथ एपीआई लोड परीक्षण
// k6/api-load.js
import http from 'k6/http';
import { check, group, sleep } from 'k6';
import { Counter, Trend } from 'k6/metrics';
const apiCalls = new Counter('api_calls');
const authDuration = new Trend('auth_duration');
export const options = {
scenarios: {
// Constant arrival rate: 100 requests/second regardless of VU count
constant_load: {
executor: 'constant-arrival-rate',
rate: 100,
timeUnit: '1s',
duration: '3m',
preAllocatedVUs: 50,
maxVUs: 200,
},
},
thresholds: {
http_req_duration: ['p(95)<300', 'p(99)<500'],
'http_req_duration{type:api}': ['p(95)<200'],
http_req_failed: ['rate<0.005'], // 0.5% error budget
},
};
const BASE_URL = __ENV.BASE_URL || 'http://localhost:3001';
// setup() runs once before VUs start
export function setup() {
// Authenticate and return tokens for VUs to use
const loginRes = http.post(`${BASE_URL}/auth/login`, JSON.stringify({
email: __ENV.TEST_EMAIL,
password: __ENV.TEST_PASSWORD,
}), {
headers: { 'Content-Type': 'application/json' },
});
check(loginRes, { 'login successful': (r) => r.status === 200 });
const { accessToken } = loginRes.json();
return { accessToken };
}
export default function (data) {
const { accessToken } = data;
const headers = {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
};
group('Contacts API', () => {
// List contacts
const listRes = http.get(`${BASE_URL}/contacts?page=1&limit=20`, {
headers,
tags: { type: 'api', endpoint: 'contacts-list' },
});
check(listRes, {
'list contacts: 200': (r) => r.status === 200,
'list contacts: has items': (r) => r.json('data') !== null,
});
apiCalls.add(1);
sleep(0.5);
// Create a contact
const createRes = http.post(`${BASE_URL}/contacts`, JSON.stringify({
name: `Load Test User ${Date.now()}`,
email: `load-test-${Date.now()}@example.com`,
}), {
headers,
tags: { type: 'api', endpoint: 'contacts-create' },
});
check(createRes, {
'create contact: 201': (r) => r.status === 201,
});
apiCalls.add(1);
});
sleep(1);
}
// teardown() runs once after all VUs finish
export function teardown(data) {
// Clean up test data if needed
console.log(`Test complete. Data: ${JSON.stringify(data)}`);
}
रैंपिंग वीयू परिदृश्य
कई चरणों और परिदृश्यों के साथ वास्तविक ट्रैफ़िक पैटर्न मॉडल करें:
// k6/stress-test.js
export const options = {
scenarios: {
// Scenario 1: Normal traffic baseline
normal_traffic: {
executor: 'ramping-vus',
startVUs: 0,
stages: [
{ duration: '2m', target: 20 },
{ duration: '5m', target: 20 },
],
gracefulRampDown: '30s',
},
// Scenario 2: Sudden spike (marketing campaign goes live)
traffic_spike: {
executor: 'ramping-vus',
startVUs: 0,
startTime: '7m', // Starts after baseline is stable
stages: [
{ duration: '30s', target: 200 }, // Rapid spike
{ duration: '2m', target: 200 }, // Hold spike
{ duration: '30s', target: 20 }, // Fall back
],
},
// Scenario 3: Soak test for memory leaks
soak_test: {
executor: 'constant-vus',
vus: 10,
duration: '30m', // Run for 30 minutes
startTime: '10m',
},
},
thresholds: {
'http_req_duration{scenario:normal_traffic}': ['p(95)<300'],
'http_req_duration{scenario:traffic_spike}': ['p(95)<800'],
http_req_failed: ['rate<0.02'],
},
};
ब्लॉग/साइटमैप क्रॉल टेस्ट
// k6/sitemap-crawl.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';
// Load URLs from sitemap (pre-fetched and saved as JSON)
const urls = new SharedArray('sitemap urls', function () {
// In real usage, fetch sitemap XML and parse URLs beforehand
// SharedArray is loaded once and shared across all VUs (memory efficient)
return JSON.parse(open('./sitemap-urls.json'));
});
export const options = {
vus: 20,
duration: '5m',
thresholds: {
http_req_duration: ['p(95)<2000'], // Public pages can be slower
http_req_failed: ['rate<0.01'],
},
};
export default function () {
// Each VU picks a random URL from the sitemap
const url = urls[Math.floor(Math.random() * urls.length)];
const res = http.get(url, {
headers: {
// Identify as load tester in logs
'User-Agent': 'k6-load-tester/1.0',
},
timeout: '10s',
});
check(res, {
'status is 200': (r) => r.status === 200,
'no error page': (r) => !r.body.includes('Error'),
'has canonical tag': (r) => r.body.includes('rel="canonical"'),
'response time < 2000ms': (r) => r.timings.duration < 2000,
});
sleep(Math.random() * 2 + 1); // Random 1-3 second think time
}
कस्टम मेट्रिक्स और सीमाएँ
// k6/checkout-load.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Counter, Rate, Trend, Gauge } from 'k6/metrics';
// Custom metrics for business-specific tracking
const checkoutSuccesses = new Counter('checkout_successes');
const checkoutFailures = new Counter('checkout_failures');
const checkoutDuration = new Trend('checkout_duration');
const activeCheckouts = new Gauge('active_checkouts');
export const options = {
stages: [
{ duration: '1m', target: 10 },
{ duration: '3m', target: 30 },
{ duration: '1m', target: 0 },
],
thresholds: {
checkout_duration: ['p(95)<3000'], // Checkout < 3s at p95
checkout_failures: ['count<10'], // Max 10 absolute failures
http_req_duration: ['p(99)<2000'],
},
};
export default function (data) {
activeCheckouts.add(1);
const start = Date.now();
// Step 1: Add to cart
const cartRes = http.post('/api/cart/add', JSON.stringify({
productId: 'prod_odoo_customization',
quantity: 1,
}), { headers: { 'Content-Type': 'application/json' } });
if (!check(cartRes, { 'add to cart: 200': (r) => r.status === 200 })) {
checkoutFailures.add(1);
activeCheckouts.add(-1);
return;
}
sleep(2);
// Step 2: Create checkout session
const checkoutRes = http.post('/api/billing/checkout', JSON.stringify({
cartId: cartRes.json('cartId'),
}), { headers: { 'Content-Type': 'application/json' } });
const success = check(checkoutRes, {
'checkout session created': (r) => r.status === 200,
'has session URL': (r) => r.json('url') !== null,
});
if (success) {
checkoutSuccesses.add(1);
checkoutDuration.add(Date.now() - start);
} else {
checkoutFailures.add(1);
}
activeCheckouts.add(-1);
sleep(1);
}
ग्राफाना आउटपुट इंटीग्रेशन
K6 मेट्रिक्स को InfluxDB पर स्ट्रीम करें और परीक्षण के दौरान Grafana में विज़ुअलाइज़ करें:
# Run with InfluxDB output
k6 run --out influxdb=http://localhost:8086/k6 k6/api-load.js
# Or use the k6 Grafana integration (k6 v0.45+)
k6 run --out experimental-prometheus-rw k6/api-load.js
# docker-compose.monitoring.yml
services:
influxdb:
image: influxdb:2.7
ports: ["8086:8086"]
environment:
INFLUXDB_DB: k6
INFLUXDB_ADMIN_USER: admin
INFLUXDB_ADMIN_PASSWORD: password
grafana:
image: grafana/grafana:latest
ports: ["3030:3000"]
environment:
GF_AUTH_ANONYMOUS_ENABLED: "true"
volumes:
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
- ./grafana/datasources:/etc/grafana/provisioning/datasources
सीआई एकीकरण
# .github/workflows/ci.yml (load test section)
load-tests:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # Only on main branch
needs: [deploy-staging]
steps:
- uses: actions/checkout@v4
- name: Install k6
run: |
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
| sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update && sudo apt-get install k6
- name: Run smoke test (30 VUs, 60s)
run: |
k6 run --vus 30 --duration 60s \
--env BASE_URL=${{ secrets.STAGING_URL }} \
--env TEST_EMAIL=${{ secrets.TEST_EMAIL }} \
--env TEST_PASSWORD=${{ secrets.TEST_PASSWORD }} \
apps/api/k6/api-load.js
- name: Upload k6 results
uses: actions/upload-artifact@v4
if: always()
with:
name: k6-results
path: k6-results/
प्रदर्शन आधार रेखाएँ
आधार रेखाएँ स्थापित करें और प्रतिगमन पर सचेत करें:
| समापन बिंदु | p50 | p95 | p99 | त्रुटि बजट |
|---|---|---|---|---|
GET / (मुखपृष्ठ) | 120ms | 400ms | 800 एमएस | 0.1% |
GET /api/contacts | 50 एमएस | 150ms | 300ms | 0.5% |
POST /api/contacts | 80 एमएस | 200ms | 400ms | 0.5% |
POST /auth/login | 200ms | 500ms | 1000ms | 1% |
POST /billing/checkout | 500ms | 1500ms | 3000 एमएस | 1% |
GET /blog/[slug] | 100ms | 300ms | 600ms | 0.1% |
अक्सर पूछे जाने वाले प्रश्न
वीयू और प्रति सेकंड अनुरोधों के बीच क्या अंतर है?
VU (वर्चुअल उपयोगकर्ता) समवर्ती सिम्युलेटेड उपयोगकर्ता हैं। प्रत्येक VU आपके डिफ़ॉल्ट फ़ंक्शन को एक लूप में चलाता है। प्रति सेकंड अनुरोध इस बात पर निर्भर करता है कि प्रत्येक पुनरावृत्ति कितनी तेजी से चलती है। यदि प्रत्येक VU पुनरावृत्ति में 2 सेकंड लगते हैं (नींद के समय सहित) और आपके पास 100 VU हैं, तो आपको लगभग 50 RPS मिलते हैं। जब आपको पुनरावृत्ति अवधि की परवाह किए बिना किसी विशिष्ट RPS को लक्षित करने की आवश्यकता हो तो constant-arrival-rate निष्पादक का उपयोग करें।
क्या मुझे उत्पादन या स्टेजिंग के विरुद्ध परीक्षण लोड करना चाहिए?
हमेशा मंचन को प्राथमिकता दें. उत्पादन लोड परीक्षण वास्तविक उपयोगकर्ताओं को प्रभावित करने, दर सीमा समाप्त करने, परीक्षण डेटा से वास्तविक ऑर्डर बनाने और वास्तविक वेबहुक घटनाओं को ट्रिगर करने का जोखिम उठाते हैं। यदि आपको उत्पादन का परीक्षण करना है, तो कम ट्रैफ़िक वाली विंडो के दौरान करें, परीक्षण भुगतान टोकन का उपयोग करें और रोलबैक योजना बनाएं। k6 क्लाउड भू-वितरित लोड जेनरेशन का समर्थन करता है ताकि आप मूल को छुए बिना अपने सीडीएन एज प्रदर्शन का परीक्षण कर सकें।
मैं लंबे परीक्षणों के दौरान प्रमाणीकरण टोकन समाप्ति को कैसे संभाल सकता हूं?
छोटे परीक्षणों (15 मिनट से कम) के लिए, setup() में एक टोकन प्राप्त करें और इसे data के माध्यम से सभी VUs को भेजें। लंबे परीक्षणों (15 मिनट से अधिक) के लिए, परीक्षण स्क्रिप्ट में टोकन रिफ्रेश लागू करें: डिफ़ॉल्ट फ़ंक्शन में टोकन आयु की जांच करें और समाप्ति के करीब आने पर रिफ्रेश करें। प्रत्येक VU के लिए स्थानीय जावास्क्रिप्ट वैरिएबल में टोकन को स्टोर करें।
stages और scenarios के बीच क्या अंतर है?
stages एकल ramping-vus परिदृश्य के लिए एक आशुलिपि है - सरल रैंप-अप/होल्ड/रैंप-डाउन पैटर्न के लिए अच्छा है। scenarios आपको पूर्ण नियंत्रण देता है: एक साथ कई ट्रैफ़िक पैटर्न, प्रति परिदृश्य अलग-अलग निष्पादक, प्रति-परिदृश्य सीमाएँ, और मेट्रिक्स में परिदृश्य टैगिंग। यथार्थवादी बहु-पैटर्न परीक्षण (बेसलाइन + स्पाइक + सोख एक साथ) के लिए scenarios का उपयोग करें।
एक एकल k6 प्रक्रिया कितने VUs को संभाल सकती है?
आधुनिक हार्डवेयर पर एक एकल k6 प्रक्रिया 5,000-10,000 VU को बनाए रख सकती है और स्क्रिप्ट जटिलता और प्रतिक्रिया आकार के आधार पर 50,000-100,000 RPS उत्पन्न कर सकती है। अधिक लोड के लिए, k6 cloud का उपयोग करें या लोड डिस्ट्रीब्यूटर के पीछे कई k6 इंस्टेंस चलाएं। प्रत्येक VU बेहद हल्का (एक गोरोइन) है - k6 समकक्ष VU गणना के लिए JMeter या गैटलिंग की तुलना में बहुत कम संसाधनों का उपयोग करता है।
अगले चरण
उपयोगकर्ताओं को तनाव में होने का पता चलने से पहले लोड परीक्षण से आपके एप्लिकेशन की वास्तविक प्रदर्शन प्रोफ़ाइल का पता चलता है। इस गाइड के पैटर्न - रैंपिंग परिदृश्य, कस्टम थ्रेशोल्ड, सीआई एकीकरण और ग्राफाना डैशबोर्ड - आपको लगातार प्रदर्शन बाधाओं को खोजने और ठीक करने के लिए बुनियादी ढांचा प्रदान करते हैं।
ECOSIRE होमपेज, एपीआई एंडपॉइंट, चेकआउट फ्लो और पूर्ण साइटमैप क्रॉल को कवर करने वाले k6 लोड परीक्षणों के साथ प्रदर्शन-मान्य NestJS API बनाता है। हमारी बैकएंड इंजीनियरिंग सेवाओं का अन्वेषण करें यह जानने के लिए कि हम पहले दिन से प्रदर्शन के लिए कैसे निर्माण करते हैं।
लेखक
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
ECOSIRE के साथ अपना व्यवसाय बढ़ाएं
ईआरपी, ईकॉमर्स, एआई, एनालिटिक्स और ऑटोमेशन में एंटरप्राइज समाधान।
संबंधित लेख
Odoo 19 HR: Skills Matrix, Career Plans, Performance Cycles
Odoo 19 HR upgrade: native skills matrix, career path planning, performance review cycles, 9-box grid, succession planning, HRIS integration.
Odoo 19 Performance Benchmarks: PostgreSQL 17 Tuning Numbers
Real-world Odoo 19 performance benchmarks: web client speed, ORM throughput, PG17 tuning settings, connection pooling, worker counts, scaling thresholds.
Odoo ORM API Cheat Sheet 2026: search, read, write, create
Practical Odoo ORM cheat sheet with examples: search, browse, read, write, create, unlink, recordsets, domains, computed fields, performance tips.
Performance & Scalability से और अधिक
Odoo 19 HR: Skills Matrix, Career Plans, Performance Cycles
Odoo 19 HR upgrade: native skills matrix, career path planning, performance review cycles, 9-box grid, succession planning, HRIS integration.
Odoo 19 Performance Benchmarks: PostgreSQL 17 Tuning Numbers
Real-world Odoo 19 performance benchmarks: web client speed, ORM throughput, PG17 tuning settings, connection pooling, worker counts, scaling thresholds.
OpenClaw Cost Optimization and Token Efficiency at Scale
OpenClaw token cost optimization: prompt caching, model routing, response caching, batch APIs, and per-tenant cost guardrails for production agents.
Power BI Incremental Refresh for Tables Over 10 Million Rows
Power BI Incremental Refresh playbook for 10M+ row tables: partition design, RangeStart/RangeEnd, refresh policies, query folding, and DirectQuery hybrids.
वेबहुक डिबगिंग और मॉनिटरिंग: संपूर्ण समस्या निवारण मार्गदर्शिका
विफलता पैटर्न, डिबगिंग टूल, पुनः प्रयास रणनीतियाँ, मॉनिटरिंग डैशबोर्ड और सुरक्षा सर्वोत्तम प्रथाओं को कवर करने वाली इस संपूर्ण मार्गदर्शिका के साथ वेबहुक डिबगिंग में महारत हासिल करें।
Nginx Production Configuration: SSL, Caching, and Security
Nginx production configuration guide: SSL termination, HTTP/2, caching headers, security headers, rate limiting, reverse proxy setup, and Cloudflare integration patterns.