[{"data":1,"prerenderedAt":20},["ShallowReactive",2],{"blog:post:vi:cach-cau-hinh-sticky-sessions-trong-ci-cd-de-tranh-bi-chan":3},{"slug":4,"lang":5,"title":6,"summary":7,"date":8,"tags":9,"tag_slugs":15,"thumbnail_url":16,"translations":17,"body":18,"asset_base":19},"cach-cau-hinh-sticky-sessions-trong-ci-cd-de-tranh-bi-chan","vi","Cách cấu hình sticky sessions trong CI/CD để tránh bị chặn","Hướng dẫn cấu hình sticky sessions trong pipeline CI/CD, sử dụng API RoProxy để duy trì IP cố định và giảm lỗi chặn.","2026-10-31",[10,11,12,13,14],"proxy","ci-cd","scraping","sticky-session","api",[10,11,12,13,14],"https://blog-api.ro-proxy.com/api/blog/posts/cach-cau-hinh-sticky-sessions-trong-ci-cd-de-tranh-bi-chan/thumbnail.svg?lang=vi",[5],"## Giới thiệu\n\nTrong môi trường CI/CD, các job scraping thường phải truy cập nhiều trang web, thực hiện collecte dữ liệu và cập nhật thông tin. Khi mỗi job sử dụng IP khác nhau, các hệ thống có thể phát hiện và chặn các request do thay đổi địa chỉ IP quá nhanh. Việc sử dụng session sticky – giữ IP cố định trong suốt quá trình thực hiện – giúp giảm thiểu khả năng bị chặn, duy trì tốc độ và tránh lãng phí tài khoản proxy.\n\n## Tại sao sticky sessions trong CI/CD?\n\n### 1. Tính nhất quán của dữ liệu\nKhi một job chạy nhiều request liên tiếp, nếu IP thay đổi giữa các request, các server có thể xem đây là comportment của bot và đưa ra các cơ chế chặn như CAPTCHA, rate‑limit hoặc trả về lỗi 429. Giữ IP cố định cho toàn bộ job giúp các server nhận diện patterns chính xác và giảm lỗi.\n\n### 2. Giảm chi phí tài khoản proxy\nVới session sticky, bạn không cần tạo mới session cho mỗi request, vì vậy số lượng rotate IP giảm đáng kể. Điều này kéo dài thời gian sử dụng của mỗi tài khoản và giảm chi phí khi thanh toán bằng bank transfer, crypto hoặc balance.\n\n### 3. Tích hợp dễ dàng vào pipeline\nTrong CI/CD, các bước build, test và deploy thường chạy trong môi trường cô lập. Khi bạn cấu hình một job để sử dụng một session sticky, toàn bộ pipeline sẽ giữ cùng một IP, tránh xung đột và simplifies log analysis.\n\n## Cách thiết lập session sticky\n\n### Bước 1: Lấy danh sách session hiện có\nBạn có thể gọi API GET để liệt kê các session hiện tại và chọn một session có trạng thái hoạt động, country mong muốn và mode rotation là sticky.\n\n```python\nimport requests\n\n# Thay thế các biến placeholder với thông tin thực tế\nAPI_KEY = 'YOUR_API_KEY'\nheaders = {'Authorization': f'Bearer {API_KEY}'}\nresp = requests.get('https://backend-api.ro-proxy.com/api/session', headers=headers)\nif resp.status_code == 200:\n    sessions = resp.json()\n    # Chọn session có mode sticky và country mong muốn\n    for s in sessions:\n        if s['mode'] == 'sticky' and s['country'] == 'VN':\n            SESSION_ID = s['id']\n            break\nelse:\n    raise Exception('Không thể lấy danh sách session')\n```\n\n### Bước 2: Cấu hình proxy trong ứng dụng của bạn\nĐối với hầu hết các thư viện HTTP (requests, aiohttp, httpie), bạn chỉ cần chỉ định proxy dạng:\n\n```python\nproxy_url = f'http://{USERNAME}:{PASSWORD}@{GATEWAY_HOST}:{HTTP_PORT}'\nproxies = {\n    'http': proxy_url,\n    'https': proxy_url\n}\n```\n\nTrong CI/CD, các biến môi trường thường được truyền vào container, ví dụ:\n- GATEWAY_HOST\n- HTTP_PORT\n- USERNAME\n- PASSWORD\n- API_KEY\n\nVới RoProxy, mỗi session có một combination duy nhất của địa chỉ gateway, cổng HTTP và thông tin đăng nhập, vì vậy việc thay đổi cổng SOCKS5 không ảnh hưởng đến việc sử dụng session sticky qua HTTP/HTTPS.\n\n### Bước 3: Sử dụng session ID trong request\nĐể duy trì session sticky, bạn có thể gắn session ID vào một header tùy chỉnh, ví dụ X‑Session‑ID. Nhiều API của RoProxy không bắt buộc việc này, nhưng việc truyền session ID giúp các hệ thống phía sau (ví dụ, ứng dụng web) hiểu được request đang thuộc cùng một session.\n\n```python\ncustom_headers = {\n    'X-Session-ID': SESSION_ID,\n    'Authorization': f'Bearer {API_KEY}'\n}\n```\n\nSau đó, thực hiện request như bình thường:\n\n```python\nimport requests\nimport time\n\ndef fetch_with_retry(url, max_retries=3, base_delay=1.0):\n    for attempt in range(max_retries):\n        try:\n            response = requests.get(url, proxies=proxies, headers=custom_headers, timeout=30)\n            response.raise_for_status()\n            return response\n        except requests.exceptions.RequestException as e:\n            if attempt \u003C max_retries - 1:\n                delay = base_delay * (2 ** attempt)\n                print(f'Attempt {attempt+1} failed: {e}. Retrying in {delay:.1f}s...')\n                time.sleep(delay)\n            else:\n                raise\n```\n\n### Kiểm tra trạng thái session trước khi thực hiện\n\nTrong môi trường CI/CD, việc xảy ra lỗi mạng hoặc bị chặn có thể làm session mất hiệu lực. Để tránh thực hiện request với session đã hết hạn, bạn nên kiểm tra trạng thái session trước khi gửi request chính.\n\n```python\ndef check_session_alive(session_id):\n    headers = {'Authorization': f'Bearer {API_KEY}'}\n    resp = requests.get(\n        f'https://backend-api.ro-proxy.com/api/session/{session_id}',\n        headers=headers\n    )\n    if resp.status_code == 200:\n        print('Session vẫn hoạt động')\n        return True\n    elif resp.status_code == 404:\n        print('Session không tồn tại')\n        return False\n    else:\n        print(f'Lỗi trả về: {resp.status_code}')\n        return False\n```\n\nBạn có thể gọi hàm này ở đầu mỗi job hoặc khi phát hiện lỗi 502/504 đầu tiên. Nếu session không còn alive, hãy thực hiện rotate IP ngay lập tức.\n\n## Xử lý lỗi và xoay IP\n\n### Phát hiện lỗi 502, 504 hoặc timeout\nKhi request trả về mã 502 (Bad Gateway) hoặc 504 (Gateway Timeout), nghĩa là gateway không thể truyền request tới máy chủ đích hoặc không nhận được phản hồi trong thời gian quy định. Hai lỗi này thường do:\n\n- Kết nối TCP bị gián đoạn giữa client và gateway.\n- Thời gian timeout quá ngắn khiến server đích không kịp trả lời.\n- Xử lý rotation không hoàn thành đúng cách.\n\n### Kỹ thuật retry với backoff\nĐây là phương pháp cơ bản nhưng rất hiệu quả. Khi gặp lỗi, chờ một khoảng thời gian tăng dần (mở rộng nhân 2) trước khi thử lại. Điều này giảm thiểu hiện tượng retry quá mức và tránh gây tải lên gateway.\n\n```python\ndef fetch_with_smart_retry(url, session_id, max_retries=3, base_delay=1.0):\n    for attempt in range(max_retries):\n        try:\n            # Kiểm tra session trước khi gửi\n            if not check_session_alive(session_id):\n                rotate_ip(session_id)\n                # Đợi một chút để session mới được kích hoạt\n                time.sleep(2)\n            response = requests.get(\n                url,\n                proxies=proxies,\n                headers=custom_headers,\n                timeout=30\n            )\n            response.raise_for_status()\n            return response\n        except requests.exceptions.RequestException as e:\n            if attempt \u003C max_retries - 1:\n                delay = base_delay * (2 ** attempt)\n                print(f'Attempt {attempt+1} failed: {e}. Retrying in {delay:.1f}s...')\n                time.sleep(delay)\n            else:\n                raise\n```\n\n### Xoay IP ngay khi phát hiện lỗi\nNếu bạn phát hiện rằng session không còn alive (ví dụ trả về 404 hoặc 502), việc xoay IP ngay lập tức thường giải quyết vấn đề.\n\n```python\ndef rotate_ip_on_error(session_id):\n    headers = {'Authorization': f'Bearer {API_KEY}'}\n    resp = requests.post(\n        f'https://backend-api.ro-proxy.com/api/session/{session_id}/rotate',\n        headers=headers\n    )\n    if resp.status_code == 200:\n        print('IP đã được xoay mới')\n        return True\n    else:\n        print(f'Xoay IP thất bại: {resp.status_code}')\n        return False\n```\n\nBạn có thể gọi hàm này trong khối except của fetch_with_smart_retry, hoặc khi nhận được mã 502/504 từ response.\n\n## Áp dụng trong pipeline CI/CD\n\n### 1. Đặt biến môi trường trong file .gitlab-ci.yml, GitHub Actions hoặc Jenkins\nVí dụ trong GitHub Actions:\n\n```yaml\njobs:\n  scrape:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v3\n      - name: Set proxy env\n        run: |\n          echo \"GATEWAY_HOST=gateway.example.com\" >> $GITHUB_ENV\n          echo \"HTTP_PORT=8080\" >> $GITHUB_ENV\n          echo \"USERNAME=abc123\" >> $GITHUB_ENV\n          echo \"PASSWORD=xyz789\" >> $GITHUB_ENV\n          echo \"API_KEY=your_key\" >> $GITHUB_ENV\n```\n\n### 2. Khởi tạo session sticky trong bước setup\nBạn có thể thêm một bước Python để lấy session ID và lưu vào file cache.\n\n```yaml\n      - name: Get session ID\n        run: |\n          python - \u003C\u003CEOF\nimport os, json, requests, time\nAPI_KEY = os.getenv('API_KEY')\nheaders = {'Authorization': f'Bearer {API_KEY}'}\n# Lấy danh sách session\nresp = requests.get('https://backend-api.ro-proxy.com/api/session', headers=headers)\nsessions = resp.json()\nfor s in sessions:\n    if s['mode'] == 'sticky' and s['country'] == 'VN':\n        with open('session_id.txt', 'w') as f:\n            f.write(s['id'])\n        print('Session ID saved')\nEOF\n```\n\n### 3. Sử dụng session ID trong script scraping\nTrong script Python, đọc session ID từ file và dùng trong các request.\n\n```python\nimport os, requests, time\n\n# Đọc session ID\nwith open('session_id.txt') as f:\n    SESSION_ID = f.read().strip()\n\n# Cấu hình proxy và header tùy chỉnh\nGATEWAY_HOST = os.getenv('GATEWAY_HOST')\nHTTP_PORT = int(os.getenv('HTTP_PORT'))\nUSERNAME = os.getenv('USERNAME')\nPASSWORD = os.getenv('PASSWORD')\nAPI_KEY = os.getenv('API_KEY')\nproxy_url = f'http://{USERNAME}:{PASSWORD}@{GATEWAY_HOST}:{HTTP_PORT}'\nproxies = {'http': proxy_url, 'https': proxy_url}\ncustom_headers = {'X-Session-ID': SESSION_ID, 'Authorization': f'Bearer {API_KEY}'}\n\n# Thực hiện request với retry\nresponse = fetch_with_smart_retry('https://example.com', SESSION_ID)\nprint('Status code:', response.status_code)\n```\n\n### 4. Kiểm tra và xử lý lỗi trong pipeline\nNếu script trả về mã không thành công (exit code != 0), pipeline sẽ dừng và thông báo lỗi. Bạn có thể thêm bước cuối cùng để log session ID và trạng thái, giúp team nhanh chóng định vị nguyên nhân.\n\n## Kết luận\n\nViệc cấu hình sticky sessions trong CI/CD không chỉ giúp duy trì IP cố định mà còn nâng cao độ tin cậy và giảm chi phí cho các job scraping. Các bước chính bao gồm: lấy danh sách session, chọn session có mode sticky, cấu hình proxy với các placeholder, gắn session ID vào header, và áp dụng retry với backoff cùng cơ chế rotate IP khi session không còn alive. Khi áp dụng đúng cách, pipeline CI/CD sẽ hoạt động ổn định, giảm lỗi chặn và tối ưu hoá tài nguyên proxy.\n\nVới RoProxy, việc quản lý session sticky trở nên ổn định và dễ bảo trì.\n","https://blog-api.ro-proxy.com/api/blog/posts/cach-cau-hinh-sticky-sessions-trong-ci-cd-de-tranh-bi-chan/assets",1793430114959]