# 粘性会话和 IP 轮换：会话 ID、TTL 和连接重用

> 住宅代理网关上的粘性会话和 IP 轮换：会话 ID，TTL，不同库的连接重用，和会话池。

- URL: https://crawlrelay.com/zh/docs/sessions/
- 最后更新: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

轮换按连接发生，粘性按会话 ID 发生。了解您的库如何重用连接后，您可以精准控制 IP 何时更换。

**快速回答 — 住宅代理粘性会话和 IP 轮换是如何工作的？**

在 **CrawlRelay** 上，未带会话 ID 的用户名每次新 TCP 连接都会从池中获取一个 IP，通常不同，`-session-<id>-ttl-<minutes>` 会为该 ID 保持一个 IP，持续 最长支持 30 分钟持续时长，但 IP 也可提前更换。轮换依据连接，而非 HTTP 请求，因此保持连接状态决定您的 IP 何时真正切换。住宅代理流量费用为 US$0.50/GB，起购 50 GB。支持加密货币支付，且无需 KYC。

## 会话规则一览

| 属性 | 值 |
| --- | --- |
| 轮换单位 | 每个新 TCP 连接从池中获取一个通常不同的 IP |
| 粘性会话 | 用户名后附加 `-session-<id>-ttl-<minutes>` |
| 会话长度 | 最长支持 30 分钟持续时长 |
| 会话 ID | 1–32 个字母或数字；每条流一个 ID |
| 什么情况会提前结束会话 | 背后的住宅设备离线 |
| 共享 ID | 发送相同 ID 的客户端共享相同出口 |
| 费用 | 免费：会话和轮换已包含在每 GB 价格中 |

## 当我发送会话 ID 到网关时会发生什么？

网关在每次新连接时读取用户名。没有会话部分时，它会为该连接选择符合你目标的住宅代理出口。带有会话部分时，会在你设置的 TTL 时间内为该 ID 保持相同出口。

粘性 IP 是真实的住宅代理连接，因此它可能会在 TTL 结束前消失：设备关机、断开 Wi-Fi 或更换网络。长时间流量需要通过检查出口 IP 并从检查点重启来保证不中断，避免整个任务失败。

## 每个库如何复用连接？

如果库保持连接活跃，所有请求共用同一出口。你可以利用此特性实现不同的行为。

