블로그로 돌아가기

AWS Lambda에서 파싱 및 API를 위한 프록시 설정 방법: 예제와 함께하는 완벽 가이드

AWS Lambda에서 파싱, API 요청 및 자동화를 위한 프록시 설정 단계별 안내. Python 및 Node.js 코드 예제, 일반적인 문제 해결.

📅2026년 2월 18일
```html

AWS Lambda는 서버를 관리하지 않고 코드를 실행할 수 있는 서버리스 플랫폼입니다. 그러나 웹 스크래핑, 마켓플레이스 API 작업 또는 작업 자동화를 할 때 종종 발생하는 문제는 Lambda 함수가 AWS의 IP 주소를 사용하여 쉽게 감지되고 차단된다는 것입니다. 이 가이드에서는 Lambda에 프록시를 통합하고 IP 회전을 설정하며 일반적인 오류를 피하는 방법을 설명합니다.

이 기사는 AWS Lambda를 통해 작업을 자동화하는 개발자를 대상으로 합니다: 보호된 웹사이트에서 데이터 스크래핑, 경쟁자의 가격 모니터링, 소셜 미디어 또는 마켓플레이스 API 작업. 읽은 후 바로 사용할 수 있는 Python 및 Node.js의 코드 예제를 제공합니다.

AWS Lambda에서 프록시가 필요한 이유

AWS Lambda는 기본적으로 Amazon Web Services의 IP 주소를 사용합니다. 이러한 주소는 공개 목록에 있으며 봇 방지 시스템에 의해 쉽게 식별됩니다. 프록시가 필요해지는 주요 시나리오는 다음과 같습니다:

실제 사례: 개발자가 Wildberries에서 가격 모니터링을 위해 Lambda를 15분마다 설정했습니다. 2일 후 마켓플레이스는 403 Forbidden 오류를 반환하기 시작했습니다 — AWS IP가 블랙리스트에 올라갔습니다. 주거용 프록시를 연결한 후 스크래핑은 6개월 동안 안정적으로 작동하고 있습니다.

Lambda에서 프록시 사용의 주요 이유:

  • 보호된 웹사이트 스크래핑: 많은 웹사이트가 AWS 데이터 센터의 IP에서 오는 요청을 차단합니다. 프록시는 Lambda를 일반 사용자로 위장할 수 있게 해줍니다.
  • 지리적 제한: 특정 국가에서만 접근 가능한 웹사이트에서 데이터를 얻어야 할 경우 (예: Ozon의 지역 가격), 필요한 지리적 위치의 프록시가 문제를 해결합니다.
  • 요청 제한 우회: 많은 서비스의 API는 하나의 IP에서 오는 요청 수를 제한합니다. 프록시 회전은 부하를 분산시킬 수 있습니다.
  • A/B 광고 테스트: 경쟁 분석을 위해 다양한 지역에서 광고의 표시를 확인합니다.
  • 마켓플레이스 모니터링: Wildberries, Ozon, Avito에서 상품의 위치와 경쟁자의 가격을 차단 없이 추적합니다.

Lambda 함수는 종종 일정에 따라 실행되거나 (CloudWatch Events를 통해) 트리거되므로 자동화에 이상적인 도구입니다. 그러나 프록시 없이 이러한 작업은 목표 리소스의 차단에 빠르게 부딪힙니다.

Lambda에 적합한 프록시 유형 선택하기

프록시 유형의 선택은 Lambda 함수가 해결하려는 작업에 따라 달라집니다. 서버리스 아키텍처에서의 세 가지 주요 유형과 그 사용을 살펴보겠습니다:

프록시 유형 속도 익명성 Lambda에 대한 최적의 시나리오
데이터 센터 프록시 매우 높음 (50-200 ms) 중간 엄격한 보호가 없는 API 스크래핑, 대규모 웹사이트 가용성 검사, SEO 모니터링
주거용 프록시 중간 (300-800 ms) 매우 높음 보호된 웹사이트 스크래핑 (마켓플레이스, 소셜 미디어), Cloudflare 우회, Instagram/Facebook API 작업
모바일 프록시 중간 (400-1000 ms) 최대 모바일 API 작업 (TikTok, Instagram), 모바일 광고 테스트, 가장 엄격한 보호 우회

선택에 대한 권장 사항:

  • Wildberries, Ozon, Avito 스크래핑: 러시아 지리적 위치의 주거용 프록시를 사용하세요. 이 플랫폼은 데이터 센터의 IP를 적극적으로 차단합니다.
  • 엄격한 보호가 없는 API 모니터링: 데이터 센터 프록시로 충분하며, 더 저렴하고 빠릅니다.
  • Instagram, Facebook, TikTok API 작업: 모바일 또는 주거용 프록시만 사용하세요 — 이 플랫폼은 데이터 센터를 감지하고 차단합니다.
  • Cloudflare, PerimeterX 우회: 회전하는 주거용 프록시, 가능하면 sticky sessions (5-30분 동안 IP 유지) 사용하세요.

중요: Lambda 함수는 실행 시간 제한이 있습니다 (최대 15분). 느린 프록시 (주거용/모바일)를 사용할 경우 지연 시간을 고려하세요 — 프록시를 통한 요청이 2초 걸린다면 15분 동안 최대 ~450개의 요청을 할 수 있습니다.

Python에서 Lambda에 프록시 설정하기 (requests, urllib3)

Python은 Lambda 함수에 가장 인기 있는 언어로, 특히 스크래핑 및 자동화 작업에 적합합니다. 90%의 경우에 사용되는 requests 라이브러리를 사용하여 프록시 설정을 살펴보겠습니다.

HTTP 프록시 기본 설정

프록시를 연결하는 가장 간단한 방법은 proxies 매개변수를 requests.get() 메서드에 전달하는 것입니다:

import requests
import os

def lambda_handler(event, context):
    # 환경 변수에서 프록시 자격 증명 가져오기
    proxy_host = os.environ['PROXY_HOST']  # 예: proxy.example.com
    proxy_port = os.environ['PROXY_PORT']  # 예: 8080
    proxy_user = os.environ['PROXY_USER']
    proxy_pass = os.environ['PROXY_PASS']
    
    # 인증이 포함된 프록시 URL 생성
    proxy_url = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    try:
        # 프록시를 통해 요청 수행
        response = requests.get(
            'https://api.example.com/data',
            proxies=proxies,
            timeout=10  # 중요! 타임아웃 설정
        )
        
        return {
            'statusCode': 200,
            'body': response.text
        }
    
    except requests.exceptions.ProxyError as e:
        print(f"프록시 오류: {e}")
        return {
            'statusCode': 500,
            'body': '프록시 연결 실패'
        }
    
    except requests.exceptions.Timeout as e:
        print(f"타임아웃 오류: {e}")
        return {
            'statusCode': 504,
            'body': '요청 타임아웃'
        }

이 코드의 주요 사항:

  • 환경 변수: 프록시 자격 증명을 코드에 직접 저장하지 마세요! Lambda 설정에서 환경 변수를 사용하세요.
  • 타임아웃: 반드시 타임아웃을 설정하세요 (10-30초). 타임아웃이 없으면 Lambda가 최대 실행 시간까지 멈출 수 있습니다.
  • 오류 처리: 프록시가 사용할 수 없거나 느릴 수 있으므로 항상 ProxyErrorTimeout 예외를 처리하세요.
  • HTTP 및 HTTPS: 두 프로토콜 모두 proxies 사전에서 지정하세요, HTTPS만 사용하는 경우에도요.

SOCKS5 프록시 설정

SOCKS5 프록시는 더 높은 수준의 익명성을 제공하며 TCP 레벨에서 작동하여 일부 보안 시스템에 감지되지 않습니다. requests에서 SOCKS5를 사용하려면 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_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
        )
        
        # 데이터 파싱
        return {
            'statusCode': 200,
            'body': response.text
        }
    
    except Exception as e:
        print(f"오류: {e}")
        return {
            'statusCode': 500,
            'body': str(e)
        }

Lambda 배포 시 중요: SOCKS5를 사용할 경우 requirements.txt에 추가하세요:

requests[socks]
PySocks

프록시를 통한 IP 확인

주요 로직을 실행하기 전에 프록시가 작동하고 필요한 IP를 반환하는지 확인하는 것이 유용합니다:

def check_proxy_ip(proxies):
    """프록시를 통해 외부 세계가 보는 IP를 확인합니다"""
    try:
        response = requests.get(
            'https://api.ipify.org?format=json',
            proxies=proxies,
            timeout=10
        )
        ip_data = response.json()
        print(f"프록시를 통한 현재 IP: {ip_data['ip']}")
        return ip_data['ip']
    except Exception as e:
        print(f"프록시 확인 실패: {e}")
        return None

def lambda_handler(event, context):
    # ... 프록시 설정 ...
    
    # 주요 작업 전 IP 확인
    current_ip = check_proxy_ip(proxies)
    if not current_ip:
        return {
            'statusCode': 500,
            'body': '프록시 확인 실패'
        }
    
    # 주요 스크래핑 로직
    # ...

Node.js에서 Lambda에 프록시 설정하기 (axios, got)

Node.js는 Lambda 함수에 대한 두 번째로 인기 있는 언어로, API 작업 시 높은 성능이 필요할 때 특히 유용합니다. axiosgot 라이브러리를 사용하여 프록시 설정을 살펴보겠습니다.

axios를 사용한 설정

Axios는 Node.js에서 가장 인기 있는 HTTP 라이브러리입니다. 프록시 작업을 위해서는 추가 패키지 https-proxy-agent가 필요합니다:

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

exports.handler = async (event) => {
    // 환경 변수에서 자격 증명 가져오기
    const proxyHost = process.env.PROXY_HOST;
    const proxyPort = process.env.PROXY_PORT;
    const proxyUser = process.env.PROXY_USER;
    const proxyPass = process.env.PROXY_PASS;
    
    // 프록시 URL 생성
    const proxyUrl = `http://${proxyUser}:${proxyPass}@${proxyHost}:${proxyPort}`;
    
    // 프록시를 위한 에이전트 생성
    const agent = new HttpsProxyAgent(proxyUrl);
    
    try {
        const response = await axios.get('https://api.example.com/data', {
            httpsAgent: agent,
            timeout: 10000  // 10초
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify(response.data)
        };
    } catch (error) {
        console.error('요청 실패:', error.message);
        
        return {
            statusCode: 500,
            body: JSON.stringify({
                error: error.message
            })
        };
    }
};

종속성 설치: package.json에 추가하세요:

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

axios를 사용한 SOCKS5 설정

SOCKS5 프록시를 사용하려면 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('오류:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

대안: got 라이브러리

Got는 프록시를 네이티브로 지원하는 현대적인 HTTP 라이브러리입니다 (별도의 에이전트가 필요하지 않음):

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('오류:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

Lambda에서 프록시 회전: IP를 자동으로 변경하는 방법

프록시 회전은 차단 없이 많은 요청을 해야 하는 작업에 매우 중요합니다. 두 가지 주요 접근 방식이 있습니다: 자동 회전이 가능한 프록시 서비스를 사용하는 것과 프록시 풀을 수동으로 관리하는 것입니다.

공급자를 통한 자동 회전

대부분의 주거용 프록시 공급자 (ProxyCove 포함)는 자동 회전이 가능한 엔드포인트를 제공합니다 — 각 요청 또는 N분마다 IP가 자동으로 변경됩니다:

import requests
import os

def lambda_handler(event, context):
    # 자동 회전 프록시
    # 형식: rotating.proxy.com:port
    # 각 요청 = 새로운 IP
    proxy_url = f"http://{os.environ['PROXY_USER']}:{os.environ['PROXY_PASS']}@rotating.proxycove.com:8080"
    
    proxies = {
        'http': proxy_url,
        'https': proxy_url
    }
    
    results = []
    
    # 10개의 요청 수행 — 각 요청마다 새로운 IP
    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)
    }

