php根据路径列表生成bootstrap treeview
有这么一个需求,需要根据svn生成的版本之间差异的文件列表,生成一个treeview。
数据样本如下:
1 | $defaultStr = [ |
思路如下,先根据 /
符号拆分路径成数组,拼凑tree数组。最后根据tree数组递归生成json数组。
生成数组
1 | $tree=array(); |
生成类似如下的数组
1 |
|
递归生成树
1 | //递归生成树 |
生成最终符合bootstrap treeview的格式
1 | [ |
有这么一个需求,需要根据svn生成的版本之间差异的文件列表,生成一个treeview。
数据样本如下:
1 | $defaultStr = [ |
思路如下,先根据 /
符号拆分路径成数组,拼凑tree数组。最后根据tree数组递归生成json数组。
生成数组
1 | $tree=array(); |
生成类似如下的数组
1 |
|
递归生成树
1 | //递归生成树 |
生成最终符合bootstrap treeview的格式
1 | [ |
未雨绸缪,考虑到以后可能服务器增多,如果日志不集中管理,单台日志查看,还是显得比较麻烦。
有常查看nginx日志的需求,所以,打算利用rsyslog对nginx日志做个集中管理。
这里假设日志中心为center,节点1为node1
服务器 | IP |
---|---|
Center | 192.168.1.2 |
Node1 | 192.168.1.3 |
配置都是基于Centos7 默认的rsyslog版本 7.4.7 V5、V7、V8配置差别似乎挺大的,所以尽量用同样的版本吧
1 | # vim /etc/rsyslog.conf |
配置好rsyslog,就可以重启一下服务了。
#systemctl restart rsyslog
如果没意外,netstat -antp | grep rsyslog
就能看到开放的514端口了。
1 | ## 将所有等于或者大于info级别的信息传到Center |
重启服务systemctl restart rsyslog
,这个时候用logger "test"
在Center的/var/log/messages日志应该就能看到了。
新版本的nginx基本都支持在nginx配置中,直接配置syslog。
但是我这里还是用老办法。现在rsyslog配置读取nginx的日志文件,然后传送过去,这个办法也试用于其它服务的日志。
Node1 新建一个rsyslog配置nginx.conf
1 | vim /etc/rsyslog.d/nginx.conf |
我在一台V5版本上是这样配的
1 | $ModLoad imfile |
Center
这个配置例子好匮乏,找了好多资料,终于谷爹那里找到了。见文末参考资料。根据配置的tag导出日志到特定文件。
同样新建一个rsyslog配置文件nginx.conf,使用omfile模块,用dynaFile参数实现动态文件名。这个很多国内文章基本都没提到,还是看帮助文档发现这个的。否则我就用logrotate了。
1 | vim /etc/rsyslog.d/nginx.conf |
重启rsyslog,应该就没问题了。
基于我们团队现在业务还在处于比较初期的阶段。访问量并不大,性能问题就成了一个重要但是不紧急的任务。
我而目前主要在发布、监控自动化、可视化。尽可能减少人为操作的问题上努力。
最近深圳那边同事说服务器有点问题,主要是网站访问缓慢,叫如果有空帮忙看看。
我09年左右就开始运营自己的小网站,可以说也是经历过很多这类问题的排查。
也遇过很多奇葩的问题导致网站访问过慢,甚至打不开的情况,但是从未记录下来。
所以,打算开一篇博文记录一下,一方面当做一种笔记,一方面也帮助自己理清一下整个流程。
很多时候我们习惯访问一慢,就往服务器上看。看看是不是服务器出什么问题了。
其实,在访问网站的过程,任何一个环节都可能会出问题。
但是,最为常见的原因无非以下几种。
往大来分类
自己电脑->网络运营商->DNS->主机服务商->服务器
而前面几个大多时候是我们不可控的。除了选择的时候 :D 但是,也得在我们考虑范围内,否则有时候可能白忙碌一场。
抛开不可控的因素,服务器上发生的所有一切才是我们最为关心的。
这个问题,其实攻击都是有成本的,如果没有业务冲突,规模不大,很多时候是没人闲的蛋疼跑去攻击你。这个大多情况都是可以被排除的。
这两个其实还是比较简单粗暴的。这个的防护,小规模的,现在很多大的云主机商多少都提供了这类的防护。节点少的,尽可能隐藏自己的源IP可以少很多麻烦
大规模的攻击,基本都是要上升到讨论成本的东西,软硬件防护,多节点,负载均衡等杂七杂八的,增加自己的成本,提高攻击者的攻击成本。
一些服务器上做的配置防护,在这类分布式多IP的大规模攻击下,效果微乎其微。
整个对于大多网站来说,是喜闻乐见的。不过这些访问,不单单包括自然访问,还有一些非自然访问量。
根据木桶原理,任何一个短板,都有可能导致整个服务流程出现缓慢。
如果硬件到了瓶颈,那就该考虑,是不是该升级配置了?是不是该做CDN加速了?是不是该做负载均衡了?
如果排除前面提到的一些不可控和被攻击的问题,而硬件负载都很低,那基本问题就出现在服务和业务相关问题上了。
服务的配置是否针对当前服务器的配置进行过针对性的优化?是否能发挥了当前硬件的潜能?
简而言之,哪个拖后腿整哪个。剩下的就是定位问题和解决问题,这也是最重要的部分。
先挖坑,以后再填。
报错:mysqldump: unknown variable ‘set-gtid-purged=OFF’
完整出错如下:
1 | 11:45:51 AM Dumping xxx_logview (gef_infos) |
出错很明显是mysqldump
不支持这个set-gtid-purged。我用的是MairaDB自带的mysqldump工具,版本如下。可能移除了这个特性。
mysqldump Ver 10.15 Distrib 10.0.29-MariaDB, for debian-linux-gnu (x86_64)
而MySQL Workbench在export data的时候,默认是加上–set-gtid-purged=OFF参数的。
所以,我能想到的方法如下:
理论上去掉它这个默认设置就可以了。但是很遗憾,我不知道workbench在哪里改这参数。。。找了半天。
安装一个MySQL数据库,然后在MySQL Workbench
-> Edit
-> Perferences
-> Administration
-> Path to mysqldump
指定你MySQL版本数据带的mysqldump工具的路径。
用其它数据库管理工具,比如我,最后用了DBeaver CE 算是Linux下一个很万能的数据库管理工具了。大部分场景下,和Navicat有得拼。关键还是免费!
GoAccess GoAccess Download 作为一个轻量的日志分析,还是不错的。之前一直都是用命令安装。直到前几天为了体验最新版的UI,自己尝试在Ubuntu 16.04上编译安装,比较轻松。
可能是我自己的机子用了段时间,很多依赖包都装好了。但是在生产环境CentOS7.2上还是遇到了几个小问题。
安装依赖包
1 | yum install ncurses-devel geoip-devel tokyocabinet-devel openssl-devel |
安装完GeoIP
记得更新一下 # geoipupdate
把数据库下载回来,之前不知道这个,导致老是觉得数据库太简陋了。
我的话是Clone git的源码安装的,步骤如下:
$ git clone https://github.com/allinurl/goaccess.git
$ cd goaccess
$ autoreconf -fiv
这一步你可能会遇到像我一样的错误。
错误1
1 | -bash: autoreconf: command not found |
这个安装 yum install -y autoconf
即可
错误2
1 | Can't exec "autopoint": No such file or directory |
安装gettext-tools
1 | yum install gettext-common-devel gettext-devel gettext-libs |
1 | Can't exec "aclocal": No such file or directory at /usr/share/autoconf/Autom4te/FileUtils.pm line 326. |
automake
即可1 | yum install -y automake |
yum groupinstall "Development tools"
直接大杂烩,一锅炖了。$ make
$ make install
所以试试发布自己的线上业务看看。
理论部署的前后,会触发四个任务。
pre_deploy
、post_deploy
、pre_release
和post_release
名字来看,就比较好理解,部署前、部署后,发布前,发布后。
官方给出的流程如下:
以下是上线任务的发布进度条
很明显,触发的deploy任务是在宿主机。
我整理了如下表格:
任务 | 执行点 | 时间时间 |
---|---|---|
pre_deploy | 宿主机 | 代码检出前 |
post_deploy | 宿主机 | 代码检出后,传送之前 |
pre_release | 目标机 | 创建链接之前 |
post_release | 目标机 | 创建链接之后 |
我们拉取开发环境的代码部署至宿主机,乃至线上环境的时候。有一些配置是要替换的,比如数据库账户之类的。有一些文件是要删除,一些目录是需要合并的。
但是,怎么做呢?
这就用到这些任务了。大多数场景,我想就用pre-deploy或者pre release就够了。
用法基本都一样,差别就在执行顺序。
宿主机要用web执行系统命令,所以需要额外添加一句到sudoers
文件里面。
visudo
1 | Defaults:www !requiretty |
www 是web执行PHP的用户。
我们是有几个东西要替换。一个是配置目录、另外两个是用户的上传目录。用户上传的静态内容,开发环境是没有了。
考虑到每次复制替换,一个是费系统资源。
所以,我打算在传输之前,先删除掉静态资源。再传去服务器的时候,打上线上的资源的链接。
如此就能实现动态更新了。
有个官方没有说明的是。每次执行任务之前,都是进去到当前目录的。所以删除移动项目目录之类的,都用相对路径即可。
接手管理某台ERP服务器的生产环境。主要配有LNMP环境,前两天发现,这些服务居然都没有配置自启动。
这完全不考虑服务器意外重启导致服务未能启动,从而引起长时间的服务中断么?
所以,今天就特地添加了自启动。
本来,添加自启动是很简单的。尤其是yum安装出来的服务。
CentOS 7
1 | systemctl enable nginx php-fpm |
CentOS 5/6
1 | chkconfig nginx on |
然而,这台是自己下载的软件包,还是自己编译的不得而知。反正/etc/init.d/
完全没这两货的影子。
没有那就添加吧,两个bash脚本。
我从网上扒拉了两段自己修改了一下。代码如下:
1 | #!/bin/bash |
nginx 主程序一般自带了好多方法,比如好用的 stop、reload。所以nginx的代码显得比较简洁。
关于找nginx路径,一般其实用which nginx
或者 whereis nginx
就够了。
但是想补充一个更加可靠的。
ps -aux | grep nginx
看到 exe 文件的链接路径就是我们要找的程序全路径了。
1 | $ ps -aux | grep nginx |
1 | # pidfile: /var/run/php-fpm.pid |
这个代码就有点随意了,我做了少量修改,注意修改下执行程序的路径和PID文件的路径就行了,这里代码并没有用到配置文件路径其实。如果无法正确加载配置,可以把我加上的#-c /app/php56/lib/php.ini -y ${php_config}
这句代码注释去掉。
另外 php-fpm的配置路径在ps -aux | grep php-fpm
即可看到。记得修改,去掉pid路径的注释。
虽然代码在没找到pid文件的时候,会自己尝试提取pid,但是建议还是去掉注释。
两个文件一个保存为 /etc/init.d/nginx
一个保存为 /etc/init.d/php-fpm
名字可以自己改,但是不推荐。
添加进chkconfig chkconfig --add nginx && chkconfig -add php-fpm
开启开机启动 chkconfig nginx on && chkconfig php-fpm on
/etc/rc.local
修改吗可以的。
比如
1 | /app/nginx/sbin/nginx -c /app/nginx/conf/nginx.conf |
为何不这样做,为了以后管理服务,比如重启方便一点。
近日需要频繁测试各种环境,奔波于各种虚拟机之间,虽然自己制作了诸多虚拟机环境模板,平时直接克隆软连接使用。
但是还是感受到了世界满满的恶意。
所以决定安装一下docker 减轻一下工作量。一个人kubernetes
就没必要装了吧。
觉得如果用kubernetes
去管理团队各个机器的开发者的环境,减轻他们平时环境搭建的麻烦还是挺不错的。
不过,还没到时候。
本文主要参考docker的官方文档。
如果之前安装了旧版本的docker,旧版本docker名字是docker或者docker-engine
sudo apt-get remove docker docker-engine
因为新版本的docker仓库改为使用https
链接,所以,还要运行以下语句,让apt
允许使用https
方式链接
1 | $ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common |
安装官方源的GPG key,关闭GPG check应该也是可以的。
1 | $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - |
安装docker源
如果和我一样是使用linux mint
的话,$(lsb_release -cs)
并不能获取Ubuntu的版本代号,获取的是自己的。
自行修改,比如我的是16.04 那就是 xenial。
1 | $ sudo add-apt-repository \ |
更新源
1 | sudo apt-get update |
done.
先下载一个docker的registry镜像。
其实,应该 sudo apt install docker-registry
就能直接装一个的,当服务管理。
这里就用docker镜像实现吧。
我直接用root账户用docker
1 | # docker pull registry |
我本地docker环境IP是 192.168.1.88
那么仓库地址就是 http://192.168.1.88:5000
首先给本地镜像打个tag
1 | # docker pull centos # 先从官方镜像仓库拉一个centos回来测试 |
这个时候 # docker push 192.168.1.88:5000/centos
遇到了错误。
docker现在版本默认仓库都是使用https
协议连接的,要使用本地仓库,还能自定义添加非安全的仓库地址。
步骤如下:
1.修改 /etc/default/docker
1 | DOCKER_OPTS="--registry-mirror=http://xxxxxxxx.m.daocloud.io --insecure-registry 192.168.1.88:5000 --dns 8.8.8.8 --dns 8.8.4.4" |
重点是--insecure-registry 192.168.1.88:5000
这句
以往这样修改就没问题了。然而今天发现重启docker后,居然没生效。systemctl status docker
没看到启动参数有我们添加的内容
2.修改服务文件,增加指定启动参数
其实直接在ExecStart
直接添加--insecure-registry 192.168.1.88:5000
是一样可以的。
但是为了管理方便,和以后便于修改,就改成如下形式。从/etc/default/docker
读取$DOCKER_OPTS
的配置。
1 | # vim /lib/systemd/system/docker.service |
这个时候再systemctl status docker
就能看到我们添加的参数了。
ps. docker.service
文件也可以通过systemctl status docker
查看到。
3.Push 到本地仓库
1 | # docker push 192.168.1.88:5000/centos |
这个时候就能很愉快地完成push到本地仓库了。
看到这个的我眼泪留下来,daocloud.io搞的东西。
1 | 在 Linux上 安装 Docker |
Centos7
1 | yum install -y yum-utils |
今天遇到,所以补充一下.阿里云提供了一个镜像源https://mirrors.cloud.aliyun.com/docker-ce/
但是没外网的时候是访问不了的,经过一番观察,只需做如下改动即可.
阿里云提供了一个内网访问的域名.将链接改成如下信息即可
http://mirrors.cloud.aliyuncs.com/docker-ce/
1 | yum install -y yum-utils |
这个东西写有半个月了,最近工作忙没空理会,看了下数据,跑得还不错。
用各种框架和开源项目配合,站在巨人的肩膀上,轻轻松松完成一个麻雀虽小五脏俱全的爬虫。
采集URL,大规模URL去重,分类,入库,反爬虫。而完成这些,只需要寥寥不到三百行代码。
Scrapy工程目录如下
1 | ./ |
首先是字段的定义,我需要保存哪些信息
1 | import scrapy |
然后我设计了这样的数据库表来保存它们:
1 | -- phpMyAdmin SQL Dump |
注意看注释,还是很好理解这些表干嘛用的。
pipelines.py
获取到的Items怎么处理
这里有两个类,其实是两种处理方式,一种是默认的,我改了一下,采集到的数据,以JSON的形式保存。
sobaiduPipeline
才是重点,主要有两次插入数据,一次是插入用户数据,一次获取到用户ID后,插入到yzy_resources
表。
数据库的定义在 settings.py
里面
1 | import json |
sobaidupan.py
蜘蛛的主体
1 | # -*- coding: utf-8 -*- |
多IP代理采集反爬虫 IPProxys+RandomUserAgent
先下载安装这个 IPProxyPool 。
搭建成功后,运行有采集到数据的话,curl http://127.0.0.1:8000/?types=0&count=5&country=国内
可以看到返回json格式的数据。这样就成功一半了。
主要调用接口和随机切换代码 RandomProxy.py
1 | class RandomProxy(object): |
最后怎么在服务器上挂机采集,爬虫持久化
1 | nohup scrapy crawl sobaidu -s JOBDIR=crawls/sobaidu-1 1>/dev/null 2>logfile.log & |
数据样本,5天28万的数据,主要是代理IP质量不高,否则速度还能上一个台阶,还不是分布式。
1 | MariaDB [yzy_data]> select count(*) from yzy_resources; |
nginx现在用yum源安装的话,都自带了logrotate
,默认是每天定时分割日志并压缩。
但是公司目前有一台生产环境的nginx不是用yum安装的。所以就得自己手动分割下日志了。
目前就是bash脚本+crontab实现,具体代码如下:
1 | #!/bin/bash |