多线程curl

今天做了一个功能,后端提供一个接口,根据站点返回认证信息,很快ok。测试时要过一遍所有站点,总不能人工一个个查看吧,于是寻求解决方案。接口是post接口,所以自己写了一个jsp页面,用HttpURLConnection来访问接口,并把接口返回的数据吐到页面中。接下来用curl来访问这个jsp页面,获得数据放到文件中,再用awk进行解析。

在curl这个阶段发生问题。
url词表为url.txt,每行一个站点,直接

for line in `cat url.txt`; do curl -m 3 "http://xxxx.jsp?url=$line&type=1" >> result.txt; done

嗯,不错,很不错,很稳定。但是,太慢!第一批测试词表有6000条数据,每次curl耗时大约300ms,跑完需要大约30分钟,还可以忍受。但是后续词表越来越大,动不动就几万,几十万,这方法需要改进。
需要多线程或者说多进程操作,但是在这种循环中既用&来后台执行又执行curl方法,尝试多种方法都不可行。但下面的echo是可行的。

1
2
3
4
5
for line in `cat url.txt`; do
{
sleep 3;echo "http://xxx.jsp?url="$line"&type=1"
} &
done

然后各种google,有人建议用python,有人建议使用ab,最后找到一个命令,xargs,可以同时开启多个进程进行操作。

于是进行改造,首先要将词表进行整理,整理为http://xxx.jsp?url={host}的样子,使用到sed命令,别忘了重定向到新文件

1
2
3
4
5
6
# 在每行行首添加字符串,需要转义
sed 's/^/http:\/\/xxx.jsp?url=&/g' url.txt
# 在每行行尾添加字符串
sed 's/$/&\&type=1/g/' url.txt
# 也可以在一条命令中完成上面两个操作
sed '/./{s/^/http:\/\/xxx.jsp?url=&/; s/$/&\&type=1/}' url.txt

对于xargs我这边使用的方法如下:

< url.txt xargs -r -L 1 -P 50 curl > result_xargs.txt 

注意:如果服务器是测试机器,开的进程数不能太多,请求数太多会将服务器打挂。

备忘

今天用到许多之前没有接触的东西,备忘一下

  1. awk中调用shell命令: awk '{cmd="echo "$0; system(cmd);}'
  2. shell按行读取三种方式,其实用awk是比较简单的,但是如果遇到更复杂的操作需要这种方式
  • while的第一种方式
1
2
3
4
5
#!/bin/bash
while read line
do
echo $line
done < filename
  • while的第二种方式
1
2
3
4
5
#!/bin/bash
cat filename | while read line
do
echo $line
done
  • for
1
2
3
4
for line in `cat filename`
do
echo $line
done
  • for和while方式还有所不同
1
2
3
4
5
6
7
8
9
10
$ cat file
1111
3333 4444
$ cat file | while read line; do echo $line; done
1111
3333 4444
$ for line in $(<file); do echo $line; done
1111
3333
4444
  1. ab命令,apache出品,打压力专用。备忘,以后可能用到

参考