使用Docker Swarm搭建分布式爬虫集群

在爬虫开发过程当中,你确定遇到过须要把爬虫部署在多个服务器上面的状况。此时你是怎么操做的呢?逐一SSH登陆每一个服务器,使用git拉下代码,而后运行?代码修改了,因而又要一个服务器一个服务器登陆上去依次更新?node

有时候爬虫只须要在一个服务器上面运行,有时候须要在200个服务器上面运行。你是怎么快速切换的呢?一个服务器一个服务器登陆上去开关?或者聪明一点,在Redis里面设置一个能够修改的标记,只有标记对应的服务器上面的爬虫运行?python

A爬虫已经在全部服务器上面部署了,如今又作了一个B爬虫,你是否是又得依次登陆每一个服务器再一次部署?linux

若是你确实是这么作的,那么你应该后悔没有早一点看到这篇文章。看完本文之后,你可以作到:git

  • 2分钟内把一个新爬虫部署到50台服务器上:
docker build -t localhost:8003/spider:0.01 .
docker push localhost:8002/spider:0.01
docker service create --name spider --replicas 50 --network host 45.77.138.242:8003/spider:0.01
  • 30秒内把爬虫从50台服务器扩展到500台服务器:
docker service scale spider=500
  • 30秒内批量关闭全部服务器上的爬虫:
docker service scale spider=0
  • 1分钟内批量更新全部机器上的爬虫:
docker build -t localhost:8003/spider:0.02 .
docker push localhost:8003/spider:0.02
docker service update --image 45.77.138.242:8003/spider:0.02 spider

这篇文章不会教你怎么使用Docker,因此请肯定你有一些Docker基础再来看本文。redis

Docker Swarm是什么sql

Docker Swarm是Docker自带的一个集群管理模块。他可以实现Docker集群的建立和管理。docker

环境搭建shell

本文将会使用3台Ubuntu 18.04的服务器来进行演示。这三台服务器安排以下:json

  • Master:45.77.138.242
  • Slave-1:199.247.30.74
  • Slave-2:95.179.143.21

Docker Swarm是基于Docker的模块,因此首先要在3台服务器上安装Docker。安装完成Docker之后,全部的操做都在Docker中完成。ubuntu

在Master上安装Docker

经过依次执行下面的命令,在Master服务器上安装Docker

apt-get update
apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
apt-get update
apt-get install -y docker-ce

建立Manager节点

一个Docker Swarm集群须要Manager节点。如今初始化Master服务器,做为集群的Manager节点。运行下面一条命令。

docker swarm init

运行完成之后,能够看到的返回结果下图所示。

 

 

 

 

 

这个返回结果中,给出了一条命令:

docker swarm join --token SWMTKN-1-0hqsajb64iynkg8ocp8uruktii5esuo4qiaxmqw2pddnkls9av-dfj7nf1x3vr5qcj4cqiusu4pv 45.77.138.242:2377

这条命令须要在每个从节点(Slave)中执行。如今先把这个命令记录下来。

初始化完成之后,获得一个只有1台服务器的Docker 集群。执行以下命令:

docker node ls

能够看到当前这个集群的状态,以下图所示。

 

 

 

 

 

建立私有源(可选)

建立私有源并非一个必需的操做。之因此须要私有源,是由于项目的Docker镜像可能会涉及到公司机密,不能上传到DockerHub这种公共平台。若是你的镜像能够公开上传DockerHub,或者你已经有一个能够用的私有镜像源,那么你能够直接使用它们,跳过本小节和下一小节。

私有源自己也是一个Docker的镜像,先将拉取下来:

docker pull registry:latest

以下图所示。

 

 

 

 

 

如今启动私有源:

docker run -d -p 8003:5000 --name registry -v /tmp/registry:/tmp/registry docker.io/registry:latest

以下图所示。

 

 

 

 

 

在启动命令中,设置了对外开放的端口为8003端口,因此私有源的地址为:45.77.138.242:8003

提示:

这样搭建的私有源是HTTP方式,而且没有权限验证机制,因此若是对公网开放,你须要再使用防火墙作一下IP白名单,从而保证数据的安全。

容许docker使用可信任的http私有源(可选)

