用于所有请求的PHP单例类

用于所有请求的PHP单例类,php,performance,singleton,Php,Performance,Singleton,我有一个简单的问题。我使用php作为服务器部件,并有一个html输出。“我的网站”显示其他服务器的状态。因此,流程是: 浏览器用户登录www.example.com/status 浏览器联系人:www.example.com/status PHP服务器在www.statusserver.com/status上接收请求并请求status PHP接收数据,将其转换为可读的HTML输出,并将其发送回客户端 浏览器用户可以查看状态 现在,我在php中创建了一个singleton类,它只需8秒即可访问st

我有一个简单的问题。我使用php作为服务器部件,并有一个html输出。“我的网站”显示其他服务器的状态。因此,流程是:

  • 浏览器用户登录www.example.com/status
  • 浏览器联系人:www.example.com/status
  • PHP服务器在www.statusserver.com/status上接收请求并请求status
  • PHP接收数据,将其转换为可读的HTML输出,并将其发送回客户端
  • 浏览器用户可以查看状态
  • 现在,我在php中创建了一个singleton类,它只需8秒即可访问statusserver。所以它会在8秒钟内更新状态。如果用户在其间请求更新,服务器将返回本地(在www.example.com上)存储的状态

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

    在apache服务器中,是否有可能只向所有用户提供一个实例?如果有1000个用户连接到www.example.com/status,这将解决问题

    谢谢你的任何提示

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

    我已在硬盘上使用缓存:

    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);
        }
    }
    
    公共函数getFile($filename)
    {
    $diff=(time()-filemtime($filename));
    //回声“diff:$diff
    ”; 如果($diff>8){ //回声“grösser 8
    ”; self::updateFile($filename); } 如果(是否可读($filename)){ 试一试{ $returnValue=@ImageCreateFromPNG($filename); 如果($returnValue==''){ 睡眠(1); 返回self::getFile($filename); }否则{ return$returnValue; } }捕获(例外$e){ 睡眠(1); 返回self::getFile($filename); } }否则{ 睡眠(1); 返回self::getFile($filename); } }
    这是单亲家庭的电话。我需要一个文件并将其保存在硬盘上。但是所有请求同时调用它并开始请求状态服务器

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

    据我所知,在PHP中是不可能的。但是,您当然可以序列化和缓存对象实例。

    查看据我所知,这在PHP中是不可能的。但是,您当然可以序列化和缓存对象实例。

    检查一下

    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_时间
    ,如果超过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部分中的代码才会从两个不同的进程执行,这不应该发生,因为它几乎是一个原子操作

    此外,如果您想确保您应该使用类似的方法来处理该问题,但对于此类需求来说,这将是一个超大的解决方案


    最后,8秒是一个很小的时间间隔,我会使用更大的时间间隔,至少30秒,但这取决于您的需求。

    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_时间
    ,如果超过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 l之后时,if部分中的代码才会从两个不同的进程执行