Quay lại blog

Cách cấu hình proxy trong AWS Lambda cho việc phân tích và API: hướng dẫn đầy đủ với ví dụ

Hướng dẫn từng bước để cấu hình proxy trong AWS Lambda cho việc phân tích, yêu cầu API và tự động hóa. Ví dụ mã trên Python và Node.js, giải quyết các vấn đề thường gặp.

📅18 tháng 2, 2026
```html

AWS Lambda là một nền tảng serverless cho phép chạy mã mà không cần quản lý máy chủ. Tuy nhiên, khi làm việc với việc phân tích trang web, API của các chợ trực tuyến hoặc tự động hóa các tác vụ, thường xảy ra vấn đề: các hàm Lambda sử dụng địa chỉ IP của AWS, dễ dàng bị phát hiện và chặn. Trong hướng dẫn này, chúng ta sẽ xem xét cách tích hợp proxy vào Lambda, cấu hình xoay vòng IP và tránh các lỗi phổ biến.

Bài viết này hướng tới các nhà phát triển tự động hóa các tác vụ thông qua AWS Lambda: phân tích dữ liệu từ các trang web bảo mật, theo dõi giá cả của đối thủ, làm việc với API của mạng xã hội hoặc chợ trực tuyến. Bạn sẽ nhận được các ví dụ mã sẵn có bằng Python và Node.js, có thể sử dụng ngay sau khi đọc.

Tại sao cần proxy trong AWS Lambda

AWS Lambda mặc định sử dụng địa chỉ IP từ nhóm Amazon Web Services. Những địa chỉ này nằm trong danh sách công khai và dễ dàng bị phát hiện bởi các hệ thống bảo vệ chống bot. Dưới đây là những kịch bản chính khi proxy trở nên cần thiết:

Trường hợp thực tế: Một nhà phát triển đã cấu hình Lambda để theo dõi giá trên Wildberries mỗi 15 phút. Sau 2 ngày, chợ trực tuyến bắt đầu trả về lỗi 403 Forbidden — IP AWS đã bị đưa vào danh sách đen. Sau khi kết nối với proxy cư trú, việc phân tích đã hoạt động ổn định trong 6 tháng.

Các lý do chính để sử dụng proxy trong Lambda:

  • Phân tích các trang web bảo mật: Nhiều trang web chặn các yêu cầu từ địa chỉ IP của các trung tâm dữ liệu AWS. Proxy cho phép che giấu Lambda dưới dạng người dùng bình thường.
  • Giới hạn địa lý: Nếu bạn cần lấy dữ liệu từ một trang web chỉ có sẵn từ một quốc gia cụ thể (ví dụ: giá cả khu vực trên Ozon), proxy với địa lý cần thiết sẽ giải quyết vấn đề.
  • Vượt qua giới hạn tốc độ: API của nhiều dịch vụ giới hạn số lượng yêu cầu từ một IP. Xoay vòng proxy cho phép phân phối tải.
  • Thử nghiệm A/B quảng cáo: Kiểm tra hiển thị quảng cáo từ các khu vực khác nhau để phân tích đối thủ.
  • Theo dõi chợ trực tuyến: Theo dõi vị trí sản phẩm, giá cả của đối thủ trên Wildberries, Ozon, Avito mà không bị chặn.

Các hàm Lambda thường được kích hoạt theo lịch trình (thông qua CloudWatch Events) hoặc các trình kích hoạt, điều này làm cho chúng trở thành công cụ lý tưởng cho tự động hóa. Tuy nhiên, nếu không có proxy, những tác vụ như vậy nhanh chóng gặp phải tình trạng chặn từ các nguồn tài nguyên mục tiêu.

Loại proxy nào nên chọn cho Lambda

Việc chọn loại proxy phụ thuộc vào tác vụ mà hàm Lambda của bạn đang giải quyết. Chúng ta sẽ xem xét ba loại chính và ứng dụng của chúng trong kiến trúc serverless:

Loại proxy Tốc độ Độ ẩn danh Kịch bản tốt nhất cho Lambda
Proxy trung tâm dữ liệu Rất cao (50-200 ms) Trung bình Phân tích API không có bảo vệ nghiêm ngặt, kiểm tra khả dụng hàng loạt, theo dõi SEO
Proxy cư trú Trung bình (300-800 ms) Rất cao Phân tích các trang web bảo mật (chợ trực tuyến, mạng xã hội), vượt qua Cloudflare, làm việc với API Instagram/Facebook
Proxy di động Trung bình (400-1000 ms) Tối đa Làm việc với API di động (TikTok, Instagram), thử nghiệm quảng cáo di động, vượt qua các bảo vệ nghiêm ngặt nhất

Khuyến nghị về lựa chọn:

  • Đối với phân tích Wildberries, Ozon, Avito: Sử dụng proxy cư trú với địa lý Nga. Những nền tảng này thường xuyên chặn IP của các trung tâm dữ liệu.
  • Đối với theo dõi API không có bảo vệ nghiêm ngặt: Proxy trung tâm dữ liệu là đủ, chúng rẻ hơn và nhanh hơn.
  • Đối với làm việc với API Instagram, Facebook, TikTok: Chỉ sử dụng proxy di động hoặc cư trú — những nền tảng này phát hiện và cấm các trung tâm dữ liệu.
  • Đối với vượt qua Cloudflare, PerimeterX: Proxy cư trú với xoay vòng, tốt nhất là với phiên sticky (giữ IP từ 5-30 phút).

Quan trọng: Các hàm Lambda có giới hạn thời gian thực hiện (tối đa 15 phút). Khi sử dụng proxy chậm (cư trú/di động), hãy tính đến độ trễ — nếu yêu cầu qua proxy mất 2 giây, thì trong 15 phút bạn có thể thực hiện tối đa ~450 yêu cầu.

Cấu hình proxy trong Lambda bằng Python (requests, urllib3)

Python là ngôn ngữ phổ biến nhất cho các hàm Lambda, đặc biệt là cho các tác vụ phân tích và tự động hóa. Chúng ta sẽ xem xét cách cấu hình proxy với thư viện requests, được sử dụng trong 90% trường hợp.

Cấu hình cơ bản HTTP proxy

Cách đơn giản nhất để kết nối proxy là truyền tham số proxies vào phương thức requests.get():

import requests
import os

def lambda_handler(event, context):
    # Lấy thông tin xác thực proxy từ biến môi trường
    proxy_host = os.environ['PROXY_HOST']  # Ví dụ: proxy.example.com
    proxy_port = os.environ['PROXY_PORT']  # Ví dụ: 8080
    proxy_user = os.environ['PROXY_USER']
    proxy_pass = os.environ['PROXY_PASS']
    
    # Tạo URL proxy với xác thực
    proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    try:
        # Thực hiện yêu cầu qua proxy
        response = requests.get(
            'https://api.example.com/data',
            proxies=proxies,
            timeout=10  # Quan trọng! Đặt timeout
        )
        
        return {
            'statusCode': 200,
            'body': response.text
        }
    
    except requests.exceptions.ProxyError as e:
        print(f"Lỗi proxy: {e}")
        return {
            'statusCode': 500,
            'body': 'Kết nối proxy thất bại'
        }
    
    except requests.exceptions.Timeout as e:
        print(f"Lỗi timeout: {e}")
        return {
            'statusCode': 504,
            'body': 'Yêu cầu timeout'
        }

Các điểm chính của mã này:

  • Biến môi trường: Không bao giờ lưu trữ thông tin xác thực proxy trực tiếp trong mã! Sử dụng Biến Môi Trường trong cài đặt Lambda.
  • Timeout: Nhất định phải đặt timeout (10-30 giây). Nếu không, Lambda có thể bị treo cho đến khi hết thời gian thực hiện tối đa.
  • Xử lý lỗi: Proxy có thể không khả dụng hoặc chậm — luôn xử lý các ngoại lệ ProxyErrorTimeout.
  • HTTP và HTTPS: Chỉ định cả hai giao thức trong từ điển proxies, ngay cả khi chỉ sử dụng HTTPS.

Cấu hình SOCKS5 proxy

SOCKS5 proxy cung cấp mức độ ẩn danh cao hơn và hoạt động ở cấp độ TCP, làm cho chúng không bị phát hiện bởi một số hệ thống bảo vệ. Để làm việc với SOCKS5 trong requests, cần thư viện requests[socks]:

import requests
import os

def lambda_handler(event, context):
    proxy_host = os.environ['PROXY_HOST']
    proxy_port = os.environ['PROXY_PORT']
    proxy_user = os.environ['PROXY_USER']
    proxy_pass = os.environ['PROXY_PASS']
    
    # SOCKS5 proxy với xác thực
    proxy_url = f"socks5://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    try:
        response = requests.get(
            'https://www.wildberries.ru/catalog/12345/detail.aspx',
            proxies=proxies,
            timeout=15
        )
        
        # Phân tích dữ liệu
        return {
            'statusCode': 200,
            'body': response.text
        }
    
    except Exception as e:
        print(f"Lỗi: {e}")
        return {
            'statusCode': 500,
            'body': str(e)
        }

Quan trọng cho việc triển khai trong Lambda: Khi sử dụng SOCKS5, hãy thêm vào requirements.txt:

requests[socks]
PySocks

Kiểm tra IP qua proxy

Trước khi chạy logic chính, hữu ích để kiểm tra xem proxy có hoạt động và trả về IP cần thiết không:

def check_proxy_ip(proxies):
    """Kiểm tra IP mà thế giới bên ngoài thấy qua proxy"""
    try:
        response = requests.get(
            'https://api.ipify.org?format=json',
            proxies=proxies,
            timeout=10
        )
        ip_data = response.json()
        print(f"IP hiện tại qua proxy: {ip_data['ip']}")
        return ip_data['ip']
    except Exception as e:
        print(f"Kiểm tra proxy thất bại: {e}")
        return None

def lambda_handler(event, context):
    # ... cấu hình proxy ...
    
    # Kiểm tra IP trước khi làm việc chính
    current_ip = check_proxy_ip(proxies)
    if not current_ip:
        return {
            'statusCode': 500,
            'body': 'Xác minh proxy thất bại'
        }
    
    # Logic chính của phân tích
    # ...

Cấu hình proxy trong Lambda bằng Node.js (axios, got)

Node.js là ngôn ngữ phổ biến thứ hai cho các hàm Lambda, đặc biệt khi cần hiệu suất cao khi làm việc với API. Chúng ta sẽ xem xét cách cấu hình proxy với các thư viện axiosgot.

Cấu hình với axios

Axios là thư viện HTTP phổ biến nhất cho Node.js. Để làm việc với proxy, cần một gói bổ sung https-proxy-agent:

const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

exports.handler = async (event) => {
    // Lấy thông tin xác thực từ biến môi trường
    const proxyHost = process.env.PROXY_HOST;
    const proxyPort = process.env.PROXY_PORT;
    const proxyUser = process.env.PROXY_USER;
    const proxyPass = process.env.PROXY_PASS;
    
    // Tạo URL proxy
    const proxyUrl = `http://${proxyUser}:${proxyPass}@${proxyHost}:${proxyPort}`;
    
    // Tạo tác nhân cho proxy
    const agent = new HttpsProxyAgent(proxyUrl);
    
    try {
        const response = await axios.get('https://api.example.com/data', {
            httpsAgent: agent,
            timeout: 10000  // 10 giây
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.data)
        };
    } catch (error) {
        console.error('Yêu cầu thất bại:', error.message);
        
        return {
            statusCode: 500,
            body: JSON.stringify({
                error: error.message
            })
        };
    }
};

