近日蜓谋,朋友推薦了一個(gè)好用的工具区匣,叫做splash. 是一個(gè)使用webdriver進(jìn)行瀏覽器動(dòng)態(tài)渲染的工具偷拔,非常的高效,可靠亏钩。剛好趁著周末閑來(lái)無(wú)事莲绰,在自身服務(wù)器上進(jìn)行一下程序的部署工作。
如果存在二次開發(fā)需求的朋友可以去git上下載項(xiàng)目源代碼 :spash git地址?
首先姑丑,我們使用docker-compose進(jìn)行程序的部署維護(hù)工作蛤签。docker-compose是一個(gè)用來(lái)定義和運(yùn)行復(fù)雜應(yīng)用的Docker工具。
這里我們不在講述安裝方法栅哀,具體的安裝方法可以參考?docker-compose教程(安裝震肮,使用, 快速入門)
安裝第一步:? 下載創(chuàng)建spash的docker鏡像。
? ?????????docker pull scrapinghub/splash
安裝第二步:配置docker-compose.yaml文件留拾,我這里貼出了我自己的docker-compose文件戳晌,供大家食用:version: "3"
services:
? nginx:
? ? image: nginx
? ? container_name: splash_nginx
? ? restart: always
? ? ports:
? ? ? - 8050:80
? ? volumes:
? ? ? - ./nginx/nginx.conf:/etc/nginx/nginx.conf
? ? depends_on:
? ? ? - splash1
? ? ? - splash2
? listener:
? ? image: python:3.8
? ? hostname: listener
? ? volumes:
? ? ? - ./script:/app
? ? command: bash /app/run.sh
? ? depends_on:
? ? ? - splash1
? ? ? - splash2
? splash1:
? ? hostname: splash1
? ? container_name: splash_1
? ? image: scrapinghub/splash
? ? restart: always
? splash2:
? ? hostname: splash2
? ? container_name: splash_2
? ? image: scrapinghub/splash
? ? restart: always
這時(shí)候就可以執(zhí)行docker-compose命令去啟動(dòng)splash了。
啟動(dòng)命令如下:
docker-compose up //程序控制臺(tái)啟動(dòng)
docker-compose up -d //程序后臺(tái)啟動(dòng)
在啟動(dòng)的時(shí)候痴柔,docker-compose 會(huì)自動(dòng)下載yaml文件中的nginx的鏡像于python3.8的鏡像沦偎,當(dāng)然如果各位大佬對(duì)于nginx于python版本有要求的話,可以自行更改docker-compose.yaml文件中的版本控制部分咳蔚。
如發(fā)生報(bào)錯(cuò):
? ? 發(fā)現(xiàn)nginx啟動(dòng)報(bào)錯(cuò)豪嚎,且報(bào)錯(cuò)內(nèi)容如下:
? ?
則是因?yàn)槌绦蜃詣?dòng)想要幫你創(chuàng)建的nginx.conf配置文件。但是因?yàn)槌绦騜ug的問(wèn)題谈火,niginx文件侈询,被創(chuàng)建成了一個(gè)名叫nginx.conf的文件夾所以導(dǎo)致報(bào)錯(cuò)。這里我們只需要?jiǎng)?chuàng)建一個(gè)nginx.conf的文件即可糯耍。 具體文件內(nèi)容為:
user nginx;
worker_processes? 1;
error_log? /var/log/nginx/error.log warn;
pid? ? ? ? /var/run/nginx.pid;
events {
? ? worker_connections? 1024;
}
http {
? ? include? ? ? /etc/nginx/mime.types;
? ? default_type? application/octet-stream;
? ? log_format? main? '$remote_addr - $remote_user [$time_local] "$request" '
? ? ? ? ? ? ? ? ? ? ? '$status $body_bytes_sent "$http_referer" '
? ? ? ? ? ? ? ? ? ? ? '"$http_user_agent" "$http_x_forwarded_for"';
? ? access_log? /var/log/nginx/access.log? main;? ?
? ? client_max_body_size 10m;
? ? sendfile? ? ? ? on;
? ? #tcp_nopush? ? on;
? ? keepalive_timeout? 65;
? ? #gzip? on;
? ? upstream tomcat_client {
? ? ? ? server splash1:8050 weight=1;
? ? ? ? server splash2:8050 weight=1;
? ? }
? ? server {
? ? ? ? server_name "";
? ? ? ? listen 80 default_server;
? ? ? ? listen [::]:80 default_server ipv6only=on;
? ? ? ? location / {
? ? ? ? ? ? proxy_pass http://tomcat_client;
? ? ? ? ? ? proxy_redirect default;
? ? ? ? ? ? proxy_set_header Host $host;
? ? ? ? ? ? proxy_set_header X-Real-IP $remote_addr;
? ? ? ? }? ?
? ? }
}
然后再次啟動(dòng)即可扔字。
如果這時(shí)候依舊發(fā)生報(bào)錯(cuò),且錯(cuò)誤內(nèi)容為(問(wèn)題無(wú)法重現(xiàn)谍肤,就不貼圖了):python的鏡像無(wú)法啟動(dòng):
則是因?yàn)槟闳鄙賞ython的執(zhí)行腳本以及啟動(dòng)腳本:
? ?python 執(zhí)行腳本如下:?splash_listener.py
# -*- coding:utf-8 -*-
# @Author: wmy
# @Time: 2020/7/3
# @Description:
import sys
import subprocess
import requests
import logging
class Listener(object):
? ? def __init__(self):
? ? ? ? self.splash_timeout = 10
? ? ? ? self.splash_ping_times = 2
? ? ? ? self.logger = self.get_logger()
? ? ? ? self.splash_servers = [
? ? ? ? ? ? {
? ? ? ? ? ? ? ? 'host': 'splash1',
? ? ? ? ? ? ? ? 'port': '8050',
? ? ? ? ? ? ? ? 'name': 'splash_1',
? ? ? ? ? ? },
? ? ? ? ? ? {
? ? ? ? ? ? ? ? 'host': 'splash2',
? ? ? ? ? ? ? ? 'port': '8050',
? ? ? ? ? ? ? ? 'name': 'splash_2',
? ? ? ? ? ? },
? ? ? ? ]
? ? def get_logger(self, name='splash_listener', level=logging.INFO):
? ? ? ? """
? ? ? ? 獲得一個(gè)logger
? ? ? ? :param name:
? ? ? ? :param level:
? ? ? ? :return:
? ? ? ? """
? ? ? ? logger = logging.getLogger(name)
? ? ? ? logger.setLevel(level)
? ? ? ? stream_handler = logging.StreamHandler()
? ? ? ? formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s: - %(message)s',
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? datefmt='%Y-%m-%d %H:%M:%S')
? ? ? ? stream_handler.setFormatter(formatter)
? ? ? ? logger.addHandler(stream_handler)
? ? ? ? return logger
? ? def ping_splash(self, splash_host, splash_port):
? ? ? ? """
? ? ? ? 嘗試連接splash啦租,測(cè)試splash服務(wù)是否正常
? ? ? ? :return: 正常,True,無(wú)法訪問(wèn),False
? ? ? ? """
? ? ? ? splash_url = 'http://{}:{}'.format(splash_host, splash_port)
? ? ? ? try:
? ? ? ? ? ? resp = requests.get(splash_url, timeout=self.splash_timeout)
? ? ? ? except Exception as e:
? ? ? ? ? ? self.logger.error(u'請(qǐng)求出錯(cuò).{}'.format(e))
? ? ? ? ? ? return False
? ? ? ? if resp.status_code != 200:
? ? ? ? ? ? self.logger.error(u'狀態(tài)碼異常.{}'.format(resp.status_code))
? ? ? ? ? ? return False
? ? ? ? return True
? ? def listen_splash(self):
? ? ? ? """
? ? ? ? 監(jiān)聽splash荒揣,嘗試連接splash,直到成功或者失敗self.splash_ping_times次焊刹。
? ? ? ? :return: 成功系任,True恳蹲,失敗,F(xiàn)alse
? ? ? ? """
? ? ? ? for splash in self.splash_servers:
? ? ? ? ? ? mark = False
? ? ? ? ? ? # check splash
? ? ? ? ? ? for i in range(self.splash_ping_times):
? ? ? ? ? ? ? ? if self.ping_splash(splash['host'], splash['port']):
? ? ? ? ? ? ? ? ? ? mark = False
? ? ? ? ? ? ? ? else:
? ? ? ? ? ? ? ? ? ? mark = True
? ? ? ? ? ? if mark:
? ? ? ? ? ? ? ? # restart splash
? ? ? ? ? ? ? ? subprocess.Popen(args=['docker', 'restart', splash['name']])
? ? ? ? ? ? ? ? self.logger.error(u'{} splash服務(wù)異常俩滥,重啟服務(wù)'.format(splash['name']))
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? self.logger.info(u'{} splash服務(wù)正常'.format(splash['name']))
if __name__ == '__main__':
? ? import time
? ? while True:
? ? ? ? Listener().listen_splash()
? ? ? ? time.sleep(60*5)
python腳本啟動(dòng)如下:run.sh
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests
python /app/splash_listener.py
將兩個(gè)文件復(fù)制到docker-compose的同級(jí)目錄script文件夾下即可嘉蕾。
然后再次使用docker-compose up 命令進(jìn)行程序的啟動(dòng)。
以上便是我在使用docker-compose安裝splash程序過(guò)程中所遇到的問(wèn)題霜旧。特此記錄一下