所以我有这个脚本(这对网站很重要),它每3-5分钟运行一次。
基本上,此脚本的作用是从API请求获取信息并使用新的API请求更新表。
问题是,它运行了很多API请求(大约500个?),因为我的表有500个条目。
正因为如此,每次运行此脚本时,我的CPU都会使用100%的限制。那我怎么能避免这种情况呢。如何单独限制此脚本的CPU使用率?
header('Content-Type: text/html; charset=UTF-8');
date_default_timezone_set('America/Los_Angeles');
echo memory_get_usage() . "\n";
$con = mysqli_connect("localhost", "***", "***", '***');
$result = mysqli_query($con,"SELECT * FROM **_streams");
while($row = mysqli_fetch_array($result)) {
$json_array = json_decode(file_get_contents('https://api.twitch.tv/kraken/streams/'.strtolower($row['channel'])), true);
if ($json_array['stream'] != NULL) {
// turn them into variables to prevent outside SQL injection
$displayname = mysqli_real_escape_string($con,$json_array['stream']['channel']['display_name']);
$title = mysqli_real_escape_string($con,$json_array['stream']['channel']['status']);
$game = mysqli_real_escape_string($con,$json_array['stream']['channel']['game']);
$viewers = mysqli_real_escape_string($con,$json_array['stream']['viewers']);
$preview = mysqli_real_escape_string($con,$json_array['stream']['preview']['medium']);
$followers = mysqli_real_escape_string($con,$json_array['stream']['channel']['followers']);
$date = date('m/d/Y h:i:s a', time());
mysqli_query($con,"SET NAMES utf8mb4");
mysqli_query($con,"UPDATE mybb_streams SET `online` = '1', `title` = '$title', `viewers` = '$viewers', `game` = '$game', `preview` = '$preview', `followers` = '$followers', `lastactive` = '$date' WHERE `channel` = '".strtolower($row['channel'])."'") or die("A MySQL error has occurred.<br />Your Query: UPDATE `streams` SET `online` = `1`, `title` = `$title`, `viewers` = `$viewers`, `game` = `$game`, `preview` = `$preview` WHERE channel = '".strtolower($row['channel'])."'<br /> Error: (" . mysqli_errno($con) . ") " . mysqli_error($con));
}
else {
mysqli_query($con,"UPDATE mybb_streams SET `online` = '0', `viewers` = '0' WHERE `channel` = '".strtolower($row['channel'])."'") or die("A MySQL error has occurred.<br />Your Query: UPDATE streams SET `online` = '0', `viewers` = '0' WHERE `channel` = '".strtolower($row['channel'])."'<br /> Error: (" . mysqli_errno($con) . ") " . mysqli_error($con));
}
}
echo memory_get_usage() . "\n";
?>
数据库刷新了!
答案 0 :(得分:0)
我打赌它会非常慢。对于每个流,你A)向api.twitch.tv发出一个HTTP请求(php停止所有执行,直到从api返回一个响应)然后你执行两个查询。
我只是看了同样的api,如果你先打电话给https://api.twitch.tv/kraken/streams,它会给你一个我猜测的所有流的列表。
所以执行一次调用以获取所有流然后循环访问API结果并以这种方式更新数据库。
答案 1 :(得分:0)
希望我的建议会给你一些帮助。
我的建议: 如果您使用CRON Job,那么您可以使用内存限制来解决此问题
帮助完整链接:
https://www.urbaninsight.com/2011/06/06/fixing-out-of-memory-problem-for-cron-job
https://serverfault.com/questions/295584/php-cli-memory-limit
示例代码:
<?php
if ($_SERVER['PHP_SELF'] == '/cron.php' or
(isset($_GET['q']) and $_GET['q'] == 'admin/reports/status/run-cron')) {
ini_set('memory_limit', '256M'); // Set higher value if needed
}
?>
我的另一个建议:
您需要优化MySql Innodb Performance。
提高SELECT操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引条目的作用类似于表行的指针,允许查询快速确定哪些行与WHERE子句中的条件匹配,并检索这些行的其他列值。可以索引所有MySQL数据类型。
http://dev.mysql.com/doc/refman/5.5/en/optimization-indexes.html
http://www.mysqlperformanceblog.com/2013/04/26/more-on-mysql-transaction-descriptors-optimization/
http://www.mysqlperformanceblog.com/2013/09/20/innodb-performance-optimization-basics-updated/
http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/
答案 2 :(得分:0)
答案 3 :(得分:0)
<强> ReactPHP 强>
也许您可以查看ReactPHP(https://github.com/reactphp/react),它提供了一种使用非阻塞请求和承诺的简便方法。
ReactPHP允许您在同一时间向您的API发送多个请求,而无需等待每个请求结束。
此页面提供了并行下载的示例:https://github.com/reactphp/react/blob/split/examples/parallel-download.php
<强>的MessageQueue 强>
您还可以使用像RabbitMQ(http://www.rabbitmq.com/)这样的MessageQueue来请求您的API。 看看这个博客,它提供了从简单的请求系统迁移到RabbitMQ和专业人员的示例:http://knplabs.com/blog/2012/02/03/knpbundles-now-uses-rabbitmq/