Cài đặt phụ thuộc: Thêm vào package.json:

{
  "dependencies": {
    "axios": "^1.6.0",
    "https-proxy-agent": "^7.0.0"
  }
}

Cấu hình SOCKS5 với axios

Đối với SOCKS5 proxy, sử dụng gói socks-proxy-agent:

const axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');

exports.handler = async (event) => {
    const proxyUrl = `socks5://${process.env.PROXY_USER}:${process.env.PROXY_PASS}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
    
    const agent = new SocksProxyAgent(proxyUrl);
    
    try {
        const response = await axios.get('https://www.ozon.ru/api/products', {
            httpAgent: agent,
            httpsAgent: agent,
            timeout: 15000
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.data)
        };
    } catch (error) {
        console.error('Lỗi:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

Lựa chọn khác: thư viện got

Got là thư viện HTTP hiện đại với hỗ trợ proxy tích hợp (không cần tác nhân riêng):

const got = require('got');

exports.handler = async (event) => {
    const proxyUrl = `http://${process.env.PROXY_USER}:${process.env.PROXY_PASS}@${process.env.PROXY_HOST}:${process.env.PROXY_PORT}`;
    
    try {
        const response = await got('https://api.example.com/data', {
            agent: {
                http: new (require('http-proxy-agent'))(proxyUrl),
                https: new (require('https-proxy-agent'))(proxyUrl)
            },
            timeout: {
                request: 10000
            },
            responseType: 'json'
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.body)
        };
    } catch (error) {
        console.error('Lỗi:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

Xoay vòng proxy trong Lambda: cách thay đổi IP tự động

Xoay vòng proxy là rất quan trọng cho các tác vụ cần thực hiện nhiều yêu cầu mà không bị chặn. Có hai cách tiếp cận chính: sử dụng dịch vụ proxy với xoay vòng tự động hoặc quản lý thủ công nhóm proxy.

Xoay vòng tự động qua nhà cung cấp

Hầu hết các nhà cung cấp proxy cư trú (bao gồm ProxyCove) cung cấp endpoint với xoay vòng tự động — mỗi yêu cầu hoặc mỗi N phút, IP sẽ tự động thay đổi:

import requests
import os

def lambda_handler(event, context):
    # Proxy với xoay vòng tự động
    # Định dạng: rotating.proxy.com:port
    # Mỗi yêu cầu = IP mới
    proxy_url = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@rotating.proxycove.com:8080"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    results = []
    
    # Thực hiện 10 yêu cầu — mỗi yêu cầu với IP mới
    for i in range(10):
        try:
            response = requests.get(
                f'https://api.wildberries.ru/products/{i}',
                proxies=proxies,
                timeout=10
            )
            results.append({
                'product_id': i,
                'status': response.status_code,
                'data': response.json()
            })
        except Exception as e:
            results.append({
                'product_id': i,
                'error': str(e)
            })
    
    return {
        'statusCode': 200,
        'body': json.dumps(results)
    }

Xoay vòng thủ công từ nhóm proxy

Nếu bạn có một danh sách proxy, có thể thực hiện xoay vòng thủ công. Điều này hữu ích khi cần kiểm soát proxy nào được sử dụng cho mỗi yêu cầu:

import requests
import random
import json

def lambda_handler(event, context):
    # Danh sách proxy (có thể lưu trữ trong DynamoDB hoặc S3)
    proxy_pool = [
        {
            'host': 'proxy1.example.com',
            'port': '8080',
            'user': 'user1',
            'pass': 'pass1'
        },
        {
            'host': 'proxy2.example.com',
            'port': '8080',
            'user': 'user2',
            'pass': 'pass2'
        },
        {
            'host': 'proxy3.example.com',
            'port': '8080',
            'user': 'user3',
            'pass': 'pass3'
        }
    ]
    
    results = []
    
    for i in range(10):
        # Chọn một proxy ngẫu nhiên từ nhóm
        proxy = random.choice(proxy_pool)
        proxy_url = f"http://{proxy['user']}:{proxy['pass']}@{proxy['host']}:{proxy['port']}"
        
        proxies = {
            'http': proxy_url,
            'https': proxy_url
        }
        
        try:
            response = requests.get(
                f'https://api.example.com/item/{i}',
                proxies=proxies,
                timeout=10
            )
            results.append({
                'item': i,
                'proxy_used': proxy['host'],
                'status': response.status_code
            })
        except Exception as e:
            results.append({
                'item': i,
                'proxy_used': proxy['host'],
                'error': str(e)
            })
    
    return {
        'statusCode': 200,
        'body': json.dumps(results)
    }

Phiên sticky để giữ IP

Một số tác vụ yêu cầu giữ một IP trong suốt phiên (ví dụ: xác thực trên trang web). Các nhà cung cấp proxy cung cấp phiên sticky qua tham số trong URL:

import requests
import uuid

def lambda_handler(event, context):
    # Tạo một session_id duy nhất
    session_id = str(uuid.uuid4())
    
    # Proxy với phiên sticky (IP được giữ trong 10 phút)
    proxy_url = f"http://{os.environ['PROXY_USER']}-session-{session_id}:{os.environ['PROXY_PASS']}@sticky.proxycove.com:8080"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    # Tất cả các yêu cầu trong Lambda này sẽ được thực hiện với một IP
    # 1. Xác thực
    login_response = requests.post(
        'https://example.com/login',
        data={'user': 'test', 'pass': 'test'},
        proxies=proxies
    )
    
    # 2. Lấy dữ liệu (sử dụng cùng một IP)
    data_response = requests.get(
        'https://example.com/dashboard',
        proxies=proxies,
        cookies=login_response.cookies
    )
    
    return {
        'statusCode': 200,
        'body': data_response.text
    }

Lưu trữ thông tin xác thực proxy qua Biến Môi Trường

Không bao giờ lưu trữ thông tin xác thực proxy (tên đăng nhập, mật khẩu, máy chủ) trực tiếp trong mã của hàm Lambda. AWS cung cấp một số cách an toàn để lưu trữ dữ liệu nhạy cảm:

1. Biến Môi Trường (cách cơ bản)

Trong bảng điều khiển AWS Lambda → Cấu hình → Biến môi trường, thêm:

  • PROXY_HOST = proxy.example.com
  • PROXY_PORT = 8080
  • PROXY_USER = your_username
  • PROXY_PASS = your_password

AWS tự động mã hóa các Biến Môi Trường khi không hoạt động. Truy cập chúng trong mã:

# Python
import os
proxy_host = os.environ['PROXY_HOST']

// Node.js
const proxyHost = process.env.PROXY_HOST;

2. AWS Secrets Manager (được khuyến nghị cho production)

Để đảm bảo an toàn tối đa, hãy sử dụng AWS Secrets Manager — nó cung cấp xoay vòng bí mật tự động và kiểm soát truy cập chi tiết:

import boto3
import json
from botocore.exceptions import ClientError

def get_proxy_credentials():
    secret_name = "proxy-credentials"
    region_name = "us-east-1"
    
    session = boto3.session.Session()
    client = session.client(
        service_name='secretsmanager',
        region_name=region_name
    )
    
    try:
        get_secret_value_response = client.get_secret_value(
            SecretId=secret_name
        )
        secret = json.loads(get_secret_value_response['SecretString'])
        return secret
    except ClientError as e:
        print(f"Lỗi khi lấy bí mật: {e}")
        raise e

def lambda_handler(event, context):
    # Lấy thông tin xác thực từ Secrets Manager
    creds = get_proxy_credentials()
    
    proxy_url = f"http://{creds['user']}:{creds['password']}@{creds['host']}:{creds['port']}"
    
    # Sử dụng proxy
    # ...

Quan trọng: Đừng quên thêm quyền IAM cho hàm Lambda để truy cập Secrets Manager:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:us-east-1:123456789:secret:proxy-credentials-*"
    }
  ]
}

