适用于所有请求的PHP Singleton类

时间:2011-09-15 19:36:01

标签: php performance singleton

我有一个简单的问题。我使用php作为服务器部分并具有html输出。我的网站显示有关其他服务器的状态。所以流程是:

  1. 浏览器用户访问www.example.com/status
  2. 浏览器联系www.example.com/status
  3. PHP Server收到请求并在www.statusserver.com/status上询问stauts
  4. PHP接收数据,将其转换为可读的HTML输出并将其发送回客户端
  5. 浏览器用户可以看到状态。
  6. 现在,我在php中创建了一个单例类,只访问状态服务器8秒。所以它会在8秒内更新状态。如果用户请求在其间进行更新,则服务器返回本地(在www.example.com上)存储的状态。

    那不错不是吗?但后来我做了一个简单的测试并启动了5个浏览器窗口,看它是否有效。在这里,php服务器为每个请求创建了一个单例类。所以现在5个客户端请求状态服务器上的所有8秒状态。这意味着我每8秒钟拨打一次状态服务器而不是一次!

    是否有可能只向Apache服务器中的所有用户提供一个实例?如果1000个用户连接到www.example.com/status ....

    ,这将解决问题

    thx任何提示

    ============================= 编辑:

    我已经在硬盘上使用了缓存:

    public function getFile($filename)
    {
        $diff = (time()-filemtime($filename));
        //echo "diff:$diff<br/>";
        if($diff>8){
            //echo 'grösser 8<br/>';
            self::updateFile($filename);
        }
        if (is_readable($filename)) {
            try {
                $returnValue = @ImageCreateFromPNG($filename);
                if($returnValue == ''){
                    sleep(1);
                    return self::getFile($filename);
                }else{
                    return $returnValue;    
                }
            } catch (Exception $e){
                sleep(1);
                return self::getFile($filename);
            }
        } else {
            sleep(1);
            return self::getFile($filename);
        }
    }
    

    这是单身人士的召唤。我要求一个文件并将其保存在硬盘上。但是所有请求都同时调用它并开始请求状态服务器。

    我认为唯一的解决方案是一个独立的应用程序,它会在文件上每8秒进行一次更新...所有请求应该只读取文件并且nomore能够更新它。 这个独立的可能是perl脚本或类似的东西......

2 个答案:

答案 0 :(得分:3)

Php请求由不同的进程处理,每个进程都有不同的状态,没有像其他Web开发框架那样的驻留进程。您应该使用例如一些缓存直接在您的类中处理该行为。

查询服务器状态的方法应具有此逻辑

public function getStatus() {
  if (!$status = $cache->load()) {
    // cache miss
    $status = // do your query here
    $cache->save($status); // store the result in cache
  }
  return $status;
}

这样只有一个X请求才能获取实际状态。 X值取决于您的缓存配置。

您可以使用的某些缓存库:

或者您可以将结果存储在纯文本文件中,并在每次请求时检查文件本身的m_time,如果传递的时间超过xx秒,则重写它。

<强>更新

您的代码很奇怪,为什么所有sleep调用?为什么ImageCreateFromPNG不会抛出try / catch块?

你问了一个不同的问题,因为php不是一个应用程序服务器,并且无法跨进程存储状态,你的方法是正确的。我建议你使用APC(使用共享内存,因此它比读取文件快至少10倍)来共享不同进程的状态。使用这种方法,您的代码可能会变成

public function getFile($filename)
{
    $latest_update = apc_fetch('latest_update');
    if (false == $latest_update) {
      // cache expired or first request
      apc_store('latest_update', time(), 8); // 8 is the ttl in seconds
      // fetch file here and save on local storage
      self::updateFile($filename);
    }
    // here you can process the file
    return $your_processed_file;
}

使用这种方法,if部分中的代码只有在if行之后的blocked进程时才会从两个不同的进程执行,这不应该发生,因为几乎原子操作。

此外,如果你想确保你应该使用类似semaphores的东西来处理这个问题,但对于这种要求来说,这将是一个超大的解决方案。

最后imho 8秒是一个小间隔,我会使用更大的东西,至少30秒,但这取决于你的要求。

答案 1 :(得分:0)

据我所知,这在PHP中是不可能的。但是,您肯定可以序列化和缓存对象实例 查看http://php.net/manual/en/language.oop5.serialization.php