CAPTCHA sonucunu beklerken thread'leri meşgul tutmak, yüksek hacimli otomasyonlarda boşa giden kapasitedir. Daha temiz yol olay odaklı bir akıştır.
Bu yaklaşımda CaptchaAI çözümü bitirince sonucu bir callback ile iletir, siz bunu AWS SNS (Simple Notification Service) konusuna yayınlarsınız ve SQS, Lambda ya da e-posta gibi tüketiciler sonucu birbirinden bağımsız işler.
Bu rehberde sorgulama tabanlı bir akıştan SNS destekli olay odaklı mimariye geçişi beş adımda kuruyoruz.
Neden sorgulama yerine olay odaklı akış?
Sürekli sorgulama (polling), her aktif görev için bir thread'i sonuç gelene kadar bloke eder. Onlarca eşzamanlı CAPTCHA çözerken bu hem kod karmaşıklığı hem de gereksiz istek demektir. İki yaklaşımı yan yana koyalım:
| Kriter | Sorgulama | Olay odaklı |
|---|---|---|
| Thread kullanımı | Sonuç gelene kadar bloke | Görevi gönderip serbest kalır |
| Ölçeklenme | Kapasite hızla dolar | Tüketiciler bağımsız ölçeklenir |
| Kod karmaşıklığı | Döngü + zaman aşımı yönetimi | Callback + tüketici ayrımı |
| Gecikme | Sorgulama aralığına bağlı | Sonuç hazır olunca anında |
Örneğin İstanbul merkezli bir e-ticaret ekibi, kampanya günlerinde binlerce ödeme ve giriş akışını QA ortamında doğrularken tek bir callback hattını yüzlerce tüketiciye dağıtabilir.
Kazınan verinin kişisel veri içermesi hâlinde KVKK kapsamına girdiğini unutmayın; bu mimariyi yetkili QA ve veri toplama iş akışlarıyla sınırlı tutun.
Mimari nasıl işliyor
[Scraper] → Submit CAPTCHA → [CaptchaAI API]
↓
Solve completes
↓
Callback → [API Gateway + Lambda]
↓
Publish → [SNS Topic]
↓
┌───────────────┼───────────────┐
↓ ↓ ↓
[SQS Queue] [Lambda Logger] [Email Alert]
(result store) (audit trail) (on failure)
SNS fan-out (dağıtım) sağlar: tek bir CAPTCHA sonucu, callback işleyicisinin bunlardan haberi bile olmadan birden fazla tüketiciyi tetikler. Akıştaki bileşenlerin rolleri şöyle ayrışır:
- Callback Lambda: sonucu alır, doğrular ve SNS konusuna yayınlar.
- SNS konusu: sonucu tüm abonelere aynı anda dağıtır.
- Tüketiciler: SQS, Lambda ve e-posta sonucu birbirinden bağımsız işler.
Başlamadan önce
Bu hattı kurmadan önce elinizde şunlar olmalı:
- Aktif bir CaptchaAI hesabı ve API anahtarı.
- SNS, SQS ve Lambda oluşturma izni olan bir AWS hesabı.
- Callback'i yayınlayacak, dışarıya açık bir API Gateway uç noktası.
Adım 1: SNS konusunu oluşturun
Önce sonuçların yayınlanacağı SNS konusunu oluşturun. AWS CLI ile boto3, ikisi de aynı konu ARN'sini üretir.
AWS CLI
aws sns create-topic --name captcha-results --output text
# Returns: arn:aws:sns:us-east-1:123456789:captcha-results
Python (boto3)
import boto3
sns = boto3.client("sns", region_name="us-east-1")
response = sns.create_topic(Name="captcha-results")
topic_arn = response["TopicArn"]
print(f"Topic ARN: {topic_arn}")
Adım 2: Callback alıcısını kurun
Bu Lambda işlevi, CaptchaAI callback sonucunu API Gateway üzerinden alır, doğrular ve SNS konusuna yayınlar.
Callback'i olabildiğince ince tutun; tüm iş mantığını tüketici tarafına bırakırsanız işleyici hızlı kalır ve zaman aşımı riskini düşürürsünüz.
Python (Lambda handler)
import json
import os
import boto3
sns = boto3.client("sns")
TOPIC_ARN = os.environ["SNS_TOPIC_ARN"]
def lambda_handler(event, context):
"""Receive CaptchaAI callback and publish to SNS."""
# Parse query parameters from API Gateway
params = event.get("queryStringParameters", {}) or {}
task_id = params.get("id", "")
solution = params.get("code", "")
if not task_id or not solution:
return {"statusCode": 400, "body": "Missing id or code"}
# Publish to SNS
message = {
"task_id": task_id,
"solution": solution,
"status": "solved"
}
sns.publish(
TopicArn=TOPIC_ARN,
Message=json.dumps(message),
Subject="captcha-solved",
MessageAttributes={
"task_id": {
"DataType": "String",
"StringValue": task_id
}
}
)
return {"statusCode": 200, "body": "OK"}
JavaScript (Lambda handler)
const { SNSClient, PublishCommand } = require("@aws-sdk/client-sns");
const sns = new SNSClient({ region: "us-east-1" });
const TOPIC_ARN = process.env.SNS_TOPIC_ARN;
exports.handler = async (event) => {
const params = event.queryStringParameters || {};
const taskId = params.id;
const solution = params.code;
if (!taskId || !solution) {
return { statusCode: 400, body: "Missing id or code" };
}
const message = {
task_id: taskId,
solution: solution,
status: "solved",
};
await sns.send(
new PublishCommand({
TopicArn: TOPIC_ARN,
Message: JSON.stringify(message),
Subject: "captcha-solved",
MessageAttributes: {
task_id: { DataType: "String", StringValue: taskId },
},
})
);
return { statusCode: 200, body: "OK" };
};
Adım 3: CAPTCHA'ları callback URL'siyle gönderin
CaptchaAI'nin pingback parametresini API Gateway uç noktanıza yönlendirin; çözüm tamamlandığında sonuç doğrudan bu adrese iletilir:
Python
import os
import requests
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
CALLBACK_URL = os.environ["CALLBACK_GATEWAY_URL"] # API Gateway URL
def submit_captcha(sitekey, pageurl):
"""Submit CAPTCHA with SNS-backed callback."""
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"pingback": CALLBACK_URL,
"json": 1
})
data = resp.json()
if data.get("status") == 1:
return data["request"] # task_id
raise RuntimeError(f"Submit failed: {data.get('request')}")
Adım 4: Tüketicileri abone edin
Aynı konuya farklı protokollerle birden fazla tüketici abone edin: sonuç deposu için SQS, denetim izi için Lambda, hata bildirimi için e-posta.
SQS kuyruğu (sonuç deposu)
# Subscribe an SQS queue to receive all results
sqs_arn = "arn:aws:sqs:us-east-1:123456789:captcha-results-queue"
sns.subscribe(
TopicArn=topic_arn,
Protocol="sqs",
Endpoint=sqs_arn
)
Lambda (denetim kaydedici)
# Subscribe a Lambda for audit logging
lambda_arn = "arn:aws:lambda:us-east-1:123456789:function:captcha-audit-logger"
sns.subscribe(
TopicArn=topic_arn,
Protocol="lambda",
Endpoint=lambda_arn
)
E-posta (hata uyarıları)
# Subscribe email for error notifications with filter
sns.subscribe(
TopicArn=topic_arn,
Protocol="email",
Endpoint="ops@example.com"
)
Adım 5: Sonuçları SQS'ten okuyun
Kazıyıcınız artık CaptchaAI'yi sorgulamak yerine çözümleri SQS'ten okur. Uzun sorgulama (long polling) sayesinde kuyruk boşken bile istekleri verimli tutarsınız:
Python
import json
import boto3
sqs = boto3.client("sqs", region_name="us-east-1")
QUEUE_URL = os.environ["SQS_QUEUE_URL"]
def get_solved_captcha(timeout=30):
"""Wait for a CAPTCHA solution from the SQS queue."""
response = sqs.receive_message(
QueueUrl=QUEUE_URL,
MaxNumberOfMessages=1,
WaitTimeSeconds=min(timeout, 20) # Long polling (max 20s)
)
messages = response.get("Messages", [])
if not messages:
return None
msg = messages[0]
# SNS wraps the message — unwrap it
sns_envelope = json.loads(msg["Body"])
result = json.loads(sns_envelope["Message"])
# Delete message after processing
sqs.delete_message(
QueueUrl=QUEUE_URL,
ReceiptHandle=msg["ReceiptHandle"]
)
return result
JavaScript
const {
SQSClient,
ReceiveMessageCommand,
DeleteMessageCommand,
} = require("@aws-sdk/client-sqs");
const sqs = new SQSClient({ region: "us-east-1" });
const QUEUE_URL = process.env.SQS_QUEUE_URL;
async function getSolvedCaptcha(timeout = 30) {
const response = await sqs.send(
new ReceiveMessageCommand({
QueueUrl: QUEUE_URL,
MaxNumberOfMessages: 1,
WaitTimeSeconds: Math.min(timeout, 20),
})
);
const messages = response.Messages || [];
if (messages.length === 0) return null;
const msg = messages[0];
const snsEnvelope = JSON.parse(msg.Body);
const result = JSON.parse(snsEnvelope.Message);
await sqs.send(
new DeleteMessageCommand({
QueueUrl: QUEUE_URL,
ReceiptHandle: msg.ReceiptHandle,
})
);
return result;
}
SNS mesaj filtreleme
Her tüketicinin her mesajı işlemesi gerekmez. FilterPolicy ile bir abone yalnızca ilgilendiği sonuçları alır — örneğin başarısız çözümleri ayrı bir operasyon kuyruğuna yönlendirin:
# Only send failures to the ops queue
sns.subscribe(
TopicArn=topic_arn,
Protocol="sqs",
Endpoint=failure_queue_arn,
Attributes={
"FilterPolicy": json.dumps({
"status": ["failed", "error"]
})
}
)
Maliyet ve ölçeklendirme: thread tabanlı faturalandırma
CaptchaAI çözüm başına değil, eşzamanlı thread başına faturalandırır ve her plan o ay için thread başına sınırsız çözüm içerir. Olay odaklı mimari tam da burada tasarruf sağlar: thread görevi gönderip hemen serbest kaldığı için aynı bütçeyle çok daha fazla eşzamanlı CAPTCHA taşırsınız. Hacme göre başlangıç noktaları:
- BASIC ($15/ay, 5 thread): küçük ekipler ve ilk entegrasyon.
- STANDARD ($30/ay, 15 thread): orta hacimli QA ve veri toplama.
- ADVANCE ($90/ay, 50 thread): kampanya günlerinde yoğun eşzamanlılık.
SNS ve SQS ücretleri tamamen AWS tarafındadır ve mesaj hacmiyle ölçeklenir; CaptchaAI faturanızdan bağımsızdır.
Türkiye'deki geliştiriciler için USD bazlı aylık planların bir avantajı da öngörülebilirliktir — TL kurundaki oynaklık göz önüne alındığında sabit bir thread bütçesi, kapasite planlamasını okunaklı kılar.
İdempotensi ve teslim modeli
SNS mesajları en az bir kez teslim eder; aynı sonuç nadiren de olsa iki kez işlenebilir. Üretimde hattı kararlı tutmak için:
- İşlemeden önce
task_id'yi kalıcı bir depoda (DynamoDB, Redis) kontrol edin; daha önce görülmüşse atlayın. - Sıralı işleme ihtiyacınız varsa SNS FIFO konusunu SQS FIFO kuyruğuyla eşleştirin ve
MessageGroupId'yi görev kimliğine ayarlayın. - Tüketici hata verdiğinde mesajı hemen silmeyin; SQS görünürlük zaman aşımından sonra yeniden denenmesine izin verin.
Böyle bir düzen, yeniden teslimlerin veri bütünlüğünü bozmadığı, üretimde kararlı bir hat verir.
Sorun giderme
| Sorun | Sebep | Düzeltme |
|---|---|---|
| Callback 403 döndürüyor | API Gateway kimlik doğrulaması CaptchaAI'yi engelliyor | Callback yolunda kimlik doğrulamayı kapatın; yerine token tabanlı doğrulama kullanın |
| SQS mesajları gelmiyor | SNS'ten SQS'e yayın izni eksik | SQS kuyruk politikasına sns:Publish iznini ekleyin |
| Aynı sonuç iki kez işleniyor | SNS en az bir kez teslim eder | İdempotensi uygulayın — işlemeden önce task_id'yi kontrol edin |
| Lambda soğuk başlangıcı callback'i geciktiriyor | Provisioned concurrency ayarlı değil | Callback Lambda için provisioned concurrency'yi etkinleştirin |
Sık sorulan sorular
Sorgulama yerine neden olay odaklı akış tercih edeyim?
Sorgulama, her aktif görev için bir thread'i sonuç gelene kadar bloke eder. Olay odaklı akışta ise thread görevi gönderip serbest kalır; sonuç hazır olduğunda callback tetiklenir.
Böylece daha yüksek eşzamanlılığı daha az kaynakla taşır, thread bütçenizi verimli kullanırsınız.
Bu mimari CaptchaAI faturamı nasıl etkiler?
CaptchaAI thread tabanlı faturalandırır, çözüm başına değil; SNS ve SQS maliyetleri AWS tarafındadır. BASIC ($15/ay, 5 thread) ile başlayıp eşzamanlı thread ihtiyacınıza göre üst planlara geçebilirsiniz.
Callback uç noktamı nasıl güvence altına alırım?
API Gateway kimlik doğrulamasını callback yolunda kapatıp bunun yerine paylaşılan bir gizli anahtarla token tabanlı doğrulama yapın.
Ayrıca gelen id ve code alanlarını doğrulayın ve task_id ile idempotensi sağlayarak yinelenen teslimleri güvenle eleyin.
SNS katmanı ne kadar ek gecikme getirir?
SNS mesaj başına yaklaşık 10–50 ms ekler. CAPTCHA çözümleri 5–30 saniye sürdüğü için bu ek yük pratikte ihmal edilebilir düzeydedir.
Hangi CAPTCHA türleri bu mimariyle çalışır?
Callback hattı çözüm türünden bağımsızdır: reCAPTCHA v2 ve v3, Cloudflare Turnstile, GeeTest v3 ve görüntü/OCR CAPTCHA'ları aynı pingback akışını kullanır. Örnek kod userrecaptcha yöntemini gösterir; başka bir tür için yalnızca gönderim parametrelerini değiştirir, SNS ve SQS katmanına hiç dokunmazsınız.
Üretime almadan önce kontrol listesi
Hattı canlıya almadan önce şunları doğrulayın:
- Callback yolunda token tabanlı doğrulama etkin.
- Her tüketici idempotent ve
task_iddenetimli. - SQS için bir ölü mektup kuyruğu (DLQ) tanımlı.
- CloudWatch alarmları SNS teslim hatalarını izliyor.
Ne zaman sorgulama yeterli kalır?
Her senaryo olay odaklı mimari gerektirmez. Şu durumlarda düz sorgulama daha basit kalır:
- Düşük hacimli, ara sıra yapılan tekil çözümlerde.
- Callback alacak, dışarıya açık bir uç noktanız yoksa.
- Prototip ve yerel geliştirme testlerinde.
İlgili makaleler
- istemci CAPTCHA çözüm hatları oluşturma rehberi
- sorumlu otomasyon ilkeleri
- CaptchaAI kullanım panosu izleme kurulumu
Sonraki adımlar
Olay odaklı CAPTCHA çözümünü bugün kurun — CaptchaAI API anahtarınızı alın ve AWS olay hattınıza bağlayın.
İlgili kılavuzlar: