【问题标题】:Image/Media Server That Works With Postgres与 Postgres 一起使用的图像/媒体服务器
【发布时间】:2013-12-08 03:10:09
【问题描述】:

我最近有一个 nginx + php-fpm 服务器,它提供如下图像:

header('Content-Type: image/png');
echo file_get_contents('example_image.png');
exit();

我意识到,无论图像是否被缓存,服务器上的性能都会受到巨大影响。 CPU 利用率非常高,100% 的连接数量很少。所以我开始将图像卸载到 CDN,性能立即得到提升,但在某些情况下,我仍然需要通过服务器提供图像,这让我想到了图像/媒体服务器的想法。

我的问题是,我应该使用特定类型的服务器吗?一个可以与数据库通信以查找图像位置并提供服务的设备?文件系统类型?或者我最好还是继续启动另一个 nginx + php-fpm 实例并创建一个类似 cdn 的结构实现,其中:

media.example.com 

仅指向该服务器,因此对 Web 服务器没有性能影响?

【问题讨论】:

  • 为什么不直接通过 nginx 提供图片呢?你真的需要 PHP 吗?
  • 该示例并不完全准确,因为图像与 ids 相关,因此它会查找图像位置存储在数据库中的位置,然后提供它。

标签: php postgresql image-processing nginx media


【解决方案1】:

您的问题是您将图像视为字符串而不是流。绝对没有必要使用file_get_contents() 将其全部加载到php 中并继续echo 的混乱。查找 readfile() 和 PG 相关的 LOB 功能等内容:

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;

http://php.net/manual/en/function.readfile.php

$db = new PDO('pgsql:dbname=test host=localhost', $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->beginTransaction();
$stmt = $db->prepare("select oid from BLOBS where ident = ?");
$stmt->execute(array($some_id));
$stmt->bindColumn('oid', $oid, PDO::PARAM_STR);
$stmt->fetch(PDO::FETCH_BOUND);
$stream = $db->pgsqlLOBOpen($oid, 'r');
header("Content-type: application/octet-stream");
fpassthru($stream);

http://php.net/manual/en/pdo.pgsqllobopen.php

按照类似的思路,查看与缓存控制相关的标头。无需重新发送已经在浏览器缓存中的图像。尽可能发送 304 Not Modified:

Make PHP page return "304 Not Modified" if it hasn't been modified

【讨论】:

  • 我从没想过图像是流。我一定会尝试一下,并将其与其他实现进行基准测试。
  • 您可能想要添加到答案中的是有关 X-SendFile 的信息
  • 我自己从未使用过它,所以这似乎不对。不过看起来很整洁。感谢您指出。 :-)(请随意添加您自己的答案,或编辑我自己的以确保完整性。)
【解决方案2】:

您提供这些图像的目的是什么?因为我会说如果您只是在 PHP 中提供图像,请在其中使用带有 HTML 的简单回显?

echo "<img src='image.png'>";

或者,如果您希望它从变量中显示,或者其他什么,只需在 IMG SRC= 之后的 '' 内添加“”(就像这样)

echo "<img src='" . $this . "." . $extention . "'>";

显示图像应该不会对您的服务器造成太大影响吗?但是,嘿,我不是专家。

【讨论】:

  • 他只需要提供纯图像,不需要 HTML。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-29
  • 1970-01-01
  • 2015-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多