
Cloud
Learning Level
Advanced scaling patterns, load testing, and optimization techniques enable building systems that gracefully handle extreme load and recover from failures.
By the end of this lesson, you'll understand:
# Use historical metrics for predictive scaling
gcloud compute backend-services update my-backend \
--enable-cdn \
--session-affinity=CLIENT_IP \
--affinity-cookie-ttl=50Predictive scaling with custom metrics:
class PredictiveScaler {
async predictLoad(history) {
// Simple linear regression
const n = history.length;
const sumX = history.reduce((s, h, i) => s + i, 0);
const sumY = history.reduce((s, h) => s + h.load, 0);
const sumXY = history.reduce((s, h, i) => s + i * h.load, 0);
const sumX2 = history.reduce((s, h, i) => s + i * i, 0);
const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
const intercept = (sumY - slope * sumX) / n;
return slope * n + intercept;
}
async adjustCapacity(predictedLoad) {
const requiredInstances = Math.ceil(predictedLoad / 1000);
return await this.setInstanceCount(requiredInstances);
}
}# Install and run load testing tool
npm install -g k6
# Run load test
k6 run load-test.jsk6 load test script:
import http from 'k6/http';
import {check, sleep} from 'k6';
export const options = {
stages: [
{duration: '30s', target: 20},
{duration: '1m30s', target: 100},
{duration: '30s', target: 0}
],
thresholds: {
http_req_duration: ['p(99)<500'],
'http_req_duration{staticAsset:yes}': ['p(99)<100']
}
};
export default function() {
const res = http.get(__ENV.BASE_URL);
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500
});
sleep(1);
}class ChaosMonkey {
async injectFailure(type, duration = 10000) {
const startTime = Date.now();
return {
enabled: true,
type,
duration,
startTime,
endTime: startTime + duration,
isActive: () => Date.now() < this.endTime,
shouldFail: () => {
if (!this.isActive()) return false;
switch(this.type) {
case 'latency':
return Math.random() < 0.1; // 10% of requests
case 'error':
return Math.random() < 0.05; // 5% of requests
case 'timeout':
return Math.random() < 0.02; // 2% of requests
default:
return false;
}
}
};
}
}
// Usage in middleware
app.use(async (req, res, next) => {
if (chaos.isActive() && chaos.shouldFail()) {
if (chaos.type === 'latency') {
await sleep(5000);
} else if (chaos.type === 'error') {
return res.status(500).json({error: 'Chaos failure'});
} else if (chaos.type === 'timeout') {
req.connection.destroy();
return;
}
}
next();
});class CircuitBreaker {
constructor(fn, options = {}) {
this.fn = fn;
this.failureThreshold = options.failureThreshold || 5;
this.resetTimeout = options.resetTimeout || 60000;
this.state = 'CLOSED';
this.failureCount = 0;
this.lastFailureTime = null;
}
async execute(...args) {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailureTime > this.resetTimeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await this.fn(...args);
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
onSuccess() {
this.failureCount = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failureCount++;
this.lastFailureTime = Date.now();
if (this.failureCount >= this.failureThreshold) {
this.state = 'OPEN';
}
}
}
// Usage
const breaker = new CircuitBreaker(
async (id) => await fetchUserData(id),
{failureThreshold: 5, resetTimeout: 30000}
);
app.get('/users/:id', async (req, res) => {
try {
const user = await breaker.execute(req.params.id);
res.json(user);
} catch (error) {
res.status(503).json({error: 'Service unavailable'});
}
});class ShardRouter {
constructor(shardCount) {
this.shardCount = shardCount;
}
getShardId(key) {
const hash = this.hashKey(key);
return hash % this.shardCount;
}
hashKey(key) {
let hash = 0;
for (let i = 0; i < key.length; i++) {
const char = key.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return Math.abs(hash);
}
async getConnection(key) {
const shardId = this.getShardId(key);
return this.shards[shardId].getConnection();
}
}
// Usage
const router = new ShardRouter(16);
async function addUser(userId, userData) {
const conn = await router.getConnection(userId);
return await conn.query(
'INSERT INTO users (id, data) VALUES (?, ?)',
[userId, JSON.stringify(userData)]
);
}Explore distributed systems patterns, or learn about service mesh for advanced traffic management.
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward