GraphQL API ngày càng trở nên phổ biến, nhưng cùng với đó là những hạn chế: giới hạn tần suất, chặn theo IP, bộ lọc địa lý. Nếu bạn làm việc với khối lượng dữ liệu lớn qua GraphQL — parse các nền tảng thương mại điện tử, thu thập phân tích từ mạng xã hội hoặc thử nghiệm API — bạn không thể thiếu proxy. Trong bài viết này, chúng ta sẽ tìm hiểu cách cấu hình proxy cho các yêu cầu GraphQL, thực hiện xoay vòng IP và tránh bị chặn.
Chúng tôi sẽ trình bày các ví dụ thực tế bằng Python và Node.js, phân tích các lỗi điển hình và đưa ra khuyến nghị về cách chọn loại proxy cho các nhiệm vụ khác nhau.
Tại sao cần proxy cho các yêu cầu GraphQL
GraphQL API thường được sử dụng để lấy khối lượng lớn dữ liệu trong thời gian ngắn. Khác với REST API, nơi dữ liệu được chia thành nhiều endpoint, GraphQL cho phép yêu cầu tất cả những gì cần thiết chỉ bằng một yêu cầu. Điều này rất tiện lợi, nhưng cũng tạo ra một số vấn đề:
- Giới hạn tần suất — hầu hết các GraphQL API công cộng giới hạn số lượng yêu cầu từ một IP (ví dụ: GitHub API: 5000 yêu cầu mỗi giờ, Shopify: 2 yêu cầu mỗi giây)
- Chặn IP — khi vượt quá giới hạn hoặc có hoạt động nghi ngờ, IP của bạn có thể bị chặn trong vài giờ hoặc vĩnh viễn
- Giới hạn địa lý — một số API chỉ có sẵn từ một số quốc gia nhất định (ví dụ: các chợ địa phương hoặc dịch vụ khu vực)
- Bảo vệ chống lại việc parse — các máy chủ theo dõi các mẫu yêu cầu và chặn các IP nghi ngờ
Proxy giải quyết những vấn đề này, cho phép phân phối các yêu cầu qua nhiều địa chỉ IP, giả lập các yêu cầu từ các khu vực khác nhau và vượt qua các chặn. Điều này đặc biệt quan trọng khi làm việc với:
- Parse dữ liệu từ các nền tảng thương mại điện tử (Shopify, WooCommerce GraphQL API)
- Thu thập phân tích từ mạng xã hội (Facebook Graph API, Instagram API)
- Giám sát giá cả và tình trạng hàng hóa
- Thử nghiệm API từ các vị trí địa lý khác nhau
- Tự động hóa việc thu thập dữ liệu cho phân tích và nghiên cứu
Loại proxy nào nên chọn để làm việc với GraphQL
Việc chọn loại proxy phụ thuộc vào nhiệm vụ và yêu cầu của API. Chúng ta sẽ xem xét ba loại chính và ứng dụng của chúng cho các yêu cầu GraphQL:
| Loại proxy | Tốc độ | Ẩn danh | Khi nào sử dụng |
|---|---|---|---|
| Proxy trung tâm dữ liệu | Rất cao (10-50 ms) | Trung bình | Parse API công cộng, thử nghiệm, tốc độ cao quan trọng hơn ẩn danh |
| Proxy cư trú | Trung bình (100-300 ms) | Rất cao | Làm việc với API bảo mật (Shopify, Facebook), vượt qua các bộ lọc nghiêm ngặt |
| Proxy di động | Trung bình (150-400 ms) | Tối đa | Instagram API, TikTok API, ứng dụng di động với GraphQL |
Khuyến nghị về lựa chọn:
- Cho API công cộng (GitHub, OpenWeather) — chỉ cần proxy trung tâm dữ liệu, chúng nhanh và rẻ
- Cho thương mại điện tử (Shopify, WooCommerce) — proxy cư trú, vì các nền tảng này thường xuyên lọc các trung tâm dữ liệu
- Cho mạng xã hội (Facebook Graph API, Instagram) — proxy di động hoặc cư trú là bắt buộc
- Cho việc parse hàng loạt — kết hợp: trung tâm dữ liệu cho lưu lượng chính + cư trú cho xoay vòng khi bị chặn
Cấu hình proxy trong Python cho GraphQL (requests, httpx, gql)
Python là một trong những ngôn ngữ phổ biến nhất để làm việc với API. Chúng ta sẽ xem xét ba cách để cấu hình proxy cho các yêu cầu GraphQL.
Tùy chọn 1: Thư viện requests (khách hàng HTTP đơn giản)
Cách đơn giản nhất là sử dụng thư viện chuẩn requests. Phù hợp cho các yêu cầu GraphQL cơ bản mà không có logic phức tạp.
import requests
import json
# Cấu hình proxy
proxies = {
'http': 'http://username:password@proxy.example.com:8080',
'https': 'http://username:password@proxy.example.com:8080'
}
# Yêu cầu GraphQL
query = """
query {
products(first: 10) {
edges {
node {
id
title
priceRange {
minVariantPrice {
amount
}
}
}
}
}
}
"""
# Gửi yêu cầu qua proxy
url = "https://your-shop.myshopify.com/api/2024-01/graphql.json"
headers = {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': 'your_token_here',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
response = requests.post(
url,
json={'query': query},
headers=headers,
proxies=proxies,
timeout=30
)
data = response.json()
print(json.dumps(data, indent=2))
Tùy chọn 2: Thư viện httpx (yêu cầu bất đồng bộ)
Nếu cần gửi nhiều yêu cầu song song, hãy sử dụng httpx với hỗ trợ async/await:
import httpx
import asyncio
import json
async def fetch_graphql(query, proxy_url):
url = "https://api.example.com/graphql"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
}
# Cấu hình proxy cho httpx
proxies = {
"http://": proxy_url,
"https://": proxy_url
}
async with httpx.AsyncClient(proxies=proxies, timeout=30.0) as client:
response = await client.post(
url,
json={'query': query},
headers=headers
)
return response.json()
# Sử dụng
query = """
query {
viewer {
login
repositories(first: 5) {
nodes {
name
stargazerCount
}
}
}
}
"""
proxy = "http://user:pass@proxy.example.com:8080"
result = asyncio.run(fetch_graphql(query, proxy))
print(json.dumps(result, indent=2))
Tùy chọn 3: Thư viện gql (khách hàng GraphQL chuyên dụng)
Để làm việc nâng cao với GraphQL, hãy sử dụng thư viện gql — nó hỗ trợ xác thực sơ đồ, lưu trữ và làm việc thuận tiện với các yêu cầu:
from gql import gql, Client
from gql.transport.requests import RequestsHTTPTransport
# Cấu hình vận chuyển với proxy
transport = RequestsHTTPTransport(
url='https://api.example.com/graphql',
headers={
'Authorization': 'Bearer YOUR_TOKEN',
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64)'
},
proxies={
'http': 'http://user:pass@proxy.example.com:8080',
'https': 'http://user:pass@proxy.example.com:8080'
},
timeout=30
)
# Tạo khách hàng
client = Client(transport=transport, fetch_schema_from_transport=True)
# Yêu cầu GraphQL
query = gql("""
query GetProducts($first: Int!) {
products(first: $first) {
edges {
node {
id
title
variants(first: 1) {
edges {
node {
price
}
}
}
}
}
}
}
""")
# Thực hiện yêu cầu
result = client.execute(query, variable_values={"first": 20})
print(result)
Cấu hình proxy trong Node.js cho GraphQL (axios, apollo-client)
Node.js cũng được sử dụng rộng rãi để làm việc với GraphQL API. Chúng ta sẽ xem xét hai cách tiếp cận chính.
Tùy chọn 1: Axios với proxy
Khách hàng HTTP đơn giản và linh hoạt với hỗ trợ proxy:
const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');
// Cấu hình proxy
const proxyUrl = 'http://username:password@proxy.example.com:8080';
const httpsAgent = new HttpsProxyAgent(proxyUrl);
// Yêu cầu GraphQL
const query = `
query {
products(first: 10) {
edges {
node {
id
title
priceRange {
minVariantPrice {
amount
}
}
}
}
}
}
`;
// Gửi yêu cầu
axios.post('https://your-shop.myshopify.com/api/2024-01/graphql.json',
{ query },
{
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': 'your_token_here',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
},
httpsAgent: httpsAgent,
timeout: 30000
}
)
.then(response => {
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error('Lỗi:', error.message);
});
Tùy chọn 2: Apollo Client với proxy
Apollo Client — khách hàng GraphQL phổ biến nhất cho Node.js và trình duyệt. Cấu hình proxy thông qua fetch tùy chỉnh:
const { ApolloClient, InMemoryCache, HttpLink, gql } = require('@apollo/client');
const fetch = require('cross-fetch');
const HttpsProxyAgent = require('https-proxy-agent');
// Đại lý proxy
const proxyUrl = 'http://user:pass@proxy.example.com:8080';
const agent = new HttpsProxyAgent(proxyUrl);
// Fetch tùy chỉnh với proxy
const customFetch = (uri, options) => {
return fetch(uri, {
...options,
agent: agent
});
};
// Tạo Apollo Client
const client = new ApolloClient({
link: new HttpLink({
uri: 'https://api.example.com/graphql',
fetch: customFetch,
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
}
}),
cache: new InMemoryCache()
});
// Yêu cầu GraphQL
const GET_REPOS = gql`
query GetRepositories($login: String!) {
user(login: $login) {
repositories(first: 5) {
nodes {
name
stargazerCount
}
}
}
}
`;
// Thực hiện yêu cầu
client.query({
query: GET_REPOS,
variables: { login: 'facebook' }
})
.then(result => {
console.log(JSON.stringify(result.data, null, 2));
})
.catch(error => {
console.error('Lỗi:', error);
});
Thực hiện xoay vòng proxy để vượt qua giới hạn tần suất
Xoay vòng proxy là kỹ thuật chính để vượt qua các hạn chế của API. Thay vì gửi tất cả các yêu cầu từ một IP, bạn phân phối chúng giữa nhiều proxy. Điều này cho phép vượt qua giới hạn tần suất và tránh bị chặn.
Xoay vòng đơn giản trên Python
Triển khai cơ bản của việc xoay vòng với chuyển đổi vòng lặp proxy:
import requests
import itertools
import time
# Danh sách proxy
PROXY_LIST = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
'http://user:pass@proxy4.example.com:8080',
]
# Tạo một bộ lặp vô hạn
proxy_pool = itertools.cycle(PROXY_LIST)
def make_graphql_request(query):
"""Gửi yêu cầu GraphQL với xoay vòng proxy"""
proxy = next(proxy_pool)
proxies = {'http': proxy, 'https': proxy}
url = "https://api.example.com/graphql"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
try:
response = requests.post(
url,
json={'query': query},
headers=headers,
proxies=proxies,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Lỗi với proxy {proxy}: {e}")
# Chuyển sang proxy tiếp theo
return make_graphql_request(query)
# Ví dụ sử dụng
queries = [
'query { products(first: 10) { edges { node { id title } } } }',
'query { collections(first: 5) { edges { node { id title } } } }',
'query { shop { name email } }'
]
for query in queries:
result = make_graphql_request(query)
print(result)
time.sleep(1) # Tạm dừng giữa các yêu cầu
Xoay vòng thông minh với theo dõi lỗi
Phiên bản nâng cao hơn, theo dõi các proxy không hoạt động và tự động loại bỏ chúng khỏi bể:
import requests
import random
from collections import defaultdict
import time
class ProxyRotator:
def __init__(self, proxy_list, max_failures=3):
self.proxy_list = proxy_list.copy()
self.max_failures = max_failures
self.failures = defaultdict(int)
self.active_proxies = proxy_list.copy()
def get_proxy(self):
"""Lấy một proxy ngẫu nhiên đang hoạt động"""
if not self.active_proxies:
raise Exception("Tất cả các proxy đều không khả dụng!")
return random.choice(self.active_proxies)
def mark_failure(self, proxy):
"""Đánh dấu một cố gắng không thành công"""
self.failures[proxy] += 1
if self.failures[proxy] >= self.max_failures:
print(f"Proxy {proxy} đã bị loại khỏi bể (vượt quá giới hạn lỗi)")
if proxy in self.active_proxies:
self.active_proxies.remove(proxy)
def mark_success(self, proxy):
"""Đặt lại bộ đếm lỗi khi thành công"""
self.failures[proxy] = 0
# Khởi tạo
proxies = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
]
rotator = ProxyRotator(proxies)
def graphql_request_with_retry(query, max_retries=3):
"""Yêu cầu GraphQL với tự động thử lại"""
for attempt in range(max_retries):
proxy = rotator.get_proxy()
proxies_dict = {'http': proxy, 'https': proxy}
try:
response = requests.post(
'https://api.example.com/graphql',
json={'query': query},
headers={
'Content-Type': 'application/json',
'Authorization': 'Bearer TOKEN',
'User-Agent': 'Mozilla/5.0'
},
proxies=proxies_dict,
timeout=30
)
response.raise_for_status()
# Thành công — đặt lại bộ đếm lỗi
rotator.mark_success(proxy)
return response.json()
except Exception as e:
print(f"Cố gắng {attempt + 1}/{max_retries} với {proxy} không thành công: {e}")
rotator.mark_failure(proxy)
time.sleep(2) # Tạm dừng trước khi thử lại
raise Exception("Không thể thực hiện yêu cầu sau tất cả các cố gắng")
# Sử dụng
query = 'query { products(first: 10) { edges { node { id title } } } }'
result = graphql_request_with_retry(query)
print(result)
Cấu hình tiêu đề và User-Agent cho các yêu cầu GraphQL
Các tiêu đề HTTP chính xác là rất quan trọng để làm việc thành công với GraphQL API qua proxy. Nhiều API kiểm tra không chỉ IP mà còn cả tiêu đề yêu cầu.
Các tiêu đề bắt buộc cho GraphQL
headers = {
# Loại nội dung — luôn là application/json cho GraphQL
'Content-Type': 'application/json',
# Xác thực (tùy thuộc vào API)
'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
# hoặc
'X-Shopify-Storefront-Access-Token': 'token_here',
# User-Agent — giả lập trình duyệt thực
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
# Accept — chỉ định rằng chúng tôi chấp nhận JSON
'Accept': 'application/json',
# Accept-Language — ngôn ngữ của người dùng
'Accept-Language': 'en-US,en;q=0.9',
# Accept-Encoding — hỗ trợ nén
'Accept-Encoding': 'gzip, deflate, br',
# Referer — từ đâu yêu cầu đến (tùy chọn)
'Referer': 'https://example.com/',
# Origin — cho các yêu cầu CORS
'Origin': 'https://example.com'
}
Xoay vòng User-Agent
Để tăng cường ẩn danh, nên xoay vòng User-Agent cùng với proxy:
import random
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Safari/605.1.15'
]
def get_random_headers(token):
"""Tạo tiêu đề ngẫu nhiên"""
return {
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}',
'User-Agent': random.choice(USER_AGENTS),
'Accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br'
}
Xử lý lỗi và thử lại qua proxy
Khi làm việc với proxy, lỗi là điều không thể tránh khỏi: thời gian chờ, proxy không khả dụng, chặn. Quan trọng là phải xử lý đúng các tình huống này và thực hiện cơ chế thử lại.
Các lỗi điển hình của GraphQL qua proxy
- Thời gian chờ — proxy chậm hoặc quá tải (tăng thời gian chờ lên 30-60 giây)
- HTTP 407 Cần xác thực proxy — tên đăng nhập/mật khẩu proxy không chính xác
- HTTP 429 Quá nhiều yêu cầu — vượt quá giới hạn tần suất (cần xoay vòng proxy)
- HTTP 403 Bị cấm — IP của proxy bị chặn (thay đổi loại proxy thành cư trú)
- Kết nối bị từ chối — proxy không khả dụng (loại bỏ khỏi bể)
Xử lý lỗi nâng cao
import requests
import time
from requests.exceptions import ProxyError, Timeout, ConnectionError
def graphql_request_robust(query, proxy, max_retries=3, backoff=2):
"""
Yêu cầu GraphQL đáng tin cậy với xử lý tất cả các loại lỗi
Args:
query: Yêu cầu GraphQL
proxy: URL proxy
max_retries: số lần cố gắng tối đa
backoff: hệ số độ trễ giữa các lần cố gắng
"""
url = "https://api.example.com/graphql"
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer TOKEN',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
}
proxies = {'http': proxy, 'https': proxy}
for attempt in range(max_retries):
try:
response = requests.post(
url,
json={'query': query},
headers=headers,
proxies=proxies,
timeout=30
)
# Kiểm tra giới hạn tần suất
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Giới hạn tần suất! Chờ {retry_after} giây...")
time.sleep(retry_after)
continue
# Kiểm tra chặn IP
if response.status_code == 403:
print(f"IP {proxy} bị chặn! Cần một proxy khác.")
raise Exception("IP bị chặn")
# Kiểm tra lỗi xác thực proxy
if response.status_code == 407:
print(f"Lỗi xác thực proxy {proxy}")
raise Exception("Xác thực proxy thất bại")
response.raise_for_status()
# Kiểm tra lỗi GraphQL
data = response.json()
if 'errors' in data:
print(f"Lỗi GraphQL: {data['errors']}")
# Một số lỗi có thể thử lại, một số không
if is_retryable_graphql_error(data['errors']):
time.sleep(backoff * (attempt + 1))
continue
else:
raise Exception(f"Lỗi GraphQL: {data['errors']}")
return data
except (ProxyError, ConnectionError) as e:
print(f"Cố gắng {attempt + 1}: Proxy không khả dụng - {e}")
time.sleep(backoff * (attempt + 1))
except Timeout as e:
print(f"Cố gắng {attempt + 1}: Thời gian chờ - {e}")
time.sleep(backoff * (attempt + 1))
except requests.exceptions.HTTPError as e:
print(f"Cố gắng {attempt + 1}: Lỗi HTTP - {e}")
if attempt < max_retries - 1:
time.sleep(backoff * (attempt + 1))
else:
raise
raise Exception(f"Không thể thực hiện yêu cầu sau {max_retries} cố gắng")
def is_retryable_graphql_error(errors):
"""Xác định xem có thể thử lại yêu cầu khi gặp lỗi GraphQL hay không"""
retryable_codes = ['THROTTLED', 'INTERNAL_ERROR', 'TIMEOUT']
for error in errors:
if error.get('extensions', {}).get('code') in retryable_codes:
return True
return False
Các thực tiễn tốt nhất khi làm việc với GraphQL qua proxy
Chúng ta sẽ tổng kết và đưa ra khuyến nghị để làm việc hiệu quả với GraphQL API qua proxy:
✓ Tối ưu hóa yêu cầu
- Yêu cầu chỉ các trường cần thiết — GraphQL cho phép chỉ định chính xác những gì cần
- Sử dụng phân trang thay vì yêu cầu tất cả dữ liệu cùng một lúc
- Nhóm các yêu cầu liên quan thành một (GraphQL hỗ trợ nhiều yêu cầu)
- Lưu trữ kết quả ở phía khách hàng để giảm số lượng yêu cầu
✓ Quản lý proxy
- Sử dụng bể ít nhất 5-10 proxy cho việc xoay vòng
- Thường xuyên kiểm tra tính khả dụng của proxy (kiểm tra sức khỏe)
- Tự động loại bỏ các proxy không hoạt động khỏi bể
- Đối với các nhiệm vụ quan trọng, giữ các proxy dự phòng loại khác
✓ Tuân thủ giới hạn
- Nghiên cứu tài liệu API — có thông tin chi tiết về giới hạn
- Thêm độ trễ giữa các yêu cầu (ít nhất 1-2 giây)
- Theo dõi các tiêu đề X-RateLimit-Remaining và X-RateLimit-Reset
- Khi nhận được lỗi 429, tăng độ trễ theo cấp số nhân
✓ An toàn và ẩn danh
- Luôn sử dụng proxy HTTPS để bảo vệ các token xác thực
- Xoay vòng User-Agent cùng với proxy
- Không lưu trữ token trong mã — sử dụng biến môi trường
- Chỉ ghi lại thông tin tối thiểu cần thiết
Kiến trúc được khuyến nghị cho các dự án quy mô lớn
Nếu bạn làm việc với khối lượng dữ liệu lớn, chúng tôi khuyên bạn nên sử dụng kiến trúc sau:
- Hàng đợi tác vụ (Redis, RabbitMQ) — để phân phối các yêu cầu giữa các worker
- Bể worker — mỗi worker sử dụng proxy riêng của mình
- Quản lý proxy — theo dõi trạng thái của proxy và phân phối chúng giữa các worker
- Cơ sở dữ liệu — để lưu trữ kết quả và trạng thái của các tác vụ
- Giám sát — theo dõi lỗi, tốc độ, sử dụng proxy
Kết luận
Làm việc với GraphQL API qua proxy không chỉ đơn giản là thêm tham số proxies vào yêu cầu. Để làm việc đáng tin cậy và hiệu quả, cần thực hiện xoay vòng proxy, xử lý lỗi đúng cách, cấu hình tiêu đề và tuân thủ giới hạn của API. Chúng tôi đã xem xét các ví dụ thực tế bằng Python và Node.js mà bạn có thể sử dụng ngay trong các dự án của mình.
Những kết luận chính: sử dụng proxy cư trú cho các API bảo mật (Shopify, Facebook), trung tâm dữ liệu cho các API công cộng và parse hàng loạt, thực hiện xoay vòng tự động với việc loại bỏ các proxy không hoạt động, thêm độ trễ và xử lý tất cả các loại lỗi. Điều này sẽ cho phép bạn làm việc ổn định với bất kỳ GraphQL API nào mà không bị chặn.
Nếu bạn dự định làm việc với GraphQL API trong môi trường sản xuất, chúng tôi khuyên bạn nên sử dụng proxy cư trú — chúng cung cấp độ ổn định tối đa và rủi ro bị chặn tối thiểu. Đối với thử nghiệm và phát triển, proxy trung tâm dữ liệu là lựa chọn phù hợp — chúng nhanh hơn và rẻ hơn.