Yuque Archive
工作资料

crawler源码分析

  1. 进入主函数

  2. 初始化配置

  3. 如果是master,初始化节点ip列表

a. redis操作 

设置 crawl:master:state  =  starting

删除 up

删除 node:*

删除 crawl:cidr:*

删除 pending

 b.获取节点ip列表

从 seeders 获得列表,会过滤掉 exclude ip list 里的地址

[(2, 0, 0, '', ('82.221.111.136', 0))]

redis设值

pending = (address, CONF['port'], TO_SERVICES)

  = ('82.221.111.136', 8333, 1)

 从 bogons 地址查bogon ip,加入exclude ip list

crawl:master:state = running

  1. 启动task(消费者,默认 700-1 个)

在true循环里

如果 crawl:master:state != running,睡眠

pending 列表里随便取一个节点出来(取不到会sleep)

key = node:{}-{}-****{} (ADDRESS-PORT-SERVICES)

判断redis有没有 key

如果有,coninue

如果没有

如果地址是 ipv6,格式化成 CIDR 的表示形式,redis中 crawl:cidr:****{} 的值加 1

     connect ( key )

connect方法

设值 node:{}-{}-****{} = ''

取值 height ,如果有的话

实例化一个连接对象 conn,调用 protocol类的 Connect( address, etc. ) 方法

      conn.open(),建立socket连接

conn.handshake() (= handshake_msgs)

把  命令发送的节点

接收数据,并发送  命令回节点

接收数据,收到了一些版本信息,包括 块高度

 conn.getaddr()

发送  命令,不自动接收数据

手动接收数据

resids设值并设置过期时间8小时 height:{}-{}-****{} (address, port, from_services)

把 getaddr 获取到的节点列表累加到 pending 中 

如果 handshake_msgs 中的 services 和 发出去的 不一样

key = "node:{}-{}-{}"

设值 key = ''

把 key 累加到 up 列表

  1. 启动一个corn线程 (生产者)

      startTime init

在 true 循环里面

获取 pending 的总数

如果 pending != 0 睡眠几秒

如果 pending == 0

redis设值 crawl:master:state = starting

redis设值 elapsed = 当前时间 - 进入cron线程的时间

restart()

        redis操作 

    查询 up (=nodes)

    把 nodes 里的 address 累加到 pending

    删除 up

    删除 node:*

    删除 crawl:cidr:*

    把 bitnodes 官方已知的节点累加到 pending 里(默认关闭)

   redis设值 nodes lpush (timestamp, reachable_nodes)

  dump(nodes) (=h)

    redis 根据 height:{}-{}-****{} 查询每一个 node 的 height 

    输出 [address, port, services, height] 到 json文件

    return 出现次数最多的块高度

   redis设值 height = h

 战略性睡眠

 startTime inti

redis设值 crawl:master:state = running

最后输出的文件

问题:

  • 为什么默认worker数量是700 ?

  • 一个crawler 700个worker,三个crawler一共2000个task同时消费 pending,实际过程中penging列表里大概 25000 左右个待处理节点。

  • 这个crawler脚本获取到的关键信息主要是块高度,要保证在出一个块的时间内处理完pending。假设一个task请求一个节点(发请求、接收数据、数据处理)共耗时 20s,2000个task处理完 25000 个节点共耗时 250s 大概 4 到 5 分钟。

  • 这个文件里设置了 elapsed 的值但是没有用过

  • 在ping那个脚本里用了。

  • 为什么设置了 crawl:cidr:* 的值,但没有用过

  • up 和 pending 是什么关系,为什么第一次要把不是1的节点放到 up 里;后续的 up 里会充斥各种services的节点