curl - PHP脚本任务优化思路或改进方案?
阿神
阿神 2017-04-11 09:44:49
[PHP讨论组]
脚本部分:
date_default_timezone_set('PRC');
require_once('canteen/MySQL.php');
$mysql  = MySQL::getInstance('localhost', 'root', '123456', 'canteens', 'UTF-8');
$user_balance = $mysql->all("SELECT id,balance FROM `user`;");

$json_data['bl'] = json_encode($user_balance);
require_once("E:\WWW\canteens\application\libraries\DESedeCoder.php");
require_once("E:\WWW\canteens\application\libraries\Curl.php");
// 上传终端数据库的最新用户金额至主数据库
$json_data['token'] = DESedeCoder::encrypt(date('YmdH'), "*****"); 
$result = Curl::send("http://canteen.com/module/resful/main/bat_balance", $json_data, 'post');
$result = json_decode($result, TRUE);
if((int)$result['status'] === 200) {
    $mysql->logs('定时更新金额ok!', 'cron.log');
}else if((int)$result['status'] === 666){
    $mysql->logs('金额更新'.$result['msg'], 'cron.log');
}else if($result['status']){
    $mysql->logs($result['status'].' '.$result['msg'], 'cron.log');
}else {
    $mysql->logs('master服务器宕机', 'cron.log');
}

// 上传终端数据库未上传至主数据库的消费记录
$send_data['token'] = DESedeCoder::encrypt(date('YmdH'), "*****");
$upt_consume = $mysql->all("SELECT id,user_id,monetary,consume_time,consume_type,card_reader_ip FROM `consum_record` WHERE upload_state=0");
$send_data['upt'] = json_encode($upt_consume);

$result = Curl::send("http://canteen.com/module/resful/main/upt_consume", $send_data, 'post');
$res_arr = json_decode($result,TRUE);
if($res_arr['status'] == 200 || $res_arr['status'] == 204) {
    $ok_id = json_decode($res_arr['ok_id'], TRUE);
    foreach ($ok_id as $val) {
        $mysql->upDate('consum_record', array('upload_state' => 1), array('id='=>$val));
    }
    if($res_arr['status'] == 200) {
        $mysql->logs('定时上传消费记录ok!', 'cron.log');
    }else {
        $mysql->logs('定时上传消费记录部分ok!', 'cron.log');
    }
}else if($res_arr['status'] == 666) {
    $mysql->logs('消费记录上传'.$result['msg'], 'cron.log');
}else if($res_arr['status']){
    $mysql->logs($result['status'].' '.$result['msg'], 'cron.log');
}else {
    $mysql->logs('master服务器宕机', 'cron.log');
}
Curl部分
private static function doRequest($is_post = 0) {
    $ch = curl_init();//初始化curl
    curl_setopt($ch, CURLOPT_URL, self::$url);//抓取指定网页
    curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
    // 来源一定要设置成来自本站
    curl_setopt($ch, CURLOPT_REFERER, self::$oriUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
    if($is_post == 1) curl_setopt($ch, CURLOPT_POST, $is_post);//post提交方式
    if (!empty(self::$data)) {
        self::$data = self::dealPostData(self::$data);
        curl_setopt($ch, CURLOPT_POSTFIELDS, self::$data);
    }
    $data = curl_exec($ch);//运行curl    
    curl_close($ch);
    return $data;
}

以上是我执行脚本的代码,具体操作流程有以下几点:

  1. 生成token

  2. 获取数据库所有用户ID金额集合

  3. token用户ID金额数据json化通过curl发送给接口api,接口更新用户最新金额数据

  4. 根据返回状态码 记录log

  5. 用户消费记录重复上面4步,不同的是,获取本机未上传的消费记录数据;
    消费记录接口,接收到消费数据的时候,插入到接口所在的数据库;而且多了一步的是,消费记录上传成功后,会返回上传成功的本机消费记录ID,根据这些消费记录ID,更新本机数据库消费记录上传状态,没上传的为0,上传成功的为1

  6. curl发送的消费记录数据量挺大的差不多在10W+字节

  7. 用户量在200+300条以下;消费记录500+1000条以下;

遇到的问题,当我执行这段脚本的时候,会出现脚本执行超时的提示,大于30s

看上面的提示内容可以得知,两次curl请求都到位了,只是在我更新本地消费记录上传状态的时候,时间不够了,当然我这个只是出现诸多问题的某一种,以后还可能会出现api接口压力过大,导致发送数据都不成功,当然这都是后话了。

只加密两个token和取出两段数据的时间可以忽略不计,大约在300~400ms之间;

解决思路或者优化思路

阿神
阿神

闭关修行中......

全部回复(2)
PHP中文网

1.设置脚本最大执行时间百度一下就很多了传送门
2.消费记录数据量挺大可以考虑分批处理或者后台队列服务,数据库操作的时候可以适当的usleep一下,释放MySQL锁。

高洛峰
  1. 修改 max_execution_time php脚本超时时间

  2. 耗时操作交给后台异步执行 例如laravel队列

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号