DevOps ve Ölçeklendirme

Google Cloud İşlevleri + CaptchaAI Entegrasyonu

Google Cloud Functions, otomatik ölçeklendirme, kullanım başına ödemeli faturalandırma ve sıkı GCP ekosistemi entegrasyonuyla sunucusuz CAPTCHA çözümü sağlar.


HTTP ile Tetiklenen İşlev

# main.py
import json
import time
import urllib.request
import urllib.parse
import functions_framework


@functions_framework.http
def solve_captcha(request):
    """HTTP Cloud Function for CAPTCHA solving."""
    # Parse request
    request_json = request.get_json(silent=True)
    if not request_json:
        return json.dumps({"error": "JSON body required"}), 400

    method = request_json.get("method", "userrecaptcha")
    params = request_json.get("params", {})

    # Get API key from Secret Manager
    api_key = _get_secret("captchaai-key")

    try:
        token = _solve(api_key, method, params)
        return json.dumps({"token": token})
    except Exception as e:
        return json.dumps({"error": str(e)}), 500


def _get_secret(secret_id):
    """Get secret from GCP Secret Manager."""
    from google.cloud import secretmanager
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{_get_project_id()}/secrets/{secret_id}/versions/latest"
    response = client.access_secret_version(request={"name": name})
    return response.payload.data.decode("UTF-8")


def _get_project_id():
    """Get current GCP project ID."""
    import urllib.request
    req = urllib.request.Request(
        "http://metadata.google.internal/computeMetadata/v1/project/project-id",
        headers={"Metadata-Flavor": "Google"},
    )
    with urllib.request.urlopen(req) as resp:
        return resp.read().decode()


def _solve(api_key, method, params, timeout=90):
    """Solve CAPTCHA via CaptchaAI API."""
    # Submit
    submit_data = urllib.parse.urlencode({
        "key": api_key,
        "method": method,
        "json": 1,
        **params,
    }).encode()

    req = urllib.request.Request(
        "https://ocr.captchaai.com/in.php",
        data=submit_data,
    )
    with urllib.request.urlopen(req, timeout=30) as resp:
        result = json.loads(resp.read())

    if result.get("status") != 1:
        raise RuntimeError(f"Submit error: {result.get('request')}")

    task_id = result["request"]

    # Poll
    start = time.time()
    while time.time() - start < timeout:
        time.sleep(5)
        poll_url = (
            f"https://ocr.captchaai.com/res.php"
            f"?key={api_key}&action=get&id={task_id}&json=1"
        )
        with urllib.request.urlopen(poll_url, timeout=15) as resp:
            data = json.loads(resp.read())

        if data["request"] != "CAPCHA_NOT_READY":
            if data.get("status") == 1:
                return data["request"]
            raise RuntimeError(f"Solve error: {data['request']}")

    raise TimeoutError("Solve timeout")

Gereksinimler

# requirements.txt
functions-framework==3.*
google-cloud-secret-manager==2.*

Dağıt

# Create secret
echo -n "YOUR_API_KEY" | gcloud secrets create captchaai-key --data-file=-

# Deploy function
gcloud functions deploy solve-captcha \
  --gen2 \
  --runtime=python311 \
  --region=us-central1 \
  --source=. \
  --entry-point=solve_captcha \
  --trigger-http \
  --allow-unauthenticated \
  --timeout=120s \
  --memory=256MB \
  --max-instances=100

# Test
curl -X POST https://us-central1-PROJECT.cloudfunctions.net/solve-captcha \
  -H "Content-Type: application/json" \
  -d '{
    "method": "userrecaptcha",
    "params": {
      "googlekey": "SITE_KEY",
      "pageurl": "https://example.com"
    }
  }'

Pub/Sub-Triggered Toplu İşleme

CAPTCHA görevlerini Pub/Sub konusundan işleyin:

import base64
import json
import functions_framework
from google.cloud import pubsub_v1


@functions_framework.cloud_event
def process_captcha_task(cloud_event):
    """Process CAPTCHA task from Pub/Sub message."""
    data = base64.b64decode(cloud_event.data["message"]["data"])
    task = json.loads(data)

    api_key = _get_secret("captchaai-key")

    try:
        token = _solve(api_key, task["method"], task["params"])
        # Publish result
        publisher = pubsub_v1.PublisherClient()
        topic = f"projects/{_get_project_id()}/topics/captcha-results"
        publisher.publish(topic, json.dumps({
            "task_id": task["id"],
            "status": "success",
            "token": token,
        }).encode())

    except Exception as e:
        print(f"Task {task.get('id')} failed: {e}")

Pub/Sub için dağıtın:

gcloud functions deploy process-captcha-task \
  --gen2 \
  --runtime=python311 \
  --trigger-topic=captcha-tasks \
  --timeout=120s \
  --memory=256MB

Görevleri Pub/Sub'ye Gönderin

from google.cloud import pubsub_v1
import json

publisher = pubsub_v1.PublisherClient()
topic = "projects/YOUR_PROJECT/topics/captcha-tasks"

# Submit batch
urls = ["https://site1.com", "https://site2.com", "https://site3.com"]
for i, url in enumerate(urls):
    task = {
        "id": f"task-{i}",
        "method": "userrecaptcha",
        "params": {"googlekey": "SITE_KEY", "pageurl": url},
    }
    publisher.publish(topic, json.dumps(task).encode())
    print(f"Published task-{i}")

Maliyet Karşılaştırması

Faktör Bulut İşlevleri Her Zaman Açık VM
100 çözüm/day ~$0,01/day ~$1,00/day
1.000 çözüm/day ~$0,10/day ~$1,00/day
10.000 çözüm/day ~$1,00/day ~$1,00/day
Boşta kalma maliyeti 0$ Tam VM maliyeti
Soğuk başlangıç ~300ms Yok

Sorun giderme

Sorun Sebep Düzeltme
İşlev zaman aşımına uğradı Zaman aşımı çok kısa --timeout=120s'yi ayarlayın
İzin gizli olarak reddedildi IAM rolü eksik secretmanager.secretAccessor'yi bağışla
Yüksek soğuk başlatma gecikmesi Büyük bağımlılıklar requests yerine urllib kullanın
Pub/Sub mesaj yeniden denemeleri İşlev döndürme hatası Tekrar denenemeyen hatalar için başarıyı döndür

SSS

Gen1 veya Gen2 Bulut İşlevleri?

Gen2'yi kullanın. Daha uzun zaman aşımlarını (60 dakikaya kadar), daha fazla belleği ve eşzamanlılığı destekler; bunların tümü CAPTCHA çözümü için faydalıdır.

Kimlik doğrulamayı nasıl halledebilirim?

Dahili kullanım için --no-allow-unauthenticated ile kimlik doğrulamayı zorunlu kılın. Harici API'ler için, işlevin önünde API anahtarları bulunan API Ağ Geçidini kullanın.

Fonksiyonu sıcak tutabilir miyim?

İşleve her 5 dakikada bir ping atmak için Cloud Scheduler'ı kullanın. Veya --min-instances=1'yi bir bulut sunucusunu sıcak tutacak şekilde ayarlayın (maliyeti ~7$/month).


İlgili Kılavuzlar


GCP'de sunucusuz –CaptchaAI anahtarınızı alınBugün.

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