Healthchecks.io คืออะไร
Healthchecks.io เป็นบริการ Cron Job Monitoring ที่ช่วยตรวจสอบว่า Scheduled Tasks ทำงานตามเวลาหรือไม่ หลักการคือ Cron Job ส่ง HTTP GET/POST ไปยัง Healthchecks.io เมื่อทำงานเสร็จ (Ping) ถ้าไม่ได้รับ Ping ภายในเวลาที่กำหนดจะแจ้งเตือน
เมื่อใช้ร่วมกับ Scaling Strategy ช่วยตรวจจับว่า Jobs เริ่มช้าลง (Duration เพิ่ม) หรือ Timeout เป็นสัญญาณว่าต้อง Scale Resources เพิ่ม
Setup Healthchecks.io
# === Healthchecks.io Setup ===
# 1. สมัครที่ https://healthchecks.io (Free: 20 Checks)
# หรือ Self-hosted ด้วย Docker
# === Self-hosted ด้วย Docker Compose ===
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
healthchecks:
image: healthchecks/healthchecks:latest
ports:
- "8000:8000"
environment:
- DB=postgres
- DB_HOST=postgres
- DB_NAME=healthchecks
- DB_USER=hc
- DB_PASSWORD=SecurePass123
- SECRET_KEY=your-secret-key-here
- ALLOWED_HOSTS=*
- SITE_ROOT=https://hc.example.com
- DEFAULT_FROM_EMAIL=alerts@example.com
- EMAIL_HOST=smtp.gmail.com
- EMAIL_PORT=587
- EMAIL_USE_TLS=True
- EMAIL_HOST_USER=your@gmail.com
- EMAIL_HOST_PASSWORD=app-password
- SLACK_CLIENT_ID=xxx
- SLACK_CLIENT_SECRET=xxx
depends_on:
- postgres
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
- POSTGRES_DB=healthchecks
- POSTGRES_USER=hc
- POSTGRES_PASSWORD=SecurePass123
volumes:
- pg-data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
pg-data:
EOF
docker compose up -d
# 2. Cron Job Integration
# แต่ละ Check มี UUID เฉพาะ เช่น:
# https://hc-ping.com/abc123-def456
# === Bash — Ping เมื่อ Job เสร็จ ===
# Backup Script
#!/bin/bash
set -e
CHECK_URL="https://hc-ping.com/abc123-def456"
# แจ้งเริ่มต้น
curl -fsS -m 10 --retry 5 "$CHECK_URL/start" > /dev/null
# ทำงาน
pg_dump mydb | gzip > /backups/mydb_$(date +%Y%m%d).sql.gz
# แจ้งเสร็จ (Ping)
curl -fsS -m 10 --retry 5 "$CHECK_URL" > /dev/null
# ถ้า Error — แจ้ง Fail
# curl -fsS -m 10 --retry 5 "$CHECK_URL/fail" > /dev/null
# 3. Crontab
# 0 2 * * * /opt/scripts/backup.sh 2>&1 | curl -fsS -m 10 \
# --retry 5 --data-binary @- https://hc-ping.com/abc123-def456/log
# 4. Python Integration
# import requests
# CHECK_URL = "https://hc-ping.com/abc123-def456"
# requests.get(f"{CHECK_URL}/start")
# # ... do work ...
# requests.get(CHECK_URL) # Success
# # requests.get(f"{CHECK_URL}/fail") # Failure
echo "Healthchecks.io setup complete"
Scaling Strategy Script
# scaling_strategy.py — Auto-scaling ตาม Healthchecks.io Metrics
import requests
import json
import subprocess
from datetime import datetime, timedelta
from dataclasses import dataclass
from typing import List, Dict, Optional
class HealthchecksClient:
"""Healthchecks.io API Client"""
def __init__(self, api_key, base_url="https://healthchecks.io"):
self.base_url = base_url
self.headers = {"X-Api-Key": api_key}
def list_checks(self):
"""ดู Checks ทั้งหมด"""
resp = requests.get(f"{self.base_url}/api/v3/checks/",
headers=self.headers)
return resp.json().get("checks", [])
def get_check(self, uuid):
"""ดู Check เฉพาะ"""
resp = requests.get(f"{self.base_url}/api/v3/checks/{uuid}",
headers=self.headers)
return resp.json()
def get_pings(self, uuid, limit=50):
"""ดู Ping History"""
resp = requests.get(
f"{self.base_url}/api/v3/checks/{uuid}/pings/",
headers=self.headers,
)
return resp.json().get("pings", [])[:limit]
def get_flips(self, uuid):
"""ดู Status Changes"""
resp = requests.get(
f"{self.base_url}/api/v3/checks/{uuid}/flips/",
headers=self.headers,
)
return resp.json().get("flips", [])
class ScalingAdvisor:
"""วิเคราะห์ Metrics และแนะนำ Scaling"""
def __init__(self, hc_client: HealthchecksClient):
self.hc = hc_client
def analyze_job_durations(self, uuid):
"""วิเคราะห์ Duration ของ Job"""
pings = self.hc.get_pings(uuid)
durations = []
start_time = None
for ping in reversed(pings):
if ping.get("type") == "start":
start_time = ping.get("date")
elif ping.get("type") == "success" and start_time:
start = datetime.fromisoformat(start_time.replace("Z", "+00:00"))
end = datetime.fromisoformat(ping["date"].replace("Z", "+00:00"))
duration = (end - start).total_seconds()
durations.append(duration)
start_time = None
if not durations:
return None
avg = sum(durations) / len(durations)
latest = durations[-1] if durations else 0
trend = "increasing" if len(durations) >= 3 and \
durations[-1] > durations[-3] * 1.2 else "stable"
return {
"avg_seconds": round(avg),
"latest_seconds": round(latest),
"min_seconds": round(min(durations)),
"max_seconds": round(max(durations)),
"samples": len(durations),
"trend": trend,
}
def scaling_recommendation(self, checks_analysis):
"""สร้างคำแนะนำ Scaling"""
recommendations = []
for name, analysis in checks_analysis.items():
if not analysis:
continue
if analysis["trend"] == "increasing":
recommendations.append({
"job": name,
"action": "SCALE UP",
"reason": f"Duration increasing: "
f"{analysis['latest_seconds']}s "
f"(avg: {analysis['avg_seconds']}s)",
"priority": "high",
})
elif analysis["latest_seconds"] > analysis["avg_seconds"] * 2:
recommendations.append({
"job": name,
"action": "INVESTIGATE",
"reason": f"Latest run 2x slower than average",
"priority": "medium",
})
return recommendations
def print_report(self, checks):
"""แสดง Scaling Report"""
print(f"\n{'='*55}")
print(f"Scaling Analysis Report — {datetime.now():%Y-%m-%d %H:%M}")
print(f"{'='*55}")
analyses = {}
for check in checks:
name = check.get("name", "Unknown")
uuid = check.get("ping_url", "").split("/")[-1]
if uuid:
analysis = self.analyze_job_durations(uuid)
analyses[name] = analysis
if analysis:
trend_icon = "UP" if analysis["trend"] == "increasing" else "OK"
print(f"\n [{trend_icon}] {name}")
print(f" Latest: {analysis['latest_seconds']}s | "
f"Avg: {analysis['avg_seconds']}s | "
f"Max: {analysis['max_seconds']}s")
recs = self.scaling_recommendation(analyses)
if recs:
print(f"\n Recommendations:")
for r in recs:
print(f" [{r['priority'].upper()}] {r['job']}: "
f"{r['action']} — {r['reason']}")
# hc = HealthchecksClient("your-api-key")
# advisor = ScalingAdvisor(hc)
# checks = hc.list_checks()
# advisor.print_report(checks)
Kubernetes HPA Integration
# === Kubernetes Auto-scaling ตาม Job Metrics ===
# hpa-config.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: worker
minReplicas: 2
maxReplicas: 20
metrics:
# Scale ตาม CPU
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
# Scale ตาม Queue Length (Custom Metric)
- type: Pods
pods:
metric:
name: job_queue_length
target:
type: AverageValue
averageValue: "10"
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 25
periodSeconds: 120
---
# === CronJob ที่ส่ง Ping ไป Healthchecks.io ===
apiVersion: batch/v1
kind: CronJob
metadata:
name: data-sync
namespace: production
spec:
schedule: "*/30 * * * *"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
containers:
- name: sync
image: myapp/data-sync:latest
command:
- /bin/sh
- -c
- |
curl -fsS -m 10 "$HC_PING_URL/start"
python sync.py
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
curl -fsS -m 10 "$HC_PING_URL"
else
curl -fsS -m 10 "$HC_PING_URL/fail"
fi
env:
- name: HC_PING_URL
valueFrom:
secretKeyRef:
name: healthchecks
key: data-sync-url
restartPolicy: OnFailure
Best Practices
- Start/Success Pattern: ใช้ /start Ping ก่อนเริ่ม และ Ping เมื่อเสร็จ เพื่อวัด Duration
- Grace Period: ตั้ง Grace Period ให้มากกว่า Max Duration ของ Job ป้องกัน False Alert
- Log Output: ส่ง Log Output ไปกับ Ping ด้วย (POST body) สำหรับ Debug
- Fail Ping: ส่ง /fail เมื่อ Job Error ไม่ใช่แค่รอ Timeout
- Scale Gradually: Scale Up เร็ว Scale Down ช้า ป้องกัน Thrashing
- Monitor Duration Trends: ติดตาม Duration ถ้าเพิ่มขึ้นต่อเนื่อง ต้อง Scale
Healthchecks.io คืออะไร
บริการ Cron Job Monitoring ตรวจสอบ Scheduled Tasks ทำงานตามเวลาหรือไม่ Cron Job ส่ง HTTP Ping เมื่อเสร็จ ถ้าไม่ได้รับ Ping แจ้งเตือน Email Slack PagerDuty Free Plan 20 Checks
Scaling Strategy คืออะไร
แผนขยายระบบรองรับ Load เพิ่ม Vertical Scaling เพิ่ม CPU/RAM Server เดิม Horizontal Scaling เพิ่มจำนวน Server ใช้ Metrics เช่น CPU Usage Request Count Queue Length ตัดสินใจ
Healthchecks.io ช่วย Scaling อย่างไร
ตรวจจับ Jobs ช้าลงหรือ Timeout สัญญาณต้อง Scale ติดตาม Job Duration เห็นแนวโน้ม Duration เพิ่มแสดงว่า Resources ไม่พอ ใช้ร่วมกับ Auto-scaling Scale เมื่อ Jobs เริ่มช้า
Self-hosted Healthchecks.io ทำได้ไหม
ได้ Open-source BSD License ติดตั้งด้วย Docker Compose ต้องมี PostgreSQL ไม่จำกัด Checks ข้อมูลอยู่ Server เอง เหมาะองค์กรที่ต้องการ Data Privacy
สรุป
Healthchecks.io เป็นเครื่องมือ Cron Job Monitoring ที่ช่วยตรวจสอบ Scheduled Tasks และเมื่อใช้ร่วมกับ Scaling Strategy ช่วยตรวจจับปัญหา Performance ก่อนกระทบผู้ใช้ ใช้ Start/Success Pattern วัด Duration ติดตาม Trends ถ้า Duration เพิ่มต่อเนื่องต้อง Scale ใช้ Kubernetes HPA สำหรับ Auto-scaling Self-hosted ด้วย Docker ถ้าต้องการ Data Privacy