Các lỗi phổ biến và cách giải quyết

Khi làm việc với proxy trong Lambda, các nhà phát triển thường gặp phải những vấn đề tương tự. Chúng ta sẽ xem xét những vấn đề phổ biến nhất và cách khắc phục:

Lỗi: ProxyError / Connection timeout

Triệu chứng: requests.exceptions.ProxyError: HTTPConnectionPool(host='proxy.example.com', port=8080): Max retries exceeded

Nguyên nhân:

  • Thông tin xác thực proxy không chính xác (tên đăng nhập/mật khẩu)
  • Máy chủ proxy không khả dụng hoặc quá tải
  • Firewall chặn các kết nối xuất phát từ Lambda
  • Timeout quá ngắn

Cách giải quyết:

# 1. Kiểm tra thông tin xác thực
print(f"Sử dụng proxy: {proxy_host}:{proxy_port}")
print(f"Người dùng: {proxy_user}")

# 2. Tăng timeout
response = requests.get(url, proxies=proxies, timeout=30)

# 3. Thêm logic retry
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

session = requests.Session()
retry = Retry(
    total=3,
    backoff_factor=1,
    status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)

response = session.get(url, proxies=proxies, timeout=30)

Lỗi: SSL Certificate verification failed

Triệu chứng: SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]

