最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

PHP如何限制定時(shí)任務(wù)的進(jìn)程數(shù)量

 更新時(shí)間:2021年03月19日 09:28:25   作者:菜鳥(niǎo)尋出路  
這篇文章主要給大家介紹了關(guān)于PHP如何限制定時(shí)任務(wù)進(jìn)程數(shù)量的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

現(xiàn)在的工作中,經(jīng)常要寫(xiě)一些腳本做一些異步的操作。

一般是大量的數(shù)據(jù)修改,或者解決部分并發(fā)問(wèn)題。

為了能夠穩(wěn)定的做好數(shù)據(jù)處理,一般情況下會(huì)用定時(shí)腳本的方式。

那么問(wèn)題來(lái)了。

可能存在的問(wèn)題

當(dāng)我們處理大量數(shù)據(jù)的時(shí)候,腳本的執(zhí)行時(shí)間可能很長(zhǎng),或者重復(fù)處理某條數(shù)據(jù)(寫(xiě)錯(cuò)的情況下)。

為了避免數(shù)據(jù)的重復(fù)處理、運(yùn)行腳本過(guò)多導(dǎo)致服務(wù)器壓力過(guò)大等問(wèn)題,我們需要限制腳本的運(yùn)行數(shù)量。

如何做

思路一

查詢(xún)某種標(biāo)識(shí)的進(jìn)程數(shù)量,如果超過(guò)一定數(shù)量,則直接退出,不處理。

思路二

記錄每次的PID,可以使用 文件、redis、memcached 等來(lái)存儲(chǔ)。

當(dāng)啟動(dòng)一個(gè)新進(jìn)程的時(shí)候,去查一下這個(gè)標(biāo)識(shí)下面有哪些PID,是否還在運(yùn)行,且與當(dāng)前標(biāo)識(shí)有關(guān)系。

當(dāng)超過(guò)一定數(shù)量的時(shí)候,直接退出,不處理。

實(shí)踐

思路一實(shí)踐

這里通過(guò) linux 的 ps、grep、wc 的命令來(lái)獲取指定標(biāo)識(shí)的運(yùn)行進(jìn)程數(shù)。

<?php
/**
 * 是否可以運(yùn)行
 *
 * @param string $ident 標(biāo)識(shí)
 * @param integer $maxNum 最大運(yùn)行數(shù)量
 *
 * @return bool
 */
function canRun($ident, $maxNum)
{
  $cmd = sprintf('ps ax | grep %s | grep -v /bin/sh | grep -v grep | wc -l', $ident);
  $fp = @popen($cmd, 'r');
  $num = (int)trim(@fread($fp, 2096));
  @pclose($fp);
  return $num <= $maxNum;
}

思路二實(shí)踐

這里使用 redis 存儲(chǔ) pid 信息。

通過(guò) /proc/{pid}/cmdline 文件檢測(cè)指定進(jìn)程是否還在運(yùn)行。

<?php
/**
 * 檢查 pid 是否存活
 *
 * @param string $pid  PID
 * @param string $ident 標(biāo)識(shí)
 *
 * @return bool
 */
function isSurvive($pid, $ident)
{
  // 獲取指定pid的cmdline文件
  $cmdlinePath = sprintf('/proc/%s/cmdline', $pid);
  if (!is_file($cmdlinePath)) {
   return false;
  }
  $cmdline = trim(file_get_contents($cmdlinePath));
  // 檢查標(biāo)識(shí)是否在 cmdline 中
  return strpos($cmdline, $ident) !== false;
}

/**
 * 是否可以運(yùn)行
 *
 * @param string $ident 標(biāo)識(shí)
 * @param integer $maxNum 最大運(yùn)行數(shù)量
 *
 * @return bool
 */
function canRun($ident, $maxNum)
{
  // 假設(shè)已經(jīng)鏈接上
  $redisHandler = getRedis();
  // 定義一個(gè)key
  $key = sprintf('php:job:%s:pid', $ident);
  // 當(dāng)前的PID
  $currentPid = getmypid();
  // 將當(dāng)前的PID寫(xiě)入redis
  $redis->sAdd($key, $currentPid);
  // 獲取redis中的所有pid
  $pids = $redis->sMembers($key);
  // 遍歷pid,檢查是否有效
  foreach ($pids as $index => $pid) {
    if ($currentPid == $pid) {
      continue;
    }
    // 檢查 pid 是否還在運(yùn)行中
    if (isSurvive($pid, $ident)) {
      continue;
    }
    // 若不再運(yùn)行,則直接刪除
    unset($pids[$index]);
    $redis->sRemove($key, $pid);
  }
  return count($pids) <= $maxNum;
}


關(guān)于標(biāo)識(shí)

關(guān)于標(biāo)識(shí),可能我們?cè)谶\(yùn)行一些定時(shí)腳本的時(shí)候,統(tǒng)一的部分可能就是 php 了;或者,擁有相同標(biāo)識(shí)的腳本,我們要?dú)w為幾類(lèi)。

為了能夠?qū)崿F(xiàn)這些需求,我們可以通過(guò) php 的內(nèi)置函數(shù) cli_set_process_title 來(lái)實(shí)現(xiàn)自定義 COMMAND。
demo.php:

這個(gè)時(shí)候,我們運(yùn)行 demo.php,然后通過(guò) ps ax 可以看到如下結(jié)果:

PID  USER   TIME COMMAND
  1 root   0:09 php-fpm: master process (/usr/local/etc/php-fpm.conf)
  7 root   0:16 php-fpm: pool www
  8 root   0:15 php-fpm: pool www
  9 root   0:14 php-fpm: pool www
  10 root   0:00 sh
 663 root   0:00 sh
 690 root   0:00 {php} Job Demo
 691 root   0:00 ps ax

修改指定腳本的進(jìn)程標(biāo)題,我們就可以實(shí)現(xiàn)定義某些腳本的標(biāo)識(shí)了。

最后

沒(méi) BUG 的功能,也可能出現(xiàn) BUG,我們需要更多的思考和設(shè)計(jì)減少這類(lèi)錯(cuò)誤的發(fā)生。

到此這篇關(guān)于PHP如何限制定時(shí)任務(wù)進(jìn)程數(shù)量的文章就介紹到這了,更多相關(guān)PHP限制進(jìn)程數(shù)量?jī)?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

水城县| 瓮安县| 靖边县| 云龙县| 崇仁县| 龙山县| 龙州县| 自贡市| 江安县| 册亨县| 郴州市| 成武县| 郁南县| 枣庄市| 潜山县| 黎城县| 交城县| 类乌齐县| 邯郸县| 武安市| 平塘县| 荥阳市| 太原市| 中卫市| 夏津县| 连山| 同仁县| 华蓥市| 密山市| 洛隆县| 伊金霍洛旗| 万源市| 苏州市| 红原县| 邯郸市| 阳谷县| 宾川县| 定州市| 南溪县| 宜兰市| 随州市|