- 后端
- CLI
【免费下载链接】check-if-email-exists
Check if an email address exists without sending any email, written in Rust. Comes with a ⚙️ HTTP backend.
导读
Reacher v0.10 是一次面向生产环境可扩展性的大版本升级:它在原有/v0/*API 之上引入了全新的/v1/*端点,支持限流(throttle)与并发控制,并将批量验证从基于数据库轮询的旧实现迁移到 RabbitMQ 队列架构。本文以官方迁移文档为骨架,结合本仓库源码(backend/src/config.rs、backend/src/throttle.rs、backend/src/http/v1)逐项讲解新增端点行为、环境变量新旧对照表、批量验证架构变迁,并给出可落地的迁移实操步骤。读完本文,你将能够把运行在 v0.7 的自托管 Reacher 后端平滑升级到 v0.10 配置体系,并正确启用/v1端点。
v0.10 引入了哪些新端点
v0.10 的核心变化是新增了一组/v1/*端点,与旧版/v0/*端点并存:
| 端点 | 作用 | 新增行为 |
|---|---|---|
POST /v1/check_email | 单次邮箱验证 | 尊重配置中设置的 throttle(限流)与并发设置 |
POST /v1/bulk | 创建批量验证任务 | 将邮箱列表发布到 RabbitMQ 队列 |
GET /v1/bulk/{job_id} | 查询批量任务的进度与状态 | 从 Postgres 聚合统计结果 |
GET /v1/bulk/{job_id}/results | 拉取批量任务的完整结果(支持 CSV) | 见 backend/src/http/v1/bulk/get_results |
其中/v1/check_email的实现细节可以从 backend/src/http/v1/check_email/post.rs 中看到:请求到达后首先执行throttle_manager.check_throttle()(backend/src/throttle.rs),一旦超过限流配额立即返回429 TOO_MANY_REQUESTS并携带被命中的限流档位与等待时长;随后根据config.worker.enable决定是在当前进程内直接执行验证(handle_without_worker),还是通过 RabbitMQ RPC 模式把任务投递给 worker 并等待回包(handle_with_worker,使用correlation_id与临时reply_queue实现请求-响应匹配)。
关键结论:/v0/check_email的行为完全不变
迁移文档特别强调了一个容易踩坑的事实:
/v0/check_email端点在 API 和行为上均不改变。即使你在新版 Reacher Configuration 中配置了 throttle 与并发设置,/v0/check_email也不会应用它们——它仍然在收到请求后立即执行验证。
这一点在源码中得到双重印证:
- 在 backend/src/http/v0/check_email/post.rs 的
http_handler中,直接调用check_email(...)并立即返回,全程没有任何 throttle 检查; - 在 backend/backend_config.toml 的
[throttle]小节注释中明确写道:"these throttle configurations only apply to /v1/* endpoints, and not to the previous /v0/check_email endpoint. The latter endpoint always executes the verification immediately"(这些 throttle 配置只作用于 /v1/* 端点,旧端点始终立即执行验证)。
因此,若你需要限流保护,必须改用/v1/check_email;保持调用/v0/check_email不会获得任何限流收益。迁移到 v0.10 时请务必将客户端从POST /v0/check_email切换到POST /v1/check_email。
环境变量重命名对照表(迁移核心)
v0.10 引入了全新的 Reacher Configuration(见 docs/self-hosting/reacher-configuration-v0.10.md),配置体系从"散落的单下划线环境变量"切换为RCH__前缀 + 双下划线分隔符的层级命名规范。官方迁移文档给出的新旧对照如下:
| 旧环境变量名 | 新环境变量名 | 说明 |
|---|---|---|
RCH_HTTP_HOST | RCH__HTTP_HOST | HTTP 服务器绑定的主机名 |
PORT | RCH__HTTP_PORT | HTTP 服务器绑定的端口,通常由云平台注入 |
RCH_SENTRY_DSN | RCH__SENTRY_DSN | 设置后错误报告将发送到该 Sentry DSN |
RCH_HEADER_SECRET | RCH__HEADER_SECRET | 设置后所有 HTTP 请求必须携带x-reacher-secret请求头,用于保护后端免受公开恶意请求 |
RCH_FROM_EMAIL | RCH__FROM_EMAIL | SMTP 流程MAIL FROM:阶段使用的邮箱,可被每个请求的from_email字段覆盖 |
RCH_HELLO_NAME | RCH__HELLO_NAME | SMTP 流程EHLO阶段使用的名称,可被每个请求的hello_name字段覆盖 |
RCH_SMTP_TIMEOUT | RCH__SMTP_TIMEOUT | 每条 SMTP 连接的超时时间 |
RCH_WEBDRIVER_ADDR | RCH__WEBDRIVER_ADDR | 设置后使用无头浏览器访问密码找回页验证 Yahoo 与 Hotmail/Outlook 邮箱;推荐使用支持并行请求的chromedriver,例如http://localhost:9515 |
| 批量验证相关 | ||
RCH_ENABLE_BULK | RCH__WORKER__ENABLE | 是否启用批量验证 worker |
DATABASE_URL | RCH__WORKER__POSTGRES__DB_URL | 批量验证的数据库连接串,用于存储结果与任务队列 |
RCH_DATABASE_MAX_CONNECTIONS | 已移除 | 旧的数据库连接池大小配置 |
RCH_MINIMUM_TASK_CONCURRENCY | 已移除 | 旧的并发任务下限(低于该值则抓取更多任务) |
RCH_MAXIMUM_CONCURRENT_TASK_FETCH | 已移除 | 旧的单次抓取任务数量上限 |
双下划线分隔符的底层机制
新命名规范中的双下划线__不是随意的约定,它直接对应配置加载代码的分层解析逻辑。在 backend/src/config.rs 中:
let cfg = Config::builder() .add_source(config::File::with_name("backend_config")) .add_source(config::Environment::with_prefix("RCH").separator("__"));Environment::with_prefix("RCH").separator("__")意味着:RCH__HTTP_PORT会被解析为 TOML 结构中的http_port字段,RCH__WORKER__POSTGRES__DB_URL会被解析为worker.postgres.db_url嵌套结构,RCH__THROTTLE__MAX_REQUESTS_PER_MINUTE对应throttle.max_requests_per_minute。这也解释了为什么被移除的三个旧变量(RCH_DATABASE_MAX_CONNECTIONS、RCH_MINIMUM_TASK_CONCURRENCY、RCH_MAXIMUM_CONCURRENT_TASK_FETCH)在新架构中不再有对应位置——它们属于旧版数据库轮询任务队列(sqlxmq)的实现细节,在 backend/src/http/v0/bulk/mod.rs 中仍能看到它们以默认值 10 / 20 被读取的痕迹,而新架构已完全交给 RabbitMQ 与 Postgres 连接池管理。
迁移实操:Docker 环境变量示例
v0.10 配置文件的完整形态可参考仓库自带的 backend/backend_config.toml,每个字段都标注了对应的环境变量名。使用 Docker 运行 v0.10 后端时,通过-e传入新命名规范的环境变量,例如:
docker run -d \ -e RCH__HTTP_HOST=0.0.0.0 \ -e RCH__HTTP_PORT=8080 \ -e RCH__HELLO_NAME=mail.example.com \ -e RCH__FROM_EMAIL=hello@example.com \ -e RCH__HEADER_SECRET=my-secret \ -e RCH__WEBDRIVER_ADDR=http://localhost:9515 \ -p 8080:8080 \ reacherhq/backend:latest对照迁移,你需要做的改动是:
- 将
RCH_HTTP_HOST、RCH_HEADER_SECRET、RCH_FROM_EMAIL等旧变量全部替换为RCH__双下划线新名称; - 若之前依赖云平台注入的
PORT,需改为显式传递RCH__HTTP_PORT; - 若启用了批量验证,用
RCH__WORKER__ENABLE=true替代RCH_ENABLE_BULK=true,并用RCH__WORKER__POSTGRES__DB_URL替代DATABASE_URL; - 删除已废弃的
RCH_DATABASE_MAX_CONNECTIONS、RCH_MINIMUM_TASK_CONCURRENCY、RCH_MAXIMUM_CONCURRENT_TASK_FETCH。
迁移文档同时指出:新配置体系中,/v1/check_email会遵守[throttle]小节的限流设置(backend/backend_config.toml),推荐至少配置每分钟与每日上限(默认建议值 60 次/分钟、10000 次/天),避免源 IP 被邮箱服务商封禁。
批量验证架构演进:从数据库轮询到 RabbitMQ 队列
迁移文档明确指出:
/v0/bulk端点已被弃用,取而代之的是基于 RabbitMQ 的队列系统。
旧版/v0/bulk的实现在 backend/src/http/v0/bulk 中,它使用sqlxmq基于 Postgres 表做任务队列(见 backend/src/http/v0/bulk/mod.rs 的create_job_registry,通过RCH_MINIMUM_TASK_CONCURRENCY/RCH_MAXIMUM_CONCURRENT_TASK_FETCH控制任务抓取节奏),这也正是那几个环境变量被移除的根源——整个队列机制被替换掉了。
新版/v1/bulk的流程(对应 backend/src/http/v1/bulk/post.rs):
POST /v1/bulk接收{ "input": ["a@example.com", ...], "webhook": {...} };- 先在 Postgres 的
v1_bulk_job表插入一条任务记录(记录total_records),拿到job_id; - 逐个邮箱构建
CheckEmailTask,以低优先级(priority = 1)批量发布到 RabbitMQ 的check_email队列(每批 10 个并发发布); - 立即返回
{ "job_id": N }; - worker 消费队列执行验证,结果写入
v1_task_result表; GET /v1/bulk/{job_id}(backend/src/http/v1/bulk/get_progress.rs)通过 SQL 聚合is_reachable的 safe / risky / invalid / unknown 计数,返回任务状态(Running或Completed)与进度;GET /v1/bulk/{job_id}/results(backend/src/http/v1/bulk/get_results)拉取完整结果,支持 CSV 导出(backend/src/http/v1/bulk/get_results/csv_helper.rs)。
需要特别注意的是:/v1/bulk端点必须在 worker 模式下才能使用。backend/src/http/v1/bulk/mod.rs 的with_worker_db过滤器会检查两点:worker.enable必须为 true,且必须配置了 Postgres 存储,否则返回503 SERVICE_UNAVAILABLE。同时 backend/src/config.rs 在配置加载阶段就强制校验:启用 worker 模式时,必须配置 Postgres 数据库,否则直接报错启动失败。
启用 worker 模式的最小配置(对应 backend/backend_config.toml):
[worker] enable = true [worker.rabbitmq] url = "amqp://guest:guest@localhost:5672" concurrency = 5 [storage.postgres] db_url = "postgresql://localhost/reacherdb"数据库结构由仓库中的迁移脚本创建,详见 backend/migrations(其中20240929230957_v1_worker_results.up.sql即/v1worker 结果表结构)。RabbitMQ 的本地编排可参考 rabbitmq/docker-compose.yaml,更完整的水平扩展架构说明见 docs/self-hosting/scaling-for-production。
迁移自检清单
完成从 v0.7 到 v0.10 的迁移后,请逐项核对:
- 所有环境变量已切换到
RCH__双下划线命名(对照上文重命名表); - 已删除三个废弃变量(
RCH_DATABASE_MAX_CONNECTIONS、RCH_MINIMUM_TASK_CONCURRENCY、RCH_MAXIMUM_CONCURRENT_TASK_FETCH); - 单次验证客户端已从
POST /v0/check_email切换到POST /v1/check_email,以获得 throttle 限流保护; - 需要限流时,已在配置的
[throttle]小节设置至少每分钟/每日上限; - 批量验证已从
/v0/bulk迁移到/v1/bulk,并确保worker.enable = true且配置了 Postgres 存储与 RabbitMQ 连接; - 保留
x-reacher-secret请求头逻辑(若设置了RCH__HEADER_SECRET,所有请求必须携带该头)。
由于/v0/check_email的 API 与行为完全向后兼容,迁移过程可以渐进进行:先升级后端并验证/v0/check_email仍正常,再切换到/v1/check_email,最后迁移批量验证链路,从而将升级风险降到最低。
- 后端
- CLI
【免费下载链接】check-if-email-exists
Check if an email address exists without sending any email, written in Rust. Comes with a ⚙️ HTTP backend.
相关推荐
marimo 的 Model Context Protocol(MCP)完整指南:用 MCP Server 对外暴露 AI 工具、用 MCP Client 接入外部服务器
marimo 的 Model Context Protocol(MCP)完整指南:用 MCP Server 对外暴露 AI 工具、用 MCP Client 接入
后端CLI如何在 LibreChat Helm Chart 启用 Langfuse Fanout Gateway 并配置镜像、中心鉴权 Secret 与 Redis
如何在 LibreChat Helm Chart 启用 Langfuse Fanout Gateway 并配置镜像、中心鉴权 Secret 与 Redis 本文
后端CLIReacher(check-if-email-exists)v0.7 Docker 环境变量完全配置指南
Reacher(check if email exists)v0.7 Docker 环境变量完全配置指南 本文以 Reacher(check if email
后端CLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考