Nguyên nhân: Một số proxy (đặc biệt là rẻ tiền) sử dụng chứng chỉ SSL tự ký.

Cách giải quyết (sử dụng cẩn thận!):

# Tắt kiểm tra SSL (chỉ dành cho thử nghiệm!)
response = requests.get(
    url,
    proxies=proxies,
    verify=False  # KHÔNG sử dụng trong production!
)

# Tốt hơn: chỉ định đường dẫn đến chứng chỉ CA
response = requests.get(
    url,
    proxies=proxies,
    verify='/path/to/ca-bundle.crt'
)

Quan trọng: Tắt kiểm tra SSL (verify=False) làm cho kết nối dễ bị tấn công man-in-the-middle. Chỉ sử dụng cho gỡ lỗi trong môi trường phát triển!

Lỗi: Lambda timeout (Nhiệm vụ đã hết thời gian sau X giây)

Triệu chứng: Hàm Lambda kết thúc với lỗi timeout, không chờ phản hồi từ proxy.

Nguyên nhân: Proxy chậm (đặc biệt là cư trú/di động) + số lượng yêu cầu lớn.

Cách giải quyết:

  • Tăng timeout của hàm Lambda: Cấu hình → Cấu hình chung → Timeout (tối đa 15 phút)
  • Giảm số lượng yêu cầu trong một lần thực hiện
  • Sử dụng các yêu cầu bất đồng bộ (asyncio trong Python, Promise.all trong Node.js)
  • Chuyển sang các proxy nhanh hơn cho các tác vụ không quan trọng