若是你使用上面一个小节的命令搭建了本身的私有源,因为Docker默认是不容许使用HTTP方式的私有源的,所以你须要配置Docker,让Docker信任它。

使用下面命令配置Docker:

echo '{ "insecure-registries":["45.77.138.242:8003"] }' >> /etc/docker/daemon.json

而后使用下面这个命令重启docker。

systemctl restart docker

以下图所示。

 

 

 

 

 

重启完成之后,Manager节点就配置好了。

建立子节点初始化脚本

对于Slave服务器来讲,只须要作三件事情:

  1. 安装Docker
  2. 加入集群
  3. 信任源

今后之后,剩下的事情所有交给Docker Swarm本身管理,你不再用SSH登陆这个服务器了。

为了简化操做,能够写一个shell脚原本批量运行。在Slave-1和Slave-2服务器下建立一个 init.sh 文件,其内容以下。

apt-get update
apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
apt-get update
apt-get install -y docker-ce
echo '{ "insecure-registries":["45.77.138.242:8003"] }' >> /etc/docker/daemon.json
systemctl restart docker 
docker swarm join --token SWMTKN-1-0hqsajb64iynkg8ocp8uruktii5esuo4qiaxmqw2pddnkls9av-dfj7nf1x3vr5qcj4cqiusu4pv 45.77.138.242:2377

把这个文件设置为可自行文件,并运行:

chmod +x init.sh
./init.sh

以下图所示。

 

 

 

 

 

等待脚本运行完成之后,你就能够从Slave-1和Slave-2的SSH上面登出了。之后也不须要再进来了。

回到Master服务器,执行下面的命令,来确认如今集群已经有3个节点了:

docker node ls

看到如今集群中已经有3个节点了。以下图所示。

 

 

 

 

 

到止为止,最复杂最麻烦的过程已经结束了。剩下的就是体验Docker Swarm带来的便利了。

建立测试程序

搭建测试Redis

因为这里须要模拟一个分布式爬虫的运行效果,因此先使用Docker搭建一个临时的Redis服务:

在Master服务器上执行如下命令:

docker run -d --name redis -p 7891:6379 redis --requirepass "KingnameISHandSome8877"

这个Redis对外使用 7891 端口,密码为 KingnameISHandSome8877 ,IP就是Master服务器的IP地址。

编写测试程序

编写一个简单的Python程序:

import time
import redis
client = redis.Redis(host='45.77.138.242', port='7891', password='KingnameISHandSome8877')
while True:
    data = client.lpop('example:swarm:spider')
    if not data:
        break
    print(f'我如今获取的数据为:{data.decode()}')
    time.sleep(10)

这个Python每10秒钟从Redis中读取一个数,并打印出来。

编写Dockerfile

编写Dockerfile,基于Python3.6的镜像建立咱们本身的镜像:

from python:3.6
label mantainer='[email protected]'
user root
ENV PYTHONUNBUFFERED=0
ENV PYTHONIOENCODING=utf-8
run python3 -m pip install redis
copy spider.py spider.py
cmd python3 spider.py

构建镜像

编写完成Dockerfile之后,执行下面的命令,开始构建咱们本身的镜像:

docker build -t localhost:8003/spider:0.01 .

这里须要特别注意,因为咱们要把这个镜像上传到私有源供Slave服务器上面的从节点下载,因此镜像的命名方式须要知足 localhost:8003/自定义名字:版本号 这样的格式。其中的 自定义名字 和 版本号 能够根据实际状况进行修改。在本文的例子中,我因为要模拟一个爬虫的程序,因此给它取名为spider,因为是第1次构建,因此版本号用的是0.01。

整个过程以下图所示。

 

 

 

 

 

上传镜像到私有源

镜像构建完成之后,须要把它上传到私有源。此时须要执行命令:

docker push localhost:8003/spider:0.01

以下图所示。

 

 

 

 

 

你们记住这个构建和上传的命令,之后每一次更新代码,都须要使用这两条命令。

建立服务

Docker Swarm上面运行的是一个一个的服务,所以须要使用docker service命令建立服务。

docker service create --name spider --network host 45.77.138.242:8003/spider:0.01

