我的网站上的PHP脚本

我的网站上的PHP脚本,php,mysql,cron,Php,Mysql,Cron,所以我有这个脚本(这对网站很重要),它每3-5分钟运行一次 基本上,这个脚本的作用是从API请求中获取信息,并用新的API请求更新表 问题是,它运行了很多API请求(大约500?),因为我的表有500个条目 正因为如此,每次运行这个脚本时,我的CPU都会使用100%的节流。那我怎么才能避免呢。如何仅限制此脚本的CPU使用 header('Content-Type: text/html; charset=UTF-8'); date_default_timezone_set('America/Los

所以我有这个脚本(这对网站很重要),它每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"; 

?>
header('Content-Type:text/html;charset=UTF-8');
日期默认时区设置(“美国/洛杉矶”);
回显内存\u获取\u用法()。“\n”;
$con=mysqli_connect(“localhost”,“***”,“***”,“***”,“***”);
$result=mysqli_查询($con,“从**\u流中选择*);
while($row=mysqli\u fetch\u数组($result)){
$json\u数组=json\u解码(文件\u获取\u内容('https://api.twitch.tv/kraken/streams/“.strtolower($row['channel']),true);
如果($json_数组['stream']!=NULL){
//将它们转换为变量以防止外部SQL注入
$displayname=mysqli_real_escape_字符串($con$json_数组['stream']['channel']['display_name']);
$title=mysqli_real_escape_string($con,$json_数组['stream']['channel']['status']);
$game=mysqli_real_escape_字符串($con,$json_数组['stream']['channel']['game']);
$viewers=mysqli_real_escape_string($con,$json_数组['stream']['viewers']);
$preview=mysqli_real_escape_string($con,$json_数组['stream']['preview']['medium']);
$followers=mysqli_real_escape_字符串($con,$json_数组['stream']['channel']['followers']);
$date=date('m/d/Y h:i:sa',time());
mysqli_查询($con,“集合名称utf8mb4”);
mysqli_query($con,“更新mybb_流集`online`='1',`title`='$title',`viewers`='$viewers',`game`='$game',`preview`='$preview',`followers`='$followers',`lastactive`='$date',其中`channel`='''''.''.strtower('row['channel'])。“'))或死亡(“出现MySQL错误。
您的查询:更新`streams`SET`online`=`1`、`title`=`$title`、`viewers`=`$viewers`、`game`=`game`、`preview`=`preview``WHERE channel=`.`strtolower('row['channel'])。”
错误:(“.mysqli\u errno($con.)”)。mysqli\u错误($con); } 否则{ mysqli_查询($con,“UPDATE mybb_streams SET`online`='0',`viewers`='0'其中`channel`='0')。strtolower($row['channel'])。“”)或死亡($MySQL错误已发生。
您的查询:UPDATE streams SET`online`='0',`viewers`='0'其中`channel`='channel`'.'.''.''.strtolower($row['channel'])。
错误:(“.mysqli_errno($con)。”)。mysqli_错误($con); } } 回显内存\u获取\u用法()。“\n”; ?>

数据库刷新了!

是的,我打赌它会非常慢。对于每个流,您A)向api.twitch.tv发出一个HTTP请求(php会停止所有执行,直到api返回响应),然后执行两个查询

我刚刚看了同一个api,如果您调用first,它将给出我猜的所有流的列表


因此,只需执行一次调用,即可获取所有流,然后通过API结果循环并以这种方式更新数据库。

希望我的建议能给您一些帮助

我的建议是: 如果您使用CRON作业,那么可以使用内存限制来解决此问题

帮助完整链接:

  • 示例代码:

    <?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性能

    提高SELECT操作性能的最佳方法是在查询中测试的一个或多个列上创建索引。索引项充当指向表行的指针,使查询能够快速确定哪些行与WHERE子句中的条件匹配,并检索这些行的其他列值。我所有的SQL数据类型可以被索引

  • 我的两分钱:

    您可以使用,但不限制CPU使用,但将脚本的优先级设置为低:

    nice -n 20 php ./streams.php
    

    php

    也许您可以看看ReactPHP(),它提供了一种使用非阻塞请求和承诺的简单方法

    ReactPHP允许您同时向API发送多个请求,而无需等待每个请求的结束

    本页提供了并行下载的示例:

    消息队列

    您还可以使用诸如RabbitMQ()之类的消息队列来请求API。
    看看这个博客,它给出了一个从简单的请求系统迁移到RabbitMQ的例子,以及它的优点:

    不要再使用不推荐的函数
    mysqli\u real\u escape\u string
    。你能确定哪个进程在使用CPU吗?我在这里看不到任何会最大限度地使用多核机器的东西,所以除非你在旧的ma上运行它中文应该没问题。不过,有可能数据库在这些更新中做了一些密集的工作?可能是触发器,或者你有一个复杂的视图正在更新?你看,我的主机说我一直在达到CPU限制,不知道为什么。我知道这个脚本非常慢,但这是我获取所有频道信息的唯一方法它存储在我的数据库中。哦,我现在正在使用共享主机。我认为你达到了CPU限制,因为你有多个cron作业在同一时间执行。如果你的脚本需要30分钟运行,并且你每5分钟启动一次,那么你有6个脚本在同一时间运行……问题是,我想要得到的流是li在我的数据库中存储。我在数据库中有500多个条目。我认为一次更新所有流没有一个很好的解决方案。你可以在服务器上设置一个cron作业,在指定的时间缓慢更新每个流。然后你可以有一个手动功能,可以随时手动更新特定流。