【问题标题】:Use non-blocking streams to paralellize REST-Api requests in PHP?使用非阻塞流在 PHP 中并行化 REST-Api 请求?
【发布时间】:2011-10-15 22:19:17
【问题描述】:

考虑以下场景:

  • http://www.restserver.com/example.php 返回一些我想在我的网络应用程序中使用的内容。

  • 我不想使用 ajax 加载它(SEO 问题等)

  • 我的页面生成需要 100 毫秒,REST 资源也需要 100 毫秒才能加载。

  • 我们假设我的网站的 100 毫秒生成时间发生在我开始使用 REST 资源之前。之后的事情可以忽略。

示例代码:

我网站的Index.php

<?
do_some_heavy_mysql_stuff(); // takes 100 ms
get_rest_resource(); // takes 100 ms
render_html_with_data_from_mysql_and_rest(); // takes neglectable amount of time
?>

网站生成大约需要 200 毫秒。

我想把它变成:

<?
Restclient::initiate_rest_loading(); // takes 0ms
do_some_heavy_mysql_stuff(); // takes 100 ms
Restclient::get_rest_resource(); // takes 0 ms because 100 ms have already passed since initiation
render_html_with_data_from_mysql_and_rest(); // takes neglectable amount of time
?>

网站生成大约需要 100 毫秒。

为了实现这一点,我考虑过使用这样的东西:

(我很确定这段代码不会工作,因为这个问题是关于如何完成这个问题,以及它是否可能。我只是认为一些天真的代码可以最好地展示它)

class Restclient {
    public static $buffer;
    public static function initiate_rest_loading() {
        // open resource
        $handle = fopen ("http://www.restserver.com/example.php", "r");
        // set to non blocking so fgets will return immediately
        stream_set_blocking($handle,0);
        // initate loading, but return immediately to continue website generation
        fgets($handle, 40960);
    }
    public static function get_rest_resource() {
        // set stream to blocking again because now we really want the data
        stream_set_blocking($handle,1);
        // get the data and save it so templates can work with it
        self::$buffer = fgets($handle, 40960); templates
    }
}

最后一个问题:

  • 这可能吗?如何实现?

  • 我需要注意什么(内部缓冲区溢出、流长度等)

  • 有更好的方法吗?

  • 这是否适用于 http 资源?

  • 任何输入都适用!

我希望我的解释可以理解。如果有什么不清楚的地方,请留言,我可以改写!

【问题讨论】:

  • 是否在开始时调用 fgets() (作为非阻塞),然后在脚本末尾循环调用它(作为非阻塞),直到返回您需要的所有内容,工作?从 PHP 文档看来, fgets() (在非阻塞模式下)将返回已经从文件中读取的任何内容,或者如果它仍在从文件中读取,则什么也不返回。因此,循环执行最终应该会为您提供数据...

标签: php api http rest stream


【解决方案1】:

“感谢任何意见”,这是我的:

  • 您想要的称为异步(您想要在“在后台”执行其他操作的同时执行某些操作)。

为了解决你的问题,我想到了这个:

  1. 在两个不同的 PHP 脚本中分隔 do_some_heavy_mysql_stuffget_rest_resource

  2. 使用 cURL“多”功能来执行同时请求。请检查:

这样,您可以同时执行两个脚本。使用 cURL 多功能,您可以同时调用 http://example.com/do_some_heavy_mysql_stuff.phphttp://example.com/get_rest_resource.php,然后在结果可用时立即播放。

这是我最初的想法,我会与您分享。也许有不同的更有趣的方法......祝你好运!

【讨论】:

  • 看起来和我想要的完全一样! +1。我只需要弄清楚我是否可以在请求运行时处理“其他” php 代码,但它应该从我到目前为止看到的示例中工作。因为他们在一个循环中获取。所以我可以在请求运行时执行我的内部“heavy_mysql_stuff”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-14
  • 2021-11-14
  • 1970-01-01
  • 2013-11-12
相关资源
最近更新 更多