API CAPTCHA của bạn đôi khi phản hồi nhanh, đôi khi chậm hẳn dù server và mạng đều ổn định? Thủ phạm thường không phải CaptchaAI hay proxy, mà là một bước ít ai để ý: tra cứu DNS trước mỗi request. Mỗi lần code gọi ocr.captchaai.com mà chưa có kết nối keep-alive, hệ thống phải phân giải tên miền — cộng thêm 5–200 mili giây tùy nhà cung cấp DNS, trạng thái cache và điều kiện mạng. Bài viết chỉ ra khi nào DNS thực sự là nút thắt cổ chai và cách loại bỏ nó bằng caching, pre-resolve và keep-alive.
Khi nào DNS thực sự là nút thắt cổ chai
Xếp theo mức độ thường gặp trong các pipeline giải CAPTCHA thực tế:
- Tạo kết nối mới cho mỗi request — code không dùng
Session(Python) hoặc agent duy trì kết nối (Node.js), nên mỗi request đều phải phân giải lại tên miền. - Cold start trong container hoặc serverless — instance mới tinh chưa có gì trong bộ nhớ đệm DNS.
- Nhà cung cấp DNS phân giải chậm — DNS mặc định của ISP thường không có cache cục bộ tốt.
- Giải CAPTCHA song song khối lượng lớn — nhiều worker khởi động cùng lúc, tất cả cùng tra cứu DNS một lượt.
Nếu pipeline của bạn đã dùng HTTP keep-alive (kết nối liên tục) thì DNS gần như không còn là vấn đề — cùng một kết nối TCP tái sử dụng IP đã phân giải cho toàn bộ vòng đời request. DNS chỉ đáng lo khi kết nối bị tạo mới liên tục.
DNS ảnh hưởng ra sao đến từng lần giải CAPTCHA
Một lần giải CAPTCHA thường gồm 5–7 request HTTP (1 lần gửi task + 4–6 lần polling). Nếu không có bộ nhớ đệm DNS, độ trễ cộng dồn rất nhanh:
| Kịch bản | Số lần tra cứu DNS | Độ trễ cộng thêm |
|---|---|---|
| Không cache, DNS chậm (200ms/lần) | 7 | 1.400 mili giây |
| Cache DNS cấp hệ điều hành (chỉ lần gọi đầu) | 1 | 200 mili giây |
| Kết nối keep-alive (0 tra cứu mới) | 0 | 0 mili giây |
| Pre-resolve DNS + keep-alive | 0 | 0 mili giây |
Ưu tiên keep-alive trước, chỉ đào sâu DNS khi kết nối buộc phải tạo mới liên tục — ví dụ worker ngắn hạn trong Lambda hoặc script chạy một lần rồi thoát.
Tối ưu DNS trong Python
Ba việc nên làm theo thứ tự: đo hiện trạng, pre-resolve thủ công, rồi mới đổi resolver — đừng nhảy thẳng vào bước 3 khi chưa đo.
Đo trước — chênh lệch giữa lần phân giải đầu và lần sau cho biết hệ điều hành đã tự cache hay chưa:
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)")
Nếu lần gọi đầu vẫn chậm dù đã dùng Session, chủ động phân giải DNS trước khi request thật diễn ra:
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()}")
Bước cuối, chỉ cần khi vẫn chậm sau pre-resolve: kiểm tra lại resolver DNS đang dùng — DNS ISP mặc định thường là điểm nghẽn:
# 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}")
Tối ưu DNS trong Node.js
Logic giống Python: đo trước, pre-resolve sau. Node.js xử lý keep-alive qua https.Agent, nên bước pre-resolve chỉ cần chạy một lần khi khởi động tiến trình.
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}`);
});
});
Kết hợp https.Agent với pre-resolve thủ công để loại bỏ hoàn toàn tra cứu DNS trong request thật:
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}`);
})();
Serverless và container: DNS cache hoạt động ra sao
Nhiều team ở Việt Nam (đặc biệt các đội outsourcing/QA chạy scraping và automation cho khách nước ngoài) deploy worker lên AWS Lambda vùng Singapore (ap-southeast-1) vì độ trễ mạng thấp tới Đông Nam Á. Mỗi cold start là một instance "trắng tinh", chưa có gì trong cache DNS. Cách cache DNS hoạt động khác nhau theo từng môi trường:
- AWS Lambda — cache trong execution context, mất sạch khi cold start; pre-resolve ngay trong handler init.
- Google Cloud Functions — cache trong phạm vi instance; pre-resolve ở global scope, ngoài hàm xử lý request.
- Docker — dùng DNS của host theo mặc định; cấu hình rõ
--dns 1.1.1.1nếu DNS host không ổn định. - Kubernetes — CoreDNS với cache có thể cấu hình; đặt
ndots: 1trong DNS config của pod để tránh tra cứu thừa.
Khắc phục sự cố DNS thường gặp
- Request đầu chậm, các request sau nhanh → tra cứu DNS xảy ra ở lần gọi đầu; bình thường nhờ cache hệ điều hành, dùng keep-alive để tránh lặp lại.
- Toàn bộ request đều chậm (~100ms+ cộng thêm) → không có cache DNS, resolver chậm; đổi DNS sang 1.1.1.1 hoặc 8.8.8.8.
- Độ trễ tăng đột biến ngẫu nhiên → cache DNS hết TTL; tăng TTL cache cục bộ hoặc pre-resolve.
- Cold start container chậm → instance mới chưa có DNS cache; pre-resolve trong code khởi tạo.
Câu hỏi thường gặp
Vì sao request CAPTCHA đầu tiên luôn chậm hơn các request sau?
Vì lần gọi đầu tiên là lúc DNS thực sự bị tra cứu; các lần sau tái sử dụng kết quả đã cache ở hệ điều hành hoặc kết nối keep-alive. Đây là hành vi bình thường, không phải lỗi — nếu chênh lệch quá lớn (trên 100ms), kiểm tra lại resolver DNS đang dùng.
Deploy trên AWS Lambda vùng Singapore có cần pre-resolve DNS không?
Có, nếu function bị cold start thường xuyên. Mỗi instance mới không kế thừa cache DNS từ instance trước, nên pre-resolve ocr.captchaai.com trong handler init sẽ tiết kiệm đáng kể cho các lượt cold start.
DNS có thực sự đáng tối ưu khi giải CAPTCHA không?
Với hầu hết pipeline đã dùng kết nối keep-alive, DNS chỉ phân giải một lần rồi tái sử dụng nên không đáng lo. Nó quan trọng chủ yếu ở môi trường serverless, cold start, hoặc khi ứng dụng tạo kết nối mới cho từng request.
CaptchaAI trả về nhiều IP khác nhau, có phải là lỗi không?
Không. DNS có thể trả về IP khác nhau giữa các lần tra cứu — đó là cơ chế cân bằng tải bình thường. Kết nối keep-alive sẽ giữ nguyên IP đã phân giải cho suốt vòng đời của kết nối đó.
Bước tiếp theo
Loại bỏ độ trễ DNS ẩn trong pipeline của bạn — lấy API key CaptchaAI.
Hướng dẫn liên quan: