Web Components High Availability HA Setup คืออะไร
Web Components เป็นมาตรฐาน web สำหรับสร้าง reusable custom HTML elements ประกอบด้วย Custom Elements, Shadow DOM, HTML Templates และ ES Modules High Availability (HA) คือการออกแบบระบบให้มี uptime สูงสุด (99.9%+) ลด downtime ให้น้อยที่สุด การรวมสองแนวคิดนี้ช่วยให้ Web Components applications มีความเสถียรสูง รองรับ traffic scale และกู้คืนจาก failures ได้อัตโนมัติ ครอบคลุม CDN distribution, service workers, fallback strategies และ infrastructure HA
Web Components Architecture for HA
# wc_ha_arch.py — Web Components HA architecture
import json
class WebComponentsHAArch:
LAYERS = {
"cdn": {
"name": "CDN Layer (Edge)",
"description": "Distribute Web Components bundles ผ่าน CDN — ใกล้ user ที่สุด",
"ha_strategy": "Multi-CDN failover (Cloudflare + Fastly), edge caching",
"uptime": "99.99%+",
},
"service_worker": {
"name": "Service Worker (Client Cache)",
"description": "Cache components locally — ทำงานได้แม้ offline",
"ha_strategy": "Cache-first strategy, background sync, offline fallback",
"uptime": "100% (cached locally)",
},
"component_registry": {
"name": "Component Registry (Server)",
"description": "Central registry สำหรับ component versions, metadata",
"ha_strategy": "Multi-region deployment, database replication",
"uptime": "99.95%+",
},
"api_backend": {
"name": "API Backend",
"description": "REST/GraphQL APIs ที่ Web Components เรียกใช้",
"ha_strategy": "Load balancer, auto-scaling, circuit breaker",
"uptime": "99.9%+",
},
"storage": {
"name": "Asset Storage",
"description": "JS bundles, CSS, images สำหรับ Web Components",
"ha_strategy": "S3/GCS multi-region replication, versioned assets",
"uptime": "99.99%+",
},
}
def show_layers(self):
print("=== HA Architecture Layers ===\n")
for key, layer in self.LAYERS.items():
print(f"[{layer['name']}] Uptime: {layer['uptime']}")
print(f" {layer['description']}")
print(f" HA: {layer['ha_strategy']}")
print()
arch = WebComponentsHAArch()
arch.show_layers()
Resilient Web Components
// resilient_wc.js — Web Components with HA patterns
// 1. Lazy Loading with Fallback
class ResilientLoader {
static async loadComponent(tagName, url, fallbackUrl) {
try {
await import(url);
} catch (err) {
console.warn(`Primary load failed for , trying fallback...`);
try {
await import(fallbackUrl);
} catch (fallbackErr) {
console.error(`All sources failed for `);
// Register a placeholder component
if (!customElements.get(tagName)) {
customElements.define(tagName, class extends HTMLElement {
connectedCallback() {
this.innerHTML = `
Component unavailable. Please refresh.`;
}
});
}
}
}
}
}
// 2. Circuit Breaker for API calls
class CircuitBreaker {
constructor(threshold = 5, timeout = 30000) {
this.failures = 0;
this.threshold = threshold;
this.timeout = timeout;
this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN
this.lastFailTime = null;
}
async call(fn) {
if (this.state === 'OPEN') {
if (Date.now() - this.lastFailTime > this.timeout) {
this.state = 'HALF_OPEN';
} else {
throw new Error('Circuit breaker is OPEN');
}
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (err) {
this.onFailure();
throw err;
}
}
onSuccess() {
this.failures = 0;
this.state = 'CLOSED';
}
onFailure() {
this.failures++;
this.lastFailTime = Date.now();
if (this.failures >= this.threshold) {
this.state = 'OPEN';
}
}
}
// 3. Web Component with Circuit Breaker
class DataWidget extends HTMLElement {
constructor() {
super();
this.breaker = new CircuitBreaker(3, 15000);
this.attachShadow({ mode: 'open' });
}
async connectedCallback() {
try {
const data = await this.breaker.call(() =>
fetch('/api/data').then(r => r.json())
);
this.render(data);
} catch (err) {
this.renderFallback();
}
}
render(data) {
this.shadowRoot.innerHTML = ``;
}
renderFallback() {
this.shadowRoot.innerHTML = `
Data temporarily unavailable
`;
}
}
customElements.define('data-widget', DataWidget);
console.log("Resilient Web Components loaded");
Service Worker Caching
// sw_cache.js — Service Worker for Web Components HA
// service-worker.js
const CACHE_NAME = 'wc-cache-v1';
const COMPONENT_URLS = [
'/components/header-nav.js',
'/components/data-table.js',
'/components/chart-widget.js',
'/components/shared-styles.css',
];
// Install: pre-cache components
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(COMPONENT_URLS);
})
);
self.skipWaiting();
});
// Fetch: stale-while-revalidate strategy
self.addEventListener('fetch', (event) => {
if (event.request.url.includes('/components/')) {
event.respondWith(
caches.open(CACHE_NAME).then(async (cache) => {
const cachedResponse = await cache.match(event.request);
// Background revalidate
const fetchPromise = fetch(event.request).then((networkResponse) => {
if (networkResponse.ok) {
cache.put(event.request, networkResponse.clone());
}
return networkResponse;
}).catch(() => null);
// Return cached immediately, update in background
return cachedResponse || fetchPromise;
})
);
}
// API calls: network-first with cache fallback
if (event.request.url.includes('/api/')) {
event.respondWith(
fetch(event.request)
.then((response) => {
const clone = response.clone();
caches.open('api-cache').then((cache) => {
cache.put(event.request, clone);
});
return response;
})
.catch(() => caches.match(event.request))
);
}
});
// Background sync for offline mutations
self.addEventListener('sync', (event) => {
if (event.tag === 'sync-mutations') {
event.waitUntil(processPendingMutations());
}
});
async function processPendingMutations() {
const db = await openDB();
const mutations = await db.getAll('pending-mutations');
for (const mutation of mutations) {
try {
await fetch(mutation.url, {
method: mutation.method,
body: JSON.stringify(mutation.body),
headers: { 'Content-Type': 'application/json' },
});
await db.delete('pending-mutations', mutation.id);
} catch (err) {
break; // Will retry on next sync
}
}
}
console.log("Service Worker with HA caching registered");
Infrastructure HA
# infra_ha.py — Infrastructure for Web Components HA
import json
class InfrastructureHA:
KUBERNETES = """
# k8s-ha.yaml — HA deployment for Web Components backend
apiVersion: apps/v1
kind: Deployment
metadata:
name: wc-registry
spec:
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: wc-registry
template:
spec:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
containers:
- name: registry
image: wc-registry:latest
ports:
- containerPort: 8080
resources:
requests:
cpu: 500m
memory: 512Mi
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: wc-registry-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: wc-registry
"""
CDN_CONFIG = {
"primary": "Cloudflare (global edge, 300+ locations)",
"failover": "Fastly (backup CDN, automatic failover)",
"cache_ttl": "Components: 1 hour, Versioned assets: 1 year",
"purge": "Instant purge on new version deploy",
"monitoring": "Real User Monitoring (RUM) + synthetic checks",
}
def show_k8s(self):
print("=== Kubernetes HA ===")
print(self.KUBERNETES[:500])
def show_cdn(self):
print(f"\n=== CDN Configuration ===")
for key, val in self.CDN_CONFIG.items():
print(f" [{key}] {val}")
def ha_checklist(self):
print(f"\n=== HA Checklist ===")
items = [
"Multi-zone Kubernetes deployment (3+ replicas)",
"CDN with automatic failover",
"Service Worker caching (offline support)",
"Circuit breaker for API calls",
"Health checks (readiness + liveness)",
"PodDisruptionBudget (min 2 available)",
"Auto-scaling (HPA based on CPU/requests)",
"Database replication (primary-replica)",
"Monitoring + alerting (Prometheus + PagerDuty)",
"Disaster recovery plan + runbooks",
]
for item in items:
print(f" □ {item}")
infra = InfrastructureHA()
infra.show_k8s()
infra.show_cdn()
infra.ha_checklist()
Monitoring & Alerting
# monitoring.py — Monitoring for Web Components HA
import json
import random
class HAMonitoring:
METRICS = {
"component_load_time": "เวลาโหลด Web Component (target: < 200ms)",
"component_error_rate": "อัตรา error ของ components (target: < 0.1%)",
"api_latency_p99": "API latency P99 (target: < 500ms)",
"cdn_hit_rate": "CDN cache hit rate (target: > 95%)",
"sw_cache_rate": "Service Worker cache hit rate",
"availability": "Overall availability (target: 99.9%)",
}
def show_metrics(self):
print("=== Monitoring Metrics ===\n")
for metric, desc in self.METRICS.items():
print(f" [{metric}] {desc}")
def dashboard(self):
print(f"\n=== Live Dashboard ===")
print(f" Availability: {random.uniform(99.9, 100):.3f}%")
print(f" Component load P50: {random.uniform(50, 150):.0f}ms")
print(f" Component load P99: {random.uniform(150, 400):.0f}ms")
print(f" Error rate: {random.uniform(0, 0.2):.3f}%")
print(f" CDN hit rate: {random.uniform(94, 99):.1f}%")
print(f" SW cache rate: {random.uniform(80, 95):.1f}%")
print(f" API latency P99: {random.uniform(100, 500):.0f}ms")
print(f" Active replicas: {random.randint(3, 5)}/5")
mon = HAMonitoring()
mon.show_metrics()
mon.dashboard()
FAQ - คำถามที่พบบ่อย
Q: Web Components ต้อง HA ไหม?
A: ขึ้นกับ use case: Micro-frontends ที่ render critical UI: ต้อง HA — ถ้า component ไม่โหลด = หน้าพัง Design system components: HA สำคัญ — ใช้ทั้ง org Third-party widgets: ต้อง isolate failure — ไม่ให้กระทบ host app Minimum: CDN + Service Worker caching = HA พื้นฐานที่ทำได้ง่าย
Q: Service Worker จำเป็นไหม?
A: แนะนำอย่างยิ่ง เพราะ: Offline support — components ทำงานได้แม้ไม่มี internet Faster loads — cache-first = instant component render Resilience — ถ้า CDN/server down ยังมี cached version แต่: ต้อง manage cache invalidation อย่างดี — stale components อาจเป็นปัญหา
Q: Circuit Breaker ใช้กับ Web Components ยังไง?
A: ใช้สำหรับ API calls ภายใน Web Components: Component เรียก API → ถ้า fail > threshold → circuit OPEN → ใช้ cached data/fallback ป้องกัน: cascade failure, resource exhaustion, poor UX Libraries: opossum (Node.js), custom implementation (ง่ายมาก)
Q: 99.9% uptime หมายความว่าอะไร?
A: 99.9% = downtime ไม่เกิน 8.76 ชั่วโมง/ปี (43.8 นาที/เดือน) 99.95% = 4.38 ชั่วโมง/ปี 99.99% = 52.6 นาที/ปี สำหรับ Web Components: CDN + SW cache ช่วยให้ client-side availability ใกล้ 100% แม้ server อาจไม่ถึง 99.99%