# Python: yêu cầu bất đồng bộ để tăng tốc
import asyncio
import aiohttp

async def fetch_url(session, url, proxy):
    async with session.get(url, proxy=proxy, timeout=10) as response:
        return await response.text()

async def lambda_handler_async(event, context):
    proxy_url = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@{os.environ['PROXY_HOST']}:{os.environ['PROXY_PORT']}"
    
    urls = [f'https://api.example.com/item/{i}' for i in range(50)]
    
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url, proxy_url) for url in urls]
        results = await asyncio.gather(*tasks)
    
    return {
        'statusCode': 200,
        'body': json.dumps({'count': len(results)})
    }

def lambda_handler(event, context):
    return asyncio.run(lambda_handler_async(event, context))

Lỗi: 407 Proxy Authentication Required

Triệu chứng: Lỗi HTTP 407 khi cố gắng sử dụng proxy.

Nguyên nhân: Định dạng truyền thông tin xác thực không chính xác hoặc proxy yêu cầu xác thực IP thay vì tên đăng nhập/mật khẩu.

Cách giải quyết:

# Kiểm tra định dạng URL proxy
# Đúng:
proxy_url = f"http://{user}:{password}@{host}:{port}"

# Sai (thiếu giao thức):
proxy_url = f"{user}:{password}@{host}:{port}"  # ❌