| 库 | 默认 | 每次请求使用新 IP | 一个流量使用一个 IP |
| --- | --- | --- | --- |
| Python requests | `Session` 保持连接活跃 | 请求头 `Connection: close`，或每次请求新建 `Session` | 一个带会话 ID 的 `Session` |
| httpx | 客户端池化连接 | `httpx.Limits(max_keepalive_connections=0)` | 每个会话 ID 一个客户端 |
| aiohttp | `TCPConnector` 池化连接 | `TCPConnector(force_close=True)` | 代理 URL 用户名中的会话 ID |
| Scrapy | 按代理凭据和主机池化 | 使用我们的 [middleware](https://crawlrelay.com/zh/docs/scrapy/) 的 `meta={"proxy_session": "new"}` | 流量指定一个固定 `proxy_session` |
| Playwright / Puppeteer | Chrome 按上下文池化 | 每页创建新上下文 | 每个会话 ID 一个上下文 |
| Node.js undici, axios, got | Agents 保持套接字活跃 | 每次请求新建代理或关闭保持连接 | 每个会话 ID 一个代理 |
| curl | 每个命令一个连接 | 已是如此 | 每个命令使用相同会话 ID |

## 哪种会话策略适合哪类爬取任务？

| 任务 | 策略 | 建议 TTL |
| --- | --- | --- |
| 独立产品、文章或列表页 | 轮换：无会话 ID | — |
| 分页其下一页依赖于 cookie 或游标 | 每个列表一个粘性会话 | 10–30 分钟 |
| 先搜索，再结果，最后详情页 | 每次搜索一个粘性会话 | 10–20 分钟 |
| 无头浏览器渲染同一网站的多个页面 | 每个浏览器上下文一个粘性会话 | 上下文生命周期，最长 30 分钟 |
| 检查多个城市页面展示内容 | 每个城市检查一次短会话 | 5 分钟 |
| 每小时重新检查同一页面 | 轮换 | — |

## 如何在 Python 中管理粘性会话池？

一个小池会在几个稳定出口之间分担负载，并在请求次数达到设定值或出现502或503错误等出口失效信号后退休此出口。注意它**不做**的事：不会为绕过 403 或 429 错误而切换 IP。因为这些错误意味着网站要求你降低访问频率，所以池子会将这些错误传递给你的代码。

*Python：粘性会话池*

```python
import random
import uuid

import requests

GATEWAY = "gw.crawlrelay.com:7777"
BASE_USER, PASSWORD = "USERNAME-country-us", "PASSWORD"


class SlowDown(Exception):
    """The target asked us to slow down (403 or 429): back off, do not rotate."""


class StickySession:
    def __init__(self, ttl=15, max_requests=50):
        self.id = uuid.uuid4().hex[:10]
        self.max_requests, self.used = max_requests, 0
        user = "%s-session-%s-ttl-%d" % (BASE_USER, self.id, ttl)
        proxy = "http://%s:%s@%s" % (user, PASSWORD, GATEWAY)
        self.http = requests.Session()
        self.http.proxies = {"http": proxy, "https": proxy}


class SessionPool:
    EXIT_PROBLEMS = {502, 503, 504}

    def __init__(self, size=5, **options):
        self.options = options
        self.sessions = [StickySession(**options) for _ in range(size)]

    def _replace(self, i):
        self.sessions[i].http.close()
        self.sessions[i] = StickySession(**self.options)

    def get(self, url, **kwargs):
        i = random.randrange(len(self.sessions))
        s = self.sessions[i]
        s.used += 1
        try:
            r = s.http.get(url, timeout=(10, 30), **kwargs)
        except requests.exceptions.RequestException:
            self._replace(i)  # dropped exit or timeout: start a fresh session
            raise
        if r.status_code in (403, 429):
            raise SlowDown("%s returned %d" % (url, r.status_code))
        if r.status_code in self.EXIT_PROBLEMS or s.used >= s.max_requests:
            self._replace(i)
        return r


pool = SessionPool(size=5, ttl=15, max_requests=50)
print(pool.get("https://api.ipify.org").text)
```

## 如何知道粘性 IP 已更换？

查询。通过同一会话在流程开始和每个检查点请求如 `https://api.ipify.org` 这样的 IP 回显服务，比较结果。IP 变化意味着会话后端出口已变更：从上次检查点重启流程，或开启新会话。用会话 ID 记录，这样调试时可以区分 IP 变更与网站行为。

## 哪些会话错误代价最大？

- **多步流程中每次请求都轮换。** 网站看到购物车、游标或搜索令牌跨国跳转，会重置状态。
- **每个工作进程只用一个会话 ID。** 会话针对单一流程，给每个工作进程和每个流程分配独立 ID。
- **会话存活时间远长于任务时长。** 2 分钟流程用 30 分钟 TTL，占用 IP 无用且日志难读。
- **把 429 错误当作 IP 问题。** 新 IP 不改变网站限制，必须减缓请求频率。参见 [429 Too Many Requests](https://crawlrelay.com/zh/docs/errors/429-too-many-requests/)]。
- **假设每请求都轮换。** Keep-alive 保持出口连接；具体情况请参考上表你的库支持情况。

## 会话和轮换：常见问答

### 粘性会话持续多久？

粘性会话保持同一 IP，时间由您设置（ttl，单位分钟），最长 30 分钟。IP 可能提前更换，例如当住宅设备离线时。选择略长于所服务流程的 TTL，并在检查点校验出口。

### 粘性会话比轮换更贵吗？

不。CrawlRelay 按 GB 计费，包含会话、轮换和定向。粘性会话甚至能节省流量，因为保持连接避免每次请求都进行 TLS 握手。

### 每请求轮换更适合爬虫吗？

对于独立页面，轮换分散负载，避免同一 IP 长时访问单站点。对于带状态的页面（例如依赖 cookie 的分页）则会中断流程。大多数抓取任务混合使用：不同项目间轮换，同一流程内保持粘性。

### 我能指定获取的具体 IP 吗？

不能。住宅代理网关从不断变化的池中分配出口，匹配用户名内的定向选项。你可以选择国家、城市、美国州、邮编或 ASN，并通过会话保持 IP，但不能预留具体地址。

**所有套餐均包含轮换和会话功能** US$1.50，1 GB起，US$0.50/GB从50 GB起。 [查看价格](https://crawlrelay.com/zh/pricing/) · [并发指南](https://crawlrelay.com/zh/docs/concurrency/)

---

CrawlRelay: CrawlRelay 是为开发者设计的住宅代理和 4G/5G 移动代理轮换服务，适用于爬虫和 AI 数据管道：按需付费且流量永不过期，最低流量从 US$0.50/GB 起，支持加密货币支付，无需上传身份证明。无需 KYC —— 无需身份证、自拍和任何证件。支持加密货币支付。