프록시 풀에서 수동 회전

프록시 목록이 있는 경우 수동으로 회전을 구현할 수 있습니다. 이는 각 요청에 대해 어떤 프록시가 사용되는지 제어할 수 있을 때 유용합니다:

import requests
import random
import json

def lambda_handler(event, context):
    # 프록시 목록 (DynamoDB 또는 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):
        # 풀에서 무작위 프록시 선택
        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)
    }

IP 유지 위한 Sticky sessions

일부 작업은 세션 동안 하나의 IP를 유지해야 합니다 (예: 웹사이트 로그인). 프록시 공급자는 URL 매개변수를 통해 sticky sessions를 제공합니다:

import requests
import uuid

def lambda_handler(event, context):
    # 고유한 session_id 생성
    session_id = str(uuid.uuid4())
    
    # sticky session을 가진 프록시 (IP는 10분 동안 유지됨)
    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
    }
    
    # 이 Lambda의 모든 요청은 동일한 IP로 수행됩니다
    # 1. 로그인
    login_response = requests.post(
        'https://example.com/login',
        data={'user': 'test', 'pass': 'test'},
        proxies=proxies
    )
    
    # 2. 데이터 가져오기 (동일한 IP 사용)
    data_response = requests.get(
        'https://example.com/dashboard',
        proxies=proxies,
        cookies=login_response.cookies
    )
    
    return {
        'statusCode': 200,
        'body': data_response.text
    }