# Nếu proxy yêu cầu xác thực IP:
# 1. Tìm IP bên ngoài của Lambda (có thể thay đổi!)
# 2. Thêm IP này vào danh sách trắng của nhà cung cấp proxy
# 3. Sử dụng proxy mà không có user:pass

# Lấy IP bên ngoài của Lambda:
response = requests.get('https://api.ipify.org?format=json')
lambda_ip = response.json()['ip']
print(f"IP bên ngoài của Lambda: {lambda_ip}")

Tối ưu hóa hiệu suất Lambda với proxy

Việc sử dụng proxy sẽ thêm độ trễ cho mỗi yêu cầu. Dưới đây là những cách đã được kiểm chứng để giảm thiểu ảnh hưởng đến hiệu suất:

1. Kết nối pooling

Tái sử dụng kết nối TCP thay vì tạo mới cho mỗi yêu cầu:

# Python: sử dụng Session thay vì requests.get()
import requests

# Tạo session một lần (có thể đưa ra ngoài handler)
session = requests.Session()
session.proxies = {
    'http': proxy_url,
    'https': proxy_url
}

def lambda_handler(event, context):
    # Tất cả các yêu cầu sẽ tái sử dụng kết nối
    for i in range(100):
        response = session.get(f'https://api.example.com/item/{i}')
        # xử lý phản hồi...

