2019-004-1-Cendertron,安全爬虫的分布式与稳定性优化之路
Cendertron,安全爬虫的分布式与稳定性优化之路
Cendertron是基于
基于Docker Swarm 的弹性化集群部署
在 
实际上,

整体爬虫在扫描调度中的逻辑流如下:

这里我们可以基于基础镜像编辑
version: "3"
services:
  crawlers:
    image: cendertron
    ports:
      - "${CENDERTRON_PORT}:3000"
    deploy:
      replicas: 2
    volumes:
      - wsat_etc:/etc/wsat
volumes:
  wsat_etc:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /etc/wsat/
这里我们将
{
  "db": {
    "redis": {
      "host": "x.x.x.x",
      "port": 6379,
      "password": "xx-xx-xx-xx"
    }
  }
}
# 创建服务
> docker stack deploy wsat --compose-file docker-compose.yml --resolve-image=changed
# 指定实例
> docker service scale wsat_crawlers=5
这里我们提供了同时扫描多个目标的创建方式,不同的| 作为分隔符:
POST /scrape
{
"urls":"http://baidu.com|http://google.com"
}
在集群运行之后,通过 ctop 命令我们能看到单机上启动的容器状态:

使用 htop 命令可以发现整个系统的

面向失败的设计与监控优先
在测试与高可用保障系列文章中,我们特地讨论过在高可用架构设计中的面向失败的设计原则:

这些原则中极重要的一条就是监控覆盖原则,我们在设计阶段,就假设线上系统会出问题,从而在管控系统添加相应措施来防止一旦系统出现某种情况,可以及时补救。而在爬虫这样业务场景多样性的情况下,我们更是需要能够及时审视系统的现状,以随时了解当前策略、参数的不恰当的地方。
在集群背景下,爬虫的状态信息是存放在了

我们依然通过 GET /_ah/health 端口来查看整个系统的状态,如下所示:
{
  "success": true,
  "mode": "cluster",
  "schedulers": [
    {
      "id": "a8621dc0-afb3-11e9-94e5-710fb88b1291",
      "browserStatus": [
        {
          "targetsCnt": 4,
          "useCount": 153,
          "urls": [
            {
              "url": ""
            },
            {
              "url": "about:blank"
            },
            {
              "url": ""
            },
            {
              "url": "http://180.100.134.161:8091/xygjitv-web/#/enter_index_db/film"
            }
          ]
        }
      ],
      "runingCrawlers": [
        {
          "id": "dabd6260-b216-11e9-94e5-710fb88b1291",
          "entryPage": "http://180.100.134.161:8091/xygjitv-web/",
          "progress": "0.44",
          "startedAt": 1564414684039,
          "option": {
            "depth": 4,
            "maxPageCount": 500,
            "timeout": 1200000,
            "navigationTimeout": 30000,
            "pageTimeout": 60000,
            "isSameOrigin": true,
            "isIgnoreAssets": true,
            "isMobile": false,
            "ignoredRegex": ".*logout.*",
            "useCache": true,
            "useWeakfile": false,
            "useClickMonkey": false,
            "cookies": [
              {
                "name": "PHPSESSID",
                "value": "fbk4vjki3qldv1os2v9m8d2nc4",
                "domain": "180.100.134.161:8091"
              },
              {
                "name": "security",
                "value": "low",
                "domain": "180.100.134.161:8091"
              }
            ]
          },
          "spiders": [
            {
              "url": "http://180.100.134.161:8091/xygjitv-web/",
              "type": "page",
              "option": {
                "allowRedirect": false,
                "depth": 1
              },
              "isClosed": true,
              "currentStep": "Finished"
            }
          ]
        }
      ],
      "localRunningCrawlerCount": 1,
      "localFinishedCrawlerCount": 96,
      "reportTime": "2019-7-29 23:38:34"
    }
  ],
  "cache": ["Crawler#http://baidu.com"],
  "pageQueueLen": 31
}
参数调优
因为网络震荡等诸多原因,src/config.ts 中包含了所有的配置:
export interface ScheduleOption {
  // 并发爬虫数
  maxConcurrentCrawler: number;
}
export const defaultScheduleOption: ScheduleOption = {
  maxConcurrentCrawler: 1,
};
export const defaultCrawlerOption: CrawlerOption = {
  // 爬取深度
  depth: 4,
  // 单爬虫最多爬取页面数
  maxPageCount: 500,
  // 默认超时为 20 分钟
  timeout: 20 * 60 * 1000,
  // 跳转超时为 30s
  navigationTimeout: 30 * 1000,
  // 单页超时为 60s
  pageTimeout: 60 * 1000,
  isSameOrigin: true,
  isIgnoreAssets: true,
  isMobile: false,
  ignoredRegex: ".*logout.*",
  // 是否使用缓存
  useCache: true,
  // 是否进行敏感文件扫描
  useWeakfile: false,
  // 是否使用模拟操作
  useClickMonkey: false,
};
export const defaultPuppeteerPoolConfig = {
  max: 1, // default
  min: 1, // default
  // how long a resource can stay idle in pool before being removed
  idleTimeoutMillis: Number.MAX_VALUE, // default.
  // maximum number of times an individual resource can be reused before being destroyed; set to 0 to disable
  acquireTimeoutMillis: defaultCrawlerOption.pageTimeout * 2,
  maxUses: 0, // default
  // function to validate an instance prior to use; see https://github.com/coopernurse/node-pool#createpool
  validator: () => Promise.resolve(true), // defaults to always resolving true
  // validate resource before borrowing; required for `maxUses and `validator`
  testOnBorrow: true, // default
  // For all opts, see opts at https://github.com/coopernurse/node-pool#createpool
};
延伸阅读
您可以通过以下任一方式阅读笔者的系列文章,涵盖了技术资料归纳、编程语言与理论、
- 在Gitbook 中在线浏览,每个系列对应各自的Gitbook 仓库。
| Awesome Lists | Awesome CheatSheets | Awesome Interviews | Awesome RoadMaps | Awesome MindMaps | Awesome-CS-Books | 
|---|
| 编程语言理论 | 
|---|
| 软件工程、数据结构与算法、设计模式、软件架构 | 现代 | 大前端混合开发与数据可视化 | 服务端开发实践与工程架构 | 分布式基础架构 | 数据科学,人工智能与深度学习 | 产品设计与用户体验 | 
|---|