환경 변수를 통한 프록시 자격 증명 저장

프록시 자격 증명 (로그인, 비밀번호, 호스트)를 Lambda 함수 코드에 직접 저장하지 마세요. AWS는 기밀 데이터를 저장하기 위한 여러 안전한 방법을 제공합니다:

1. 환경 변수 (기본 방법)

AWS Lambda 콘솔 → 구성 → 환경 변수에서 추가하세요:

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

AWS는 자동으로 환경 변수를 암호화합니다. 코드에서 접근하는 방법:

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

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

2. AWS Secrets Manager (프로덕션에 권장)

최대 보안을 위해 AWS Secrets Manager를 사용하세요 — 자동 비밀 회전 및 세부적인 접근 제어를 제공합니다:

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"비밀 가져오기 오류: {e}")
        raise e

def lambda_handler(event, context):
    # Secrets Manager에서 자격 증명 가져오기
    creds = get_proxy_credentials()
    
    proxy_url = f"http://{creds['user']}:{creds['password']}@{creds['host']}:{creds['port']}"
    
    # 프록시 사용
    # ...

중요: Lambda 함수가 Secrets Manager에 접근할 수 있도록 IAM 권한을 추가하는 것을 잊지 마세요:

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

일반적인 오류 및 해결 방법

Lambda에서 프록시를 사용할 때 개발자들은 종종 동일한 문제에 직면합니다. 가장 일반적인 문제와 해결 방법을 살펴보겠습니다:

오류: ProxyError / Connection timeout

증상: requests.exceptions.ProxyError: HTTPConnectionPool(host='proxy.example.com', port=8080): 최대 재시도 초과

원인:

  • 잘못된 프록시 자격 증명 (로그인/비밀번호)
  • 프록시 서버가 사용 불가능하거나 과부하 상태
  • 방화벽이 Lambda의 아웃바운드 연결을 차단함
  • 너무 짧은 타임아웃

해결 방법:

# 1. 자격 증명 확인
print(f"사용 중인 프록시: {proxy_host}:{proxy_port}")
print(f"사용자: {proxy_user}")

# 2. 타임아웃 늘리기
response = requests.get(url, proxies=proxies, timeout=30)

# 3. 재시도 로직 추가
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)

오류: SSL 인증서 검증 실패

증상: SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]

원인: 일부 프록시 (특히 저렴한 것)는 자체 서명된 SSL 인증서를 사용합니다.

해결 방법 (주의해서 사용하세요!):

# SSL 검증 비활성화 (테스트 용도!)
response = requests.get(
    url,
    proxies=proxies,
    verify=False  # 프로덕션에서는 사용하지 마세요!
)

# 더 나은 방법: CA 인증서 경로 지정
response = requests.get(
    url,
    proxies=proxies,
    verify='/path/to/ca-bundle.crt'
)

중요: SSL 검증 비활성화 (verify=False)는 man-in-the-middle 공격에 취약하게 만듭니다. 개발 환경에서만 디버깅 용도로 사용하세요!

오류: Lambda 타임아웃 (작업이 X초 후에 타임아웃됨)

증상: Lambda 함수가 프록시의 응답을 기다리지 않고 타임아웃 오류로 종료됩니다.

원인: 느린 프록시 (특히 주거용/모바일) + 많은 요청 수.

