「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战」
课程背景
- 我作为一个PHP工程师 虽然这几年PHP没落了
- 但我还是有责任补充一些PHP方面的高级教程
- 掘金粑粑开始更文奖励了 不能白白拿人家的奖励
应该发表一些高层次的PHP的技术文章别让PHP倒了
正文开始
上一章节中因为 splQuery无法在多线程中共享导致无法进行多线程数据的爬取。这一节,我们用Redis的解决方案替代上面的方案。
1 redis多线程生成任务方案
<?php
$worker_num = 20; //线程数
$num = 2822; //总页数
$base_url = "https://toutiao.sanhao.com/news-list.php?u=p%s";
//开启Redis
$to_key = 'sanhao_list';
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('admin123');
//生成目标连接
$redis->del($to_key);
for ($i=1; $i <= $num; $i++) {
$redis->lpush($to_key,sprintf($base_url,$i));
}
for ($i=0; $i < 10; $i++) {
$process = new swoole_process(function($pro) use ($to_key, $redis){
$url = $redis->rpop($to_key);
echo $url . PHP_EOL;
},false);
$process->start();
}
for ($i=0; $i < 10; $i++) {
swoole_process::wait();
}
上面代码中,我们把待完成的任务存到了redis的队列中。执行发现,每个线程都不会操作到相同的数据了,这是我们所期待的结果。
2 我们通过计算每个线程需要处理的连接请求数量,然后将数量去作为循环条件。
这就相当于我们平时的工作,工作的总量是确定的了。我们把工作量平均分配给几个员工,这样每个员工都去做一份工作,而且还不是重复工作。
$per_count = ceil($num/$worker_num);
for ($j=0; $j < $per_count; $j++) {
//todo
}
这样通过计算就算出了任务量。并对任务进行循环即可。
3 循环中添加异常处理
因为之前我们已经完成了爬取部分代码,保证程序健壮。则直接在外层加入 异常捕获的代码即可。