1.引言

    最近小组做了个疫情可视化的项目,说是项目更像是一个demo,实现的方式上,内部利用第三方接口,然后爬取第三方接口数据存储到我们的数据库中。为什么要这样设计呢,因为如果你不断去调用第三方接口,有类似于网上很多的接口网站:我搭了一个接口网站,结果张三发现了我这个接口网站比较好,于是张三先注册我这个接口网站用户,拿到接口网站里面的接口,然后自己“copy”出来一个接口网站。这样将导致一个问题:来自张三网站用户的调用本质是对我自己的网站的调用,导致我的网站承担了较大的服务器压力。
    除了上面提到的站点复刻,更加严重的可以是来自黑客的攻击。这里比较常见的是HTTP Flood 俗称CC攻击(Challenge Collapsar)是DDOS(分布式拒绝服务)的一种,前身名为Fatboy攻击,也是一种常见的网站攻击方法。是针对 Web 服务在第七层协议发起的攻击。攻击者相较其他三层和四层,并不需要控制大量的肉鸡,取而代之的是通过端口扫描程序在互联网上寻找匿名的 HTTP 代理或者 SOCKS 代理,攻击者通过匿名代理对攻击目标发起HTTP 请求。匿名代理服务器在互联网上广泛存在。因此攻击容易发起而且可以保持长期高强度的持续攻击,同样可以隐藏攻击者来源避免被追查。说白了就是利用大量的代理隐藏自己的ip地址然后发起大量请求,这样表面看是没有固定ip在使用自己站点的,但是如果长期大量ip肯定会导致整个服务器异常,也违背了为大众用户服务的初衷。
    解决方式是什么呢,封掉调用次数异常高的网站,做请求限制,这种限制又称为QPS限制(query per second) 指的是每秒向服务发送的请求数量峰值,相当于每个API接口每秒可以允许请求的并发上限量,被QPS限制后,若在封锁期间再次调用接口封锁时间会重新计算

2.解决方案

    基于上面的种种方案,我们决定采用请求第三方接口,然后将接口数据存储在我们的服务器中,并且能够实现数据的刷新。宏观上来说项目就是对接口数据做了个缓存,因为疫情数据不是说更新就立即更新的,而是以天为单位或者以一定间隔小时为单位。这里遇到的技术难点就是刷新,由于白天存在较多的用户,因此需要在凌晨刷新比较合理。甚至更好的采用一个退避服务,这里想说是如果数据库刷新和用户调用冲突了,可以先等待数据库更新,然后再执行用户对接口的调用。不管怎么说解决定时刷新就是难点,总不能凌晨爬起来刷新。最后通过网上搜索得到了Linux服务器的特点,能够执行定时任务,甚至能够定时请求。找的就是这种功能。

3.基于crontab的定时任务

    首先给出当前使用的crontab例子:
在Linux服务器中执行crontab -uroot -e(表示编辑crontab任务列表),写入如下内容:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
30 04 * * * /mnt/update.sh >> /data/nightowl/update.log 2>&1
#表示凌晨4:30定制执行/mnt/update.sh里面的脚本()同时将执行的日志放到/data/nightowl/update.log中,
#后面的2>&1表示的是将标准错误重定向到标准输出,顺序不能错,是2>&1,否则无内容输出
#我对于shell语言理解不是很深,就直接理解成把日志输出来吧,方便查看报错情况
#另外有些时候还在2>&1后面再加一个&,表示的是后台执行,
#这里加上了下面两句
#SHELL=/bin/sh
#PATH=/sbin:/bin:/usr/sbin:/usr/bin
#主要是为了使环境变量生效,去执行指令

    接下来就详细说一下如何配置crontab以及与crontab相关的规则。对于crontab规则,这里直接使用菜鸟驿站上面提供的时间规则:
在这里插入图片描述
crontab 常用命令:

systemctl stop crond #关闭crontab服务
systemctl start crond #开启crontab服务
systemctl restart crond #重启crontab服务
tail -f /var/log/cron #打印crontab日志(默认打印10条)
crontab -uroot -e 
#编辑crontab服务,配合insert esc :wq(保存退出) :q!(不保存退出)等指令
crontab -l #列出crontab任务列表
# 每次修改crontab之后会默认重启crontab

还是举几个例子吧:

*/1 * * * * /mnt/update.sh >> /data/nightowl/update.log 2>&1
#每秒钟执行
0 2,3 * * /mnt/update.sh >> /data/nightowl/update.log 2>&1
#每天2:00和3:00执行
0 11 4 * mon-wed /mnt/update.sh >> /data/nightowl/update.log 2>&1
#每月的4号和星期一到星期三执行
#如果是测试的话可以使用(打印时间):
*/1 * * * * date >> /data/nightowl/test.log 2>&1
#或者
*/1 * * * * echo "hello flying_dark_feather" >> /data/nightowl/test.log 2>&1

效果如下:
在这里插入图片描述
下面个给出get请求和post请求的例子:

3.1crontab发送get请求

(1)使用curl命令:

curl "get请求链接" 
#如果这里的URL指向的是一个文件或者一幅图都可以直接下载到本地
curl -i "get请求链接" #显示全部信息
curl -l "get请求链接" #只显示头部信息
curl -v "get请求链接" #显示get请求全过程解析

(2)使用wget命令:

wget "get请求链接"
3.2crontab发送post请求
curl -d "param1=value1&m2=value2" "post请求链接"
wget --post-data "param1=value1&param2=value2" "post请求链接"

举个真实点的例子:

wget "https://nightowl.top/user/login?username=nightowl&password=username"

得到如下结果(请不要攻击我的站点哦~):
在这里插入图片描述

*/1 * * * * wget --post-data "param1=value1&param2=value2" "http://www.baidu.com" >> /data/nightowl/post.log 2>&1

在这里插入图片描述

3.3crontab使用的补充说明

(1)如果指向的日志log文件不存在,默认会直接创建;
(2)设置请求有一定的频次限制,最高为1s,超过1s那么就取1s;
(3)如果想要设计一些复杂点的时间段执行,可以参考crondtab时间设置工具:https://tool.lu/crontab/
(4)避坑,在请求的时候特别是post请求,请求的连接需要确保后面没有多余的回车,否则执行失败;
(5)避坑,crontab里面的时间配置和打印日志配置的空格要求比较严格,使用的是单个空格,多了或者少了都不行;
(6)避坑,在请求的时候请求地址和参数需要带上""
(7)日志文件权限设置,推荐使用如下权限设置(保证安全):
在这里插入图片描述
(8)如需同时执行多个脚本,可以向上面那样,利用绝对路径指向一个.sh脚本文件,然后设置日志。需要注意的是里面需要配置环境变量,确保能够批量执行:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