这个命令建立了一个名为 spider 的服务。默认运行1个容器。运行状况以下图所示。

 

 

 

 

 

固然也能够一建立就用不少容器来运行,此时只须要添加一个 --replicas 参数便可。例如一建立服务就使用50个容器运行:

docker service create --name spider --replicas 50 --network host 45.77.138.242:8003/spider:0.01

可是通常一开始的代码可能会有很多bug,因此建议先使用1个容器来运行,观察日志,发现没有问题之后再进行扩展。

回到默认1个容器的状况下,这个容器可能在目前三台机器在的任何一台上面。经过执行下面的命令来观察这一个默认的容器运行状况:

docker service ps spider

以下图所示。

 

 

 

 

 

查看节点Log

根据上图执行结果,能够看到这个运行中的容器的ID为 rusps0ofwids ,那么执行下面的命令动态查看Log:

docker service logs -f 容器ID

此时就会持续跟踪这一个容器的Log。以下图所示。

 

 

 

 

 

横向扩展

如今,只有1台服务器运行了一个容器,我想使用3台服务器运行这个爬虫,那么我须要执行一条命令便可:

docker service scale spider=3

运行效果以下图所示。

 

 

 

 

 

此时,再一次查看爬虫的运行状况,能够发现三台机器上面会各自运行一个容器。以下图所示。

 

 

 

 

 

如今,咱们登陆slave-1机器上,看看是否是真的有一个任务在运行。以下图所示。

 

 

 

 

 

能够看到确实有一个容器在上面运行着。这是Docker Swarm自动分配过来的。

如今咱们使用下面的命令强行把slave-1上面的Docker给关了,再来看看效果。

systemctl stop docker

回到master服务器,再次查看爬虫的运行效果,以下图所示。

 

 

 

 

 

能够看到,Docker Swarm探测到Slave-1掉线之后,他就会自动从新找个机器启动任务,保证始终有3个任务在运行。在这一次的例子中,Docker Swarm自动在master机器上启动了2个spider容器。

若是机器性能比较好,甚至能够在3每台机器上面多运行几个容器:

docker service scale spider=10

此时,就会启动10个容器来运行这些爬虫。这10个爬虫之间互相隔离。

若是想让全部爬虫所有中止怎么办?很是简单,一条命令:

docker service scale spider=0

这样全部爬虫就会所有中止。

同时查看多个容器的日志

若是想同时看全部容器怎么办呢?可使用以下命令查看全部容器的最新的20行日志:

docker service ps robot | grep Running | awk '{print $1}' | xargs -i docker service logs --tail 20 {}

这样,日志就会按顺序显示出来了。以下图所示。

 

 

 

 

 

更新爬虫

若是你的代码作了修改。那么你须要更新爬虫。

先修改代码,从新构建,从新提交新的镜像到私有源中。以下图所示。

 

 

 

 

 

接下来须要更新服务中的镜像。更新镜像有两种作法。一种是先把全部爬虫关闭,再更新。

docker service scale spider=0
docker service update --image 45.77.138.242:8003/spider:0.02 spider
docker service scale spider=3

第二种是直接执行更新命令。

docker service update --image 45.77.138.242:8003/spider:0.02 spider

他们的区别在于,直接执行更新命令时,正在运行的容器会一个一个更新。

运行效果以下图所示。

 

 

 

 

 

你能够用Docker Swarm作更多事情

本文使用的是一个模拟爬虫的例子,可是显然,任何能够批量运行的程序都可以用Docker Swarm来运行,不管你用Redis仍是Celery来通讯,不管你是否须要通讯,只要能批量运行,就能用Docker Swarm。

在同一个Swarm集群里面,能够运行多个不一样的服务,各个服务之间互不影响。真正作到了搭建一次Docker Swarm集群,而后就不再用管了,之后的全部操做你都只须要在Manager节点所在的这个服务器上面运行。

欢迎工做一到五年的Java工程师朋友们加入Java架构开发: 855835163 群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用本身每一分每一秒的时间来学习提高本身,不要再用"没有时间“来掩饰本身思想上的懒惰!趁年轻,使劲拼,给将来的本身一个交代!

相关文章
相关标签/搜索