2. Yêu cầu song song

Nếu cần thực hiện nhiều yêu cầu độc lập, hãy thực hiện chúng song song:

// Node.js: yêu cầu song song với Promise.all
const axios = require('axios');
const HttpsProxyAgent = require('https-proxy-agent');

const agent = new HttpsProxyAgent(proxyUrl);

exports.handler = async (event) => {
    const urls = Array.from({length: 50}, (_, i) => 
        `https://api.example.com/item/${i}`
    );
    
    // Tất cả các yêu cầu được thực hiện song song
    const promises = urls.map(url => 
        axios.get(url, { 
            httpsAgent: agent,
            timeout: 10000
        })
    );
    
    try {
        const results = await Promise.all(promises);
        return {
            statusCode: 200,
            body: JSON.stringify({
                count: results.length,
                data: results.map(r => r.data)
            })
        };
    } catch (error) {
        console.error('Lỗi:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

3. Lưu trữ kết quả

Nếu dữ liệu thay đổi ít, hãy lưu trữ kết quả trong DynamoDB hoặc S3:

import boto3
import json
import time

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('proxy-cache')

def get_cached_or_fetch(url, proxies, cache_ttl=3600):
    """Trả về dữ liệu từ cache hoặc thực hiện yêu cầu qua proxy"""
    
    # Kiểm tra cache
    try:
        response = table.get_item(Key={'url': url})
        if 'Item' in response:
            item = response['Item']
            if time.time() - item['timestamp'] < cache_ttl:
                print(f"Cache hit cho {url}")
                return item['data']
    except Exception as e:
        print(f"Lỗi cache: {e}")
    
    # Cache trống hoặc đã hết hạn — thực hiện yêu cầu
    print(f"Cache miss cho {url}, đang lấy...")
    response = requests.get(url, proxies=proxies, timeout=10)
    data = response.text
    
    # Lưu vào cache
    try:
        table.put_item(Item={
            'url': url,
            'data': data,
            'timestamp': int(time.time())
        })
    except Exception as e:
        print(f"Lỗi lưu cache: {e}")
    
    return data

4. Chọn loại proxy phù hợp

So sánh tốc độ của các loại proxy khác nhau trong điều kiện thực tế:

Loại proxy Độ trễ trung bình Yêu cầu/phút (Lambda 1GB RAM) Khuyến nghị
Trung tâm dữ liệu 50-200 ms 300-600 Phân tích API hàng loạt
Cư trú 300-800 ms 100-200 Các trang web bảo mật
Di động 500-1500 ms ...
```