해결 방법:

  • Lambda 함수의 타임아웃 늘리기: 구성 → 일반 구성 → 타임아웃 (최대 15분)
  • 한 번의 실행에서 요청 수 줄이기
  • 비동기 요청 사용 (Python의 asyncio, Node.js의 Promise.all)
  • 중요하지 않은 작업에는 더 빠른 프록시로 전환하기
# Python: 속도를 높이기 위한 비동기 요청
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))

오류: 407 프록시 인증 필요

증상: 프록시를 사용하려고 할 때 HTTP 407 오류가 발생합니다.

원인: 자격 증명을 전달하는 형식이 잘못되었거나 프록시가 로그인/비밀번호 대신 IP 인증을 요구합니다.

해결 방법:

# 프록시 URL 형식 확인
# 올바른 방법:
proxy_url = f"http://{user}:{password}@{host}:{port}"

# 잘못된 방법 (프로토콜이 누락됨):
proxy_url = f"{user}:{password}@{host}:{port}"  # ❌

# 프록시가 IP 인증을 요구하는 경우:
# 1. Lambda의 외부 IP를 확인하세요 (변경될 수 있음!)
# 2. 이 IP를 프록시 공급자의 화이트리스트에 추가하세요
# 3. 사용자:비밀번호 없이 프록시를 사용하세요

# Lambda의 외부 IP 가져오기:
response = requests.get('https://api.ipify.org?format=json')
lambda_ip = response.json()['ip']
print(f"Lambda 외부 IP: {lambda_ip}")

프록시를 사용한 Lambda 성능 최적화

프록시 사용은 각 요청에 지연을 추가합니다. 성능에 미치는 영향을 최소화하는 검증된 방법은 다음과 같습니다:

1. 연결 풀링

각 요청을 위해 새로운 TCP 연결을 생성하는 대신 재사용하세요:

# Python: requests.get() 대신 Session 사용
import requests

# 세션을 한 번 생성합니다 (핸들러 외부로 이동 가능)
session = requests.Session()
session.proxies = {
    'http': proxy_url,
    'https': proxy_url
}

def lambda_handler(event, context):
    # 모든 요청이 연결을 재사용합니다
    for i in range(100):
        response = session.get(f'https://api.example.com/item/{i}')
        # 응답 처리...

2. 병렬 요청

많은 독립적인 요청을 해야 할 경우 병렬로 실행하세요:

// Node.js: 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}`
    );
    
    // 모든 요청이 병렬로 수행됩니다
    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('오류:', error.message);
        return {
            statusCode: 500,
            body: JSON.stringify({ error: error.message })
        };
    }
};

3. 결과 캐싱

데이터가 드물게 변경되는 경우 DynamoDB 또는 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):
    """캐시에서 데이터를 반환하거나 프록시를 통해 요청합니다"""
    
    # 캐시 확인
    try:
        response = table.get_item(Key={'url': url})
        if 'Item' in response:
            item = response['Item']
            if time.time() - item['timestamp'] < cache_ttl:
                print(f"{url}에 대한 캐시 적중")
                return item['data']
    except Exception as e:
        print(f"캐시 오류: {e}")
    
    # 캐시가 비어 있거나 만료됨 — 요청 수행
    print(f"{url}에 대한 캐시 미스, 가져오는 중...")
    response = requests.get(url, proxies=proxies, timeout=10)
    data = response.text
    
    # 캐시에 저장
    try:
        table.put_item(Item={
            'url': url,
            'data': data,
            'timestamp': int(time.time())
        })
    except Exception as e:
        print(f"캐시 저장 오류: {e}")
    
    return data

4. 올바른 프록시 유형 선택

실제 조건에서 다양한 프록시 유형의 속도를 비교합니다:

프록시 유형 평균 지연 요청/분 (Lambda 1GB RAM) 추천
데이터 센터 50-200 ms 300-600 대규모 API 스크래핑
주거용 300-800 ms 100-200 보호된 웹사이트
모바일 500-1500 ms 50-100 모바일 API 작업

결론: Lambda에서 프록시를 사용하면 많은 이점을 얻을 수 있지만, 올바른 설정과 관리가 필요합니다. 이 가이드를 통해 AWS Lambda에서 프록시를 효과적으로 설정하고 사용하는 방법을 배웠기를 바랍니다.

```