Anda butuh arsitektur multi-region begitu target scraping tersebar di banyak negara dan satu titik kegagalan mulai terasa mahal. Menempatkan worker di dekat situs target — misalnya di AWS ap-southeast-1 (Singapura) atau ap-southeast-3 (Jakarta) untuk target Asia Tenggara, dan di eu-west-1 untuk target Eropa — memangkas waktu bolak-balik request dan menjaga throughput tetap jalan saat satu region bermasalah. Sebaliknya, kalau target Anda hanya di satu negara dan volume masih di bawah seribu task per jam, satu region sudah cukup dan multi-region hanya menambah biaya operasional.
Artikel ini menunjukkan pola konkret: kapan multi-region layak, cara routing task ke region terdekat, cara failover saat satu region tumbang, dan cara memantau kesehatan tiap region. CaptchaAI sendiri memakai satu kunci API global dengan penagihan berbasis thread, jadi seluruh biaya multi-region ada di sisi infrastruktur Anda, bukan di sisi solver.
Sekilas arsitektur
[Task Router]
(Route53 / Load Balancer)
↙ ↓ ↘
[US-East] [EU-West] [AP-Southeast]
Workers Workers Workers
↓ ↓ ↓
[CaptchaAI API] ← shared API key
↓ ↓ ↓
[Central DB / Queue]
(Results aggregation)
Arsitektur ini punya tiga lapis yang jelas:
- Router task memutuskan region tujuan tiap task berdasarkan lokasi situs target.
- Fleet worker per region menjalankan proses penyelesaian secara mandiri di tiap lokasi.
- Penyimpanan pusat mengumpulkan seluruh hasil untuk agregasi dan pelaporan.
Setiap region menjalankan worker mandiri. Semuanya memakai kunci API CaptchaAI yang sama dan mendorong hasil ke satu penyimpanan pusat untuk agregasi.
Menempatkan worker di tiap region
Worker Python yang sadar region
import os
import time
import requests
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
REGION = os.environ.get("WORKER_REGION", "us-east-1")
RESULT_QUEUE_URL = os.environ["RESULT_QUEUE_URL"]
def solve_captcha(task):
"""Solve CAPTCHA and tag with region metadata."""
start = time.time()
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": task["method"],
"googlekey": task["sitekey"],
"pageurl": task["pageurl"],
"json": 1
})
data = resp.json()
if data.get("status") != 1:
return {
"task_id": task["task_id"],
"error": data.get("request"),
"region": REGION
}
captcha_id = data["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": captcha_id, "json": 1
}).json()
if result.get("status") == 1:
return {
"task_id": task["task_id"],
"solution": result["request"],
"region": REGION,
"duration": time.time() - start,
"api_latency_ms": round((time.time() - start) * 1000)
}
if result.get("request") != "CAPCHA_NOT_READY":
return {
"task_id": task["task_id"],
"error": result.get("request"),
"region": REGION
}
return {"task_id": task["task_id"], "error": "TIMEOUT", "region": REGION}
Router task
Arahkan setiap task ke region yang paling dekat dengan situs target. Pemetaan sederhana berbasis TLD sudah cukup untuk memulai, lalu perhalus aturannya seiring pola trafik Anda terbaca:
from urllib.parse import urlparse
# Region mapping by target site TLD/domain
REGION_MAP = {
".co.uk": "eu-west-1",
".de": "eu-central-1",
".fr": "eu-west-3",
".jp": "ap-northeast-1",
".com.au": "ap-southeast-2",
".com": "us-east-1", # Default
}
REGION_QUEUES = {
"us-east-1": "sqs://captcha-tasks-us-east",
"eu-west-1": "sqs://captcha-tasks-eu-west",
"ap-southeast-1": "sqs://captcha-tasks-ap-southeast",
}
def route_task(task):
"""Route task to the closest regional queue."""
domain = urlparse(task["pageurl"]).netloc
target_region = "us-east-1" # Default
for suffix, region in REGION_MAP.items():
if domain.endswith(suffix):
target_region = region
break
queue = REGION_QUEUES.get(target_region, REGION_QUEUES["us-east-1"])
send_to_queue(queue, task)
return target_region
Menyiapkan infrastruktur
Modelkan region sebagai satu variabel dan biarkan Terraform men-deploy fleet identik ke tiap lokasi. Pola ini menjaga tiga hal tetap konsisten di semua region:
- Satu antrean task masuk (SQS) per region.
- Satu antrean hasil pusat yang dibagi semua region.
- Satu secret kunci API yang direferensikan tiap fleet.
Kerangka Terraform
# Define regions
variable "regions" {
default = ["us-east-1", "eu-west-1", "ap-southeast-1"]
}
# Deploy worker fleet per region
module "captcha_workers" {
for_each = toset(var.regions)
source = "./modules/captcha-worker"
region = each.key
worker_count = var.workers_per_region
api_key_secret_arn = aws_secretsmanager_secret.captchaai_key.arn
task_queue_arn = aws_sqs_queue.tasks[each.key].arn
result_queue_arn = aws_sqs_queue.results.arn
}
# SQS queue per region for task intake
resource "aws_sqs_queue" "tasks" {
for_each = toset(var.regions)
name = "captcha-tasks-${each.key}"
}
# Central result queue
resource "aws_sqs_queue" "results" {
name = "captcha-results-central"
}
Docker Compose untuk simulasi multi-region lokal
Uji perilaku multi-region secara lokal dengan tiga service worker yang berbagi satu Redis:
version: "3.8"
services:
worker-us:
build: ./worker
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
- WORKER_REGION=us-east-1
- TASK_QUEUE=redis://redis:6379/0
depends_on:
- redis
worker-eu:
build: ./worker
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
- WORKER_REGION=eu-west-1
- TASK_QUEUE=redis://redis:6379/1
worker-ap:
build: ./worker
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
- WORKER_REGION=ap-southeast-1
- TASK_QUEUE=redis://redis:6379/2
redis:
image: redis:7-alpine
Memantau kesehatan tiap region
Tanpa observabilitas, Anda tidak akan tahu satu region melambat sampai task mulai menumpuk. Cek endpoint kesehatan tiap region secara berkala dan catat tiga sinyal yang nantinya memicu failover:
- Latensi respons endpoint kesehatan.
- Jumlah worker aktif di region tersebut.
- Kedalaman antrean yang menunggu diproses.
Health check dengan Node.js
const axios = require("axios");
const REGIONS = ["us-east-1", "eu-west-1", "ap-southeast-1"];
async function checkRegionHealth() {
const health = {};
for (const region of REGIONS) {
const endpoint = `https://${region}.workers.example.com/health`;
try {
const start = Date.now();
const resp = await axios.get(endpoint, { timeout: 5000 });
health[region] = {
status: "healthy",
latencyMs: Date.now() - start,
activeWorkers: resp.data.activeWorkers,
queueDepth: resp.data.queueDepth,
};
} catch (err) {
health[region] = { status: "unhealthy", error: err.message };
}
}
return health;
}
// Periodic health check
setInterval(async () => {
const health = await checkRegionHealth();
console.table(health);
}, 60000);
Strategi failover
Saat sebuah region tumbang atau gagal melewati gerbang kesehatan, alihkan task-nya ke region sehat dengan antrean paling ringan. Logikanya berjalan dalam tiga langkah:
- Kumpulkan daftar region yang masih sehat.
- Untuk tiap region bermasalah, pilih tujuan sehat dengan kedalaman antrean paling kecil.
- Catat pengalihan tersebut agar bisa diaudit setelah insiden.
Jika tidak ada satu pun region yang sehat, hentikan proses dan picu peringatan alih-alih memaksakan pengalihan.
def failover_check(region_health):
"""Redirect tasks from unhealthy regions."""
healthy_regions = [
r for r, h in region_health.items()
if h["status"] == "healthy"
]
if not healthy_regions:
raise RuntimeError("All regions unhealthy")
redirects = {}
for region, health in region_health.items():
if health["status"] == "unhealthy":
# Pick the healthy region with lowest queue depth
target = min(
healthy_regions,
key=lambda r: region_health[r].get("queue_depth", 0)
)
redirects[region] = target
print(f"Failover: {region} → {target}")
return redirects
Aturan menjalankan failover dengan rapi
Failover yang buruk justru menciptakan masalah baru. Tiga aturan operasional yang sebaiknya Anda pegang:
- Hentikan pengiriman task baru ke region yang terdegradasi begitu latensi, tingkat kesalahan, atau sinyal jaringan melewati ambang kebijakan Anda.
- Selesaikan pekerjaan yang sedang berjalan secara sengaja, alih-alih memindahkan seluruh antrean dan sesi secara mendadak.
- Kembalikan trafik ke region tersebut hanya setelah ia lolos gerbang kesehatan yang sama seperti sebelum failover.
Kapan multi-region benar-benar sepadan
Setelah melihat mekanismenya, mundur sejenak: multi-region bukan default. Pakai tabel ini untuk memutuskan sebelum menambah kompleksitas infrastruktur:
| Situasi | Satu region | Multi-region |
|---|---|---|
| Target hanya di satu negara | Cukup | Berlebihan |
| Target tersebar global | Latensi tambahan 100–300 ms | Latensi lokal per region |
| Butuh uptime 99,9% | Sulit dijaga | Redundansi alami |
| Kepatuhan residensi data | Sulit dipenuhi | Proses di region setempat |
| < 1.000 task/jam | Baik | Kompleksitas yang tidak perlu |
| > 10.000 task/jam | Mentok batas skala | Beban terdistribusi |
Untuk tim di Indonesia, kasus yang paling sering muncul adalah campuran: sebagian target di Asia Tenggara, sebagian di Amerika dan Eropa. Di sinilah routing per region mulai membayar dirinya sendiri. Naikkan ke multi-region jika minimal satu pemicu ini terpenuhi:
- Target tersebar di beberapa benua dan latensi mulai terasa.
- Ada target uptime formal yang mustahil dipenuhi oleh satu region.
- Ada kewajiban residensi data yang menuntut pemrosesan di yurisdiksi tertentu.
Merinci biaya multi-region
Biaya multi-region datang dari infrastruktur, bukan dari solver. CaptchaAI menagih berbasis thread dengan tarif yang sama di mana pun worker Anda berjalan — mulai dari paket BASIC $15 hingga tier VIP untuk volume besar — jadi menyebar worker ke tiga region tidak menambah premi apa pun di sisi API.
| Komponen | Faktor biaya | Cara menekan |
|---|---|---|
| Instance worker | Komputasi per region | Auto-scale ke nol saat idle |
| Transfer data antar region | $0.02/GB antar region | Perkecil ukuran payload hasil |
| Antrean SQS | Harga per request | Kirim pesan secara batch |
| API CaptchaAI | Tarif sama di semua region | Tanpa premi multi-region |
Untuk tim yang sensitif terhadap biaya — banyak agensi scraping dan tim data startup di Indonesia — penagihan flat berbasis thread justru menjadikan multi-region mudah dianggarkan: kapasitas solve tidak berubah harganya saat Anda menambah region.
Pertanyaan umum
Region mana yang sebaiknya saya pilih untuk target di Asia Tenggara?
Tempatkan worker di ap-southeast-1 (Singapura) atau ap-southeast-3 (Jakarta) agar dekat dengan situs target di kawasan ini. Untuk cakupan campuran, tambahkan satu region Eropa dan satu region Amerika, lalu biarkan router mengarahkan tiap task ke yang paling dekat.
Apakah menambah region membuat tagihan CaptchaAI naik?
Tidak. CaptchaAI menagih berbasis thread dengan tarif yang sama di mana pun worker berjalan, jadi jumlah region tidak mengubah biaya solve. Yang bertambah hanyalah biaya infrastruktur Anda sendiri: instance, transfer data antar region, dan antrean.
Bagaimana multi-region membantu kepatuhan residensi data?
Dengan memproses task di region setempat, Anda bisa menjaga data agar tetap berada di yurisdiksi yang diizinkan. Ini relevan dengan UU Pelindungan Data Pribadi (UU 27/2022); tetap batasi pemrosesan hanya pada data yang memang berhak Anda olah. Ini bukan nasihat hukum.
Kapan sebaiknya saya tetap pakai satu region saja?
Jika target Anda hanya di satu negara dan volume di bawah 1.000 task per jam, satu region lebih sederhana dan lebih murah. Naik ke multi-region saat target mulai tersebar global atau saat Anda butuh redundansi untuk memenuhi target uptime.
Mengatasi masalah umum
| Masalah | Penyebab | Perbaikan |
|---|---|---|
| Satu region konsisten lebih lambat | Jarak ke server CaptchaAI | Bandingkan latensi dasar; bisa jadi memang wajar |
| Semua task masuk ke satu region | Aturan routing berbasis domain terlalu luas | Tambahkan aturan routing yang lebih terperinci |
| Failover tidak terpicu | Endpoint health check tidak merespons | Pastikan endpoint kesehatan berada di jalur terpisah dari logika worker |
| Saldo kunci API terkuras lebih cepat | Semua region memakai satu kunci | Wajar — pantau penggunaan agregat |
Artikel terkait
Langkah selanjutnya
Sebarkan worker CaptchaAI di beberapa region — ambil kunci API Anda lalu bangun infrastruktur penyelesaian CAPTCHA yang tahan gangguan.
Panduan terkait: