DevOps & Scaling

CaptchaAI ile Çok Bölgeli CAPTCHA Çözme Mimarisi

Çok bölgeli bir CAPTCHA çözme mimarisine gerçekten ihtiyacınız var mı? Kısa yanıt: hedef siteleriniz tek bir ülkedeyse hayır; trafiğiniz kıtalara yayılıyorsa ve kesinti toleransınız düşükse evet. Bu rehber, CaptchaAI worker'larınızı birden fazla AWS bölgesine dağıtarak gecikmeyi nasıl düşüreceğinizi, bölgesel kesintilerden nasıl kurtulacağınızı ve sonuçları tek bir merkezde nasıl toplayacağınızı adım adım gösterir. Örnek kod Python, JavaScript, Terraform ve Docker Compose olarak hazır; tek yapmanız gereken kendi bölge haritanızı tanımlamak. Kazanç üç başlıkta toplanır: hedefe yakın worker'larla düşük gecikme, bölge çökse bile devreye giren doğal artıklık ve veriyi kendi coğrafyasında işleyebilme.

Genel mimari nasıl görünür?

                    [Task Router]
                    (Route53 / Load Balancer)
                    ↙        ↓        ↘
        [US-East]      [EU-West]     [AP-Southeast]
        Workers        Workers        Workers
            ↓              ↓              ↓
        [CaptchaAI API] ← shared API key
            ↓              ↓              ↓
        [Central DB / Queue]
        (Results aggregation)

Tasarım basit: her bölgede bağımsız bir worker filosu çalışır, hepsi aynı CaptchaAI API anahtarını paylaşır ve çözülen token'ları merkezi bir kuyruğa ya da veritabanına yazar. Bir görev geldiğinde yönlendirici onu hedef siteye en yakın bölgeye gönderir; sonuç, kaynağı hangi bölge olursa olsun aynı merkezi depoda toplanır. Böylece tek bir bölge çökse bile diğerleri işi devralır. Bu mimariyi parça parça, çalışan worker'dan yük devretmeye kadar kuralım; ardından geçişin gerçekten ne zaman değdiğini bir karar tablosuyla tartalım.

Bölge duyarlı worker'lar

Her worker, hangi bölgede çalıştığını bir ortam değişkeninden okur ve ürettiği her sonucu bu bölge etiketiyle işaretler. Bu etiket, ilerideki sağlık ve maliyet analizinin temelidir. Aşağıdaki Python worker'ı görevi CaptchaAI'ye gönderir, sonucu in.php/res.php akışıyla sorgular ve çözüm süresini bölge bilgisiyle birlikte döndürür.

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}

Görevleri en yakın bölgeye yönlendirin

Yönlendirici, hedef alan adının uzantısına bakarak görevi doğru bölge kuyruğuna bırakır. .de ile biten bir hedef eu-central-1'e, .jp ile biten bir hedef ap-northeast-1'e gider; eşleşme yoksa varsayılan olarak us-east-1 kullanılır. Kural tablosunu kendi hedef profilinize göre genişletebilirsiniz.

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

Altyapıyı kurun

Terraform iskeleti

Terraform ile bölge listesini tek bir değişkende tutun; for_each her bölge için aynı worker modülünü, görev kuyruğunu ve paylaşılan sonuç kuyruğunu üretsin. API anahtarını asla koda gömmeyin — Secrets Manager üzerinden ARN olarak geçirin.

# 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 ile yerel çoklu bölge simülasyonu

Üretime çıkmadan önce çok bölgeli davranışı yerelde denemek için her bölgeyi ayrı bir Redis veritabanına bağlı bir servis olarak tanımlayın. Böylece yönlendirme ve yük devretme mantığını gerçek bulut maliyeti oluşmadan test edebilirsiniz.

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

Bölge bazında sağlık izleme

Sağlıklı bir yük devretme kararı, önce güvenilir sağlık verisi gerektirir. Her bölge için şu üç sinyali sırayla toplayın:

  1. Gecikme: sağlık uç noktasının yanıt süresi.
  2. Aktif worker sayısı: filonun o an ne kadarının ayakta olduğu.
  3. Kuyruk derinliği: biriken ve henüz işlenmemiş görev sayısı.

Aşağıdaki JavaScript örneği her bölgenin /health uç noktasına istek atar ve yanıt vermeyen bölgeleri unhealthy olarak işaretler — yük devretme kararının girdisi tam olarak budur.

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);

Bir bölge çökerse: yük devretme

Bir bölge sağlıksız duruma düştüğünde görevlerini en düşük kuyruk derinliğine sahip sağlıklı bölgeye yönlendirin. Tüm bölgeler sağlıksızsa sistem sessizce görev düşürmek yerine yüksek sesle hata vermeli — en kötü senaryo, kaybolan görevleri fark etmemektir.

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

Yük devretme politikası

  • Gecikme, hata oranı veya kuyruk derinliği eşik değeri aştığında, bozulan bölgeye yeni görev göndermeyi durdurun.
  • Her kuyruğu ve oturumu bir anda değiştirmek yerine, uçuştaki işleri bilinçli biçimde boşaltın.
  • Trafiği ancak bölge, yük devretmeden önce kullanılan sistem durumu kapılarını yeniden geçtikten sonra kademeli olarak geri açın.

Çok bölgeye geçmeye değer mi?

Tüm bu makineyi kurmadan önce durup şu tabloya bakın. Çok bölge her iş yükü için doğru cevap değildir:

Durum Tek Bölge Çoklu Bölge
Tek ülkedeki hedef siteler Yeterli Gereksiz
Küresel hedef siteler 100–300 ms ilave gecikme Bölge başına yerel gecikme
Yüksek erişilebilirlik (HA) gereksinimi Sağlaması zor Doğal artıklık
Düzenleyici veri yerleşimi Uyum sağlanamıyor Yerel olarak işle
< 1.000 görev/saat İyi Gereksiz karmaşıklık
> 10.000 görev/saat Ölçeklendirme sınırları Yükü dağıtır

Çizgi net: küçük ve tek coğrafyaya bağlı iş yükleri için çok bölge yalnızca gereksiz karmaşıklık ve maliyet ekler. Ancak saatte on binlerce görevi farklı ülkelerdeki sitelere karşı çalıştırıyorsanız, tek bölgenin gecikmesi ve tek hata noktası gerçek bir soruna dönüşür.

Somut bir örnek: İstanbul merkezli bir otomasyon ekibi, hem Türkiye hem de Avrupa'daki hedeflere karşı QA testleri yürütüyor. Türkiye'de bir AWS bölgesi bulunmadığından en düşük gecikmeyi genellikle eu-central-1 (Frankfurt) verir; ABD hedefleri için us-east-1, Asya-Pasifik hedefleri için ap-southeast-1 devreye girer. Worker'ları hedeflere yakın konumlandırmak hem ağ gidiş-dönüş süresini hem de proxy zincirinin uzunluğunu kısaltır. Veri tarafında da KVKK'yı unutmayın: topladığınız veri kişisel veri içeriyorsa, Avrupa kaynaklı trafiği bir Avrupa bölgesinde işlemek uyumu kolaylaştırır ve bu tür işler her zaman yetkili, amaca bağlı veri toplama akışları içinde kalmalıdır.

Maliyet planlaması

Çok bölgeli mimarinin ek maliyeti tamamen altyapı tarafındadır; CaptchaAI, worker'ın hangi kıtada çalıştığına bakmaksızın aynı ücreti alır.

Not: Aşağıdaki bulut kalemleri sağlayıcınıza ve trafiğinize göre değişir. CaptchaAI tarafında bölgeye bağlı bir ek ücret yoktur.

Bileşen Maliyet Faktörü Optimizasyon
Worker örnekleri Bölge başına işlem gücü Boştayken otomatik olarak 0'a ölçeklendirin
Bölgeler arası veri aktarımı Bölgeler arası GB başına yaklaşık $0,02 Sonuç veri boyutunu en aza indirin
SQS kuyrukları İstek başına fiyatlandırma Mümkün olduğunda mesajları toplu gönderin
CaptchaAI API'si Bölgeden bağımsız aynı maliyet Çoklu bölge primi yok

CaptchaAI planları thread bazlıdır: eş zamanlı çözüm sayısı için ödersiniz, çözüm başına değil. Tek bir API anahtarı tüm bölgelerde geçerli olduğundan çok bölgeye geçmek CaptchaAI faturanıza prim eklemez — BASIC ($15/ay, 5 thread) ile başlayıp thread ihtiyacınız arttıkça üst planlara geçebilirsiniz. TL'nin oynaklığı düşünüldüğünde, aylık USD fiyatının öngörülebilir olması Türkiye'deki ekipler için ayrı bir avantajdır.

Sorun giderme

Sorun Sebep Düzeltme
Bir bölge sürekli olarak daha yavaş CaptchaAI sunucularına olan mesafe Temel gecikmeyi karşılaştırın; beklenebilir
Görev yönlendirme her şeyi tek bölgeye gönderiyor Alan adı tabanlı yönlendirme çok geniş Daha ayrıntılı yönlendirme kuralları ekleyin
Yük devretme tetiklenmiyor Sağlık denetimi uç noktası yanıt vermiyor Sağlık uç noktasının worker mantığından ayrı bir yolda olduğundan emin olun
API anahtarı bakiyesi daha hızlı tükeniyor Tüm bölgeler tek anahtarı paylaşıyor Beklenen durum — toplam kullanımı izleyin

Sık sorulan sorular

Çok bölgeli mimari CaptchaAI maliyetimi artırır mı?

Hayır. CaptchaAI thread bazlı faturalandırır ve bölgeye göre prim uygulamaz. Ek maliyet yalnızca worker'ları, kuyrukları ve bölgeler arası veri aktarımını içeren altyapı tarafındadır.

Türkiye ve Avrupa hedefleri için hangi bölgeyi seçmeliyim?

Türkiye'de bir AWS bölgesi olmadığından en düşük gecikmeyi genellikle eu-central-1 (Frankfurt) verir. Avrupa trafiğinin çoğunu tek bir Avrupa bölgesinde toplamak hem gecikmeyi hem de veri yerleşimi yönetimini basitleştirir.

Tüm bölgeler için tek bir CaptchaAI API anahtarı yeterli mi?

Evet. Tek bir anahtar global olarak çalışır. Bölge başına kullanımı, worker'ların döndürdüğü bölge etiketleri üzerinden kendi ölçümlerinizle takip edin.

Sonuç verilerini KVKK açısından nerede işlemeliyim?

Kişisel veri içeren sonuçları, verinin toplandığı bölgeye yakın işlemek uyumu kolaylaştırır. Avrupa kaynaklı veriyi bir Avrupa bölgesinde tutmak, KVKK ve benzeri düzenlemeler için savunulabilir bir varsayılandır. Yetkisiz veri toplama her koşulda kapsam dışıdır.

Sonraki adımlar

CaptchaAI worker'larınızı birden fazla bölgeye dağıtın — API anahtarınızı alın ve küresel bir CAPTCHA çözme altyapısı kurun.

Derinleşmek için başlangıç noktaları:

Bu makale için yorumlar devre dışı bırakılmıştır.