Если ваш HTTP-клиент держит keep-alive-соединение с ocr.captchaai.com, DNS почти не участвует в задержке решения CAPTCHA — резолвинг происходит один раз, а дальше запросы идут по уже открытому TCP-соединению. Проблема начинается там, где соединение создаётся заново под каждый запрос: холодный старт бессерверной функции, короткоживущий воркер парсинга, медленный DNS-резолвер провайдера. В таких сценариях DNS способен добавить от 5 до 200 мс к каждому из 5–7 HTTP-запросов, из которых складывается одно решение CAPTCHA. Разберёмся, когда это действительно ощутимо и как убрать задержку в Python и Node.js.
Когда DNS-резолвинг реально тормозит решение CAPTCHA
DNS становится узким местом в четырёх типичных ситуациях:
- Новое соединение на каждый запрос — нет
Sessionв Python или keep-alive-агента в Node.js, поэтому TCP-хендшейк и DNS-резолвинг повторяются заново при каждом вызове. - Холодный старт контейнера или бессерверной функции — на свежем экземпляре нет ни кеша DNS, ни открытого соединения.
- Медленный DNS-провайдер — DNS хостинга по умолчанию, без локального кеша, резолвит заметно дольше, чем 1.1.1.1 или 8.8.8.8.
- Массовый параллельный запуск воркеров — десятки исполнителей стартуют одновременно, и каждый резолвит DNS с нуля.
Пример из практики: если воркеры парсинга разворачиваются в облачных регионах Европы (Франкфурт, Амстердам) или Центральной Азии, путь до ближайшего DNS-резолвера обычно длиннее, чем из США, — 30–60 мс на один резолв не редкость. При тарифе с фиксированным числом потоков — например, BASIC ($15/мес, 5 потоков) или ADVANCE ($90/мес, 50 потоков) — лишние миллисекунды на резолвинг умножаются на количество параллельных потоков и снижают ту пропускную способность, за которую вы уже заплатили.
Что происходит внутри одного решения CAPTCHA
Одно решение CAPTCHA — это 5–7 HTTP-запросов: одна отправка задачи и 4–6 опросов результата через res.php. Вот как разные стратегии резолвинга DNS влияют на итоговую задержку:
| Сценарий | DNS-резолвингов | Задержка |
|---|---|---|
| Без кеша, медленный DNS (200 мс на запрос) | 7 | 1400 мс |
| DNS-кеш на уровне ОС (резолвинг только на первом вызове) | 1 | 200 мс |
| Keep-alive соединение (0 новых резолвингов) | 0 | 0 мс |
| Предварительное разрешение DNS + keep-alive | 0 | 0 мс |
Главный вывод: если keep-alive уже включён, одно и то же TCP-соединение переиспользует ранее разрешённый IP-адрес, и DNS перестаёт быть проблемой. Резолвинг имеет значение ровно там, где соединения создаются заново под каждый запрос.
Оптимизация DNS в Python
Три шага: сначала измерить, затем закешировать адрес заранее, и только если этого мало — сменить резолвер.
Самый быстрый способ убедиться, что DNS вообще влияет на ваш кейс, — замерить время двух последовательных вызовов getaddrinfo:
import socket
import time
# Measure DNS resolution time
hostname = "ocr.captchaai.com"
start = time.time()
ip = socket.getaddrinfo(hostname, 443)
first_resolve = time.time() - start
start = time.time()
ip = socket.getaddrinfo(hostname, 443)
second_resolve = time.time() - start
print(f"First resolve: {first_resolve*1000:.1f}ms")
print(f"Second resolve: {second_resolve*1000:.1f}ms (OS cached)")
Если разница между первым и вторым замером заметна — резолвите ocr.captchaai.com один раз при старте процесса и держите сессию с keep-alive открытой:
import os
import socket
import requests
from urllib3.util.connection import create_connection
API_KEY = os.environ.get("CAPTCHAAI_KEY", "YOUR_API_KEY")
# Pre-resolve the API hostname
CAPTCHAAI_IP = socket.getaddrinfo("ocr.captchaai.com", 443)[0][4][0]
print(f"Resolved ocr.captchaai.com to {CAPTCHAAI_IP}")
# Patch connection to use cached IP
DNS_CACHE = {"ocr.captchaai.com": CAPTCHAAI_IP}
class CachedHTTPAdapter(requests.adapters.HTTPAdapter):
def send(self, request, **kwargs):
return super().send(request, **kwargs)
# Use with Session for fastest resolution
session = requests.Session()
session.headers.update({"Connection": "keep-alive"})
# The session already maintains keep-alive, so DNS is resolved once
# For the first request, the OS cache handles subsequent lookups
resp = session.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "getbalance", "json": "1",
})
print(f"Balance: {resp.json()}")
Если и после этого задержка остаётся, переключите систему или приложение на быстрый публичный DNS:
# For systems where you control DNS configuration:
# /etc/resolv.conf (Linux) or system DNS settings
# Recommended: Cloudflare (1.1.1.1) or Google (8.8.8.8)
# In Python, you can also use dnspython for explicit resolution
import dns.resolver
resolver = dns.resolver.Resolver()
resolver.nameservers = ["1.1.1.1", "8.8.8.8"]
answers = resolver.resolve("ocr.captchaai.com", "A")
for answer in answers:
print(f"Resolved: {answer}")
Оптимизация DNS в Node.js
Та же логика, что и в Python: сначала замерить, затем убрать резолвинг из горячего пути через keep-alive и предварительное разрешение. Тест на резолвинг — через встроенный модуль dns:
const dns = require('dns');
const { performance } = require('perf_hooks');
const hostname = 'ocr.captchaai.com';
// First resolution
const start1 = performance.now();
dns.lookup(hostname, (err, address) => {
const time1 = performance.now() - start1;
console.log(`First resolve: ${time1.toFixed(1)}ms → ${address}`);
// Second resolution (OS cached)
const start2 = performance.now();
dns.lookup(hostname, (err2, address2) => {
const time2 = performance.now() - start2;
console.log(`Second resolve: ${time2.toFixed(1)}ms → ${address2}`);
});
});
Комбинация предварительного резолвинга и keep-alive-агента убирает DNS из горячего пути полностью:
const dns = require('dns');
const https = require('https');
const axios = require('axios');
const API_KEY = process.env.CAPTCHAAI_KEY || 'YOUR_API_KEY';
// Pre-resolve and cache
let cachedIP = null;
async function preResolve() {
return new Promise((resolve, reject) => {
dns.lookup('ocr.captchaai.com', (err, address) => {
if (err) reject(err);
cachedIP = address;
console.log(`Cached IP: ${cachedIP}`);
resolve(address);
});
});
}
// Use keep-alive agent (DNS resolved once per connection)
const agent = new https.Agent({
keepAlive: true,
maxSockets: 20,
keepAliveMsecs: 60000,
});
const api = axios.create({
baseURL: 'https://ocr.captchaai.com',
httpsAgent: agent,
timeout: 30000,
});
(async () => {
await preResolve();
const resp = await api.get('/res.php', {
params: { key: API_KEY, action: 'getbalance', json: '1' },
});
console.log(`Balance: ${resp.data}`);
})();
DNS в бессерверных и контейнерных средах
В AWS Lambda, Google Cloud Functions и контейнерах Docker поведение DNS-кеша отличается от классического сервера:
| Среда | Поведение DNS-кеша | Рекомендация |
|---|---|---|
| AWS Lambda | Кешируется в рамках контекста выполнения, теряется при холодном старте | Разрешайте адрес заранее в инициализации обработчика |
| Google Cloud Functions | Кешируется в рамках экземпляра | Разрешайте адрес заранее в глобальной области |
| Docker | По умолчанию использует DNS хоста | Настройте --dns 1.1.1.1 |
| Kubernetes | CoreDNS с настраиваемым кешем | Установите ndots: 1 в DNS-конфигурации пода |
Диагностика типичных проблем
Симптом почти всегда указывает на конкретную причину — и на конкретное исправление:
| Симптом | Причина | Что делать |
|---|---|---|
| Первый запрос к API медленный, остальные быстрые | DNS-резолвинг произошёл только на первом вызове | Это нормально при OS-кешировании — используйте keep-alive |
| Все запросы медленные (+100 мс и больше) | DNS не кешируется, резолвер медленный | Переключитесь на 1.1.1.1 или 8.8.8.8 |
| Случайные всплески задержки | Истёк TTL записи в DNS-кеше | Увеличьте локальный TTL кеша или резолвите адрес заранее |
| Холодный старт контейнера медленный | На новом экземпляре нет кешированного DNS | Резолвите адрес заранее в коде инициализации |
Частые вопросы
Сколько DNS-резолвингов реально происходит при одном решении CAPTCHA?
Без кеша — до семи: один при отправке задачи и по одному на каждый опрос res.php. С включённым keep-alive обычно происходит один резолвинг на всё время жизни соединения, а не на каждый запрос.
Обязательно ли переключаться на сторонний DNS-резолвер, если я уже использую keep-alive?
Нет. Если соединение постоянное, DNS резолвится один раз при его установке, и выбор резолвера почти не влияет на итоговую задержку. Переход на 1.1.1.1 или 8.8.8.8 даёт эффект там, где соединения создаются заново под каждый запрос.
Как задержка DNS сказывается на тарифе с фиксированным числом потоков?
Каждый поток, который ждёт резолвинга DNS вместо отправки запроса, простаивает впустую. На тарифах вроде BASIC (5 потоков) или STANDARD ($30/мес, 15 потоков) это заметнее, чем на ENTERPRISE ($300/мес, 200 потоков), где издержки размываются на больший пул, — но принцип один: предварительное разрешение и keep-alive увеличивают полезную пропускную способность без смены тарифа.
Стоит ли беспокоиться о DNS, если парсинг идёт через прокси-серверы?
Да, но с поправкой: DNS для самого прокси и DNS для ocr.captchaai.com резолвятся отдельно. Настройте keep-alive и предварительное разрешение для соединения с CaptchaAI API независимо от того, как настроен прокси для целевого сайта.