死循环或者非常大的循环程序运行一段时间后发现占用CPU和内存巨大,两个程序占用8核16G阿里ECS机器中的60%内存和CPU。
一个程序是从阿里redis中取zset数据然后消费删除。
一个程序是订阅redis中的一个消息,也是简单的消费。
$redisQueue = new WechatFollowServices();
//3600 * 26小时
$time1 = 93600;
//3600 * 24小时
$time2 = 86400;
if (config('app.push_debug') == true) {
$time1 = 70;
$time2 = 60;
}
while (true) {
$now = time();
$queues = $redisQueue->getQueues(0, 100, true);
foreach ($queues as $member => $time) {
$queue = \GuzzleHttp\json_decode($member, true);
/**
* 计算时间差,>= 26小时的数据删除
*/
$timeDiff = $now - $time;
if ($timeDiff >= $time1) {
$redisQueue->deleteQueue($member);
}
/**
* >= 24小时的推送
*/
if ($timeDiff >= $time2) {
$content = WechatPushServices::getMilPlanTemplate($queue['nickname']);
$res = app('GrpcServices')->customByOpenID([$queue['openId']], \GuzzleHttp\json_encode($content), 'news');
if ($res) {
$msg = '推送成功';
} else {
$msg = '推送失败';
}
info($this->description . ': ' . $queue['nickname'] . $msg);
//不考虑推送结果,直接删除
$redisQueue->deleteQueue($member);
unset($content, $res, $msg);
}
unset($member, $time, $queue, $timeDiff);
continue;
}
unset($now, $queues);
//测试模式下推送一个就退出
if (config('app.push_debug') == true) {
break;
}
}
初步考虑是不是程序变量的问题导致占用资源特别多。所以加上了 unset()。那么又有问题了,是unset掉呢还是将变量附空值呢?
对占用资源较大的程序您有什么优化的实践和建议?
根据一楼楼主的意见修改如下:
$redisQueue = new WechatFollowServices();
// 休眠时间
$sleepTime = 0;
// 延迟推送的时间长度 3600 * 24小时
$delayTime = 86400;
// 未处理的过期时间长度 3600 * 26小时
$expireTime = 93600;
if (config('app.push_debug') == true) {
$delayTime = 60;
$expireTime = 70;
}
while (true) {
$now = time();
$queues = $redisQueue->getQueues(0, 100, true);
if (empty($queues)) {
// 休眠两分钟
$sleepTime = 120;
}
/**
* @var int $time 关注时的具体时间
*/
foreach ($queues as $member => $time) {
/**
* 已关注的时间长度
*/
$followedTime = $now - $time;
/**
* 小于 24小时
*/
if ($followedTime < $delayTime) {
$sleepTime = $delayTime - $followedTime;
unset($member, $time, $followedTime);
break;
}
/**
* >= 26小时的数据删除
*/
if ($followedTime >= $expireTime) {
$redisQueue->deleteQueue($member);
unset($member, $time, $followedTime);
continue;
}
/**
* >= 24小时且 < 26小时的推送
*/
$queue = \GuzzleHttp\json_decode($member, true);
$content = WechatPushServices::getMilPlanTemplate($queue['nickname']);
$res = app('GrpcServices')->customByOpenID([$queue['openId']], \GuzzleHttp\json_encode($content), 'news');
if ($res) {
$msg = '推送成功';
} else {
$msg = '推送失败';
}
info($this->description . ': ' . $queue['nickname'] . $msg);
//不考虑推送结果,直接删除
$redisQueue->deleteQueue($member);
unset($member, $time, $followedTime, $queue, $content, $res, $msg);
//测试模式下推送一个就退出
if (config('app.push_debug') == true) {
break 2;
}
}
unset($now, $queues);
/**
* 开始休眠
*/
if ($sleepTime) {
sleep($sleepTime);
}
}
慕容3067478
30秒到达战场
UYOU