Files
ocups-kafka/docs/采集流程时序图.md
2026-01-15 21:20:57 +08:00

13 KiB
Raw Blame History

增量采集流程时序图

1. 核心逻辑

采集方向(从后往前)

offset: total-100 → total-200 → ... → last_start_offset
优势:先采集最新数据,下次只采集新增部分

消息队列

  • 使用 RabbitMQ支持消息级别 TTL
  • 消息过期时间7天过期自动删除
  • 每批数据过滤后立即发送,不等待任务结束

2. 容器启动与自动采集

┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│   Docker    │  │    App      │  │  Crawler    │  │  RabbitMQ   │
│   容器      │  │   FastAPI   │  │   Manager   │  │             │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       │                │                │                │
       │ docker-compose │                │                │
       │     up         │                │                │
       │───────────────>│                │                │
       │                │                │                │
       │                │ lifespan启动   │                │
       │                │ auto_start=true│                │
       │                │───────────────>│                │
       │                │                │                │
       │                │                │ 遍历enabled任务 │
       │                │                │ 创建TaskCrawler │
       │                │                │────────┐       │
       │                │                │<───────┘       │
       │                │                │                │
       │                │                │ 并行启动所有任务│
       │                │                │═══════════════>│
       │                │                │                │

3. 单任务采集流程(从后往前,实时发送)

┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│ TaskCrawler │  │  八爪鱼API  │  │ DateFilter  │  │  RabbitMQ   │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       │                │                │                │
       │ 1.获取数据总数 │                │                │
       │───────────────>│                │                │
       │<───────────────│                │                │
       │  total=270000  │                │                │
       │                │                │                │
       │ 2.读取上次进度,计算采集范围    │                │
       │ start_offset = total - 100 = 269900             │
       │ end_offset = last_start_offset (上次起始位置)   │
       │────────┐       │                │                │
       │<───────┘       │                │                │
       │                │                │                │
       │ ╔══════════════════════════════════════════════════════════╗
       │ ║              循环:每批请求→过滤→立即发送                 ║
       │ ╚══════════════════════════════════════════════════════════╝
       │                │                │                │
       │ 3.请求一批数据 │                │                │
       │ offset=269900  │                │                │
       │───────────────>│                │                │
       │<───────────────│                │                │
       │  返回100条     │                │                │
       │                │                │                │
       │ 4.过滤数据(7天内有效)           │                │
       │───────────────────────────────>│                │
       │<───────────────────────────────│                │
       │  有效95条过期5条              │                │
       │                │                │                │
       │ 5.立即发送到RabbitMQ            │                │
       │   (消息TTL=7天过期自动删除)   │                │
       │────────────────────────────────────────────────>│
       │<────────────────────────────────────────────────│
       │  发送成功      │                │                │
       │                │                │                │
       │ 6.更新offset继续循环          │                │
       │ offset = 269900 - 100 = 269800  │                │
       │────────┐       │                │                │
       │<───────┘       │                │                │
       │                │                │                │
       │ 7.检查停止条件 │                │                │
       │ offset >= end_offset ? 继续     │                │
       │ offset < end_offset ? 停止      │                │
       │────────┐       │                │                │
       │<───────┘       │                │                │
       │                │                │                │

4. 进度记录与增量采集

┌─────────────────────────────────────────────────────────────────────────┐
│                        进度记录与增量采集                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  首次采集:                                                              │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │ total = 270000                                                   │   │
│  │ start_offset = total - 100 = 269900                              │   │
│  │ end_offset = 0 (首次采集,遇到连续过期数据停止)                  │   │
│  │                                                                   │   │
│  │ 采集完成后保存: last_start_offset = 269900                       │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
│  下次采集:                                                              │
│  ┌─────────────────────────────────────────────────────────────────┐   │
│  │ total = 270500 (新增500条)                                       │   │
│  │ start_offset = 270500 - 100 = 270400                             │   │
│  │ end_offset = 269900 (上次的起始位置)                             │   │
│  │                                                                   │   │
│  │ 只采集 270400 → 269900 这部分新增数据                            │   │
│  │ 采集完成后保存: last_start_offset = 270400                       │   │
│  └─────────────────────────────────────────────────────────────────┘   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

5. 停止条件

采集停止的条件(满足任一即停止):

  1. offset < end_offset - 已采集到上次的起始位置
  2. 连续3批数据全部过期 - 数据太旧(仅首次采集时生效)
  3. 手动调用停止接口

6. 消息过期机制

┌─────────────────────────────────────────────────────────────────────────┐
│                        RabbitMQ 消息TTL                                  │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  消息发送时设置 TTL = 7天 (604800000ms)                                 │
│                                                                         │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐          │
│  │ 消息A    │    │ 消息B    │    │ 消息C    │    │ 消息D    │          │
│  │ 1月8日   │    │ 1月10日  │    │ 1月14日  │    │ 1月15日  │          │
│  │ 已过期   │    │ 即将过期 │    │ 有效     │    │ 有效     │          │
│  │ 自动删除 │    │          │    │          │    │          │          │
│  └──────────┘    └──────────┘    └──────────┘    └──────────┘          │
│       ↓                                                                 │
│    RabbitMQ自动清理                                                     │
│                                                                         │
│  优势:                                                                 │
│  - 消息级别TTL精确控制每条消息的过期时间                              │
│  - 过期消息自动删除,无需手动清理                                       │
│  - 队列中始终保持最近7天的有效数据                                      │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

7. 配置说明

# config.yml

# RabbitMQ配置
rabbitmq:
  host: rabbitmq           # Docker内部服务名
  port: 5672
  username: guest
  password: guest
  queue: job_data
  message_ttl: 604800000   # 消息过期时间7天(毫秒)

# 采集配置
crawler:
  filter_days: 7           # 数据有效期(天)
  max_expired_batches: 3   # 连续过期批次阈值(首次采集时生效)
  auto_start: true         # 容器启动时自动开始采集

8. API接口

接口 方法 说明
/status GET 获取采集状态
/tasks GET 获取任务列表
/crawl/start POST 启动采集任务
/crawl/stop POST 停止采集任务
/consume GET 消费队列数据
/queue/size GET 获取队列消息数量

9. 数据流向

八爪鱼API → 采集服务(过滤7天内数据) → RabbitMQ(TTL=7天) → 第三方消费
                                            ↓
                                      过期自动删除