如何使用Nginx实时实现图像压缩?

时间:2017-02-09 20:51:29

标签: nginx image-compression

要解决的问题:

我在CentOS平台上。我希望压缩静态图像资源(jpg / gif / png)以优化网络服务(不调整大小),同时保留原件。

例如,

发送到http://server-A/images/image.jpg的请求将使用预配置的无损/有损参数进行动态压缩(和缓存)。

我想在Cloudflare中实现Polish功能的类似效果,但在我自己的网络服务器上。

可以使用哪些工具进行此类集成?​​

另一种想法:

是否有方法可以查看路径/originals/是否有任何更改,如果是,则执行离线图像压缩并将其输出到/compressed/路径?

2 个答案:

答案 0 :(得分:0)

.jpg图像已经是压缩的二进制格式。 nginx对您无能为力。

如果我正确理解了您的问题,则希望在保持相同质量的同时减小图像尺寸,这需要更好的压缩算法或质量较低的图像。

如果我正确理解了cloudflares的方法,那么对于lossless他们只是剥离了图像的元数据(Exif),您也可以实现这一点,但是使用nginx不能,而不是在您的asset管道中。

第二种方法lossy实现了更好的图像压缩算法,该算法也可以部署在您的asset管道中。看到类似tinypng之类的东西。

希望有帮助, G

答案 1 :(得分:0)

我认为您可以通过多种方式实现这一点。

选项 1:使用 Apache 的 PageSpeed 模块(又名 mod_pagespeed):

<块引用>

PageSpeed 模块会优化您的图片以最小化其大小,从而减少其加载时间。它们去除不可见的图像信息并应用高效压缩技术。这可以节省 50% 或更多的数据。

<块引用>

使用 PageSpeed 模块,您可以专注于您网站的内容,知道您的访问者将在使用最小带宽的情况下以最适合其设备和浏览器的格式和尺寸接收图像。

https://www.modpagespeed.com/doc/filter-image-optimize

有关如何安装它的信息可以在 in the official docs 中找到。

选项 #2:使用自定义图像压缩服务,并向其反向代理图像请求。

如果由于某种原因 Apache PageSpeed 模块无法工作,您可以设置反向代理缓存。 Nginx 会先检查缓存,得到一个 MISS,然后在内部它会从你的压缩服务请求图像,然后返回压缩图像,同时将它保存到磁盘,这样下一个请求就会命中缓存。

有关设置的详细信息如下。

您将首先创建一个带有正则表达式的 location { ... } 块,nginx 在收到对原始图像的请求时将匹配该块。

server { 
  # your standard nginx server stuff here, then:

  # when reverse proxying, nginx needs a DNS resovler defined
  # you may be able to skip this if you use an IP address instead of
  # example.com below.
  resolver               1.1.1.1 1.0.0.1 valid=300s;
  resolver_timeout       2s;
  
  location ~ ^/your/image/originals/(.*) {
       proxy_ssl_server_name on;
       proxy_pass https://www.example.com/your-custom-compression-service/$1;

       # plus we need to define some extra stuff for caching; which I put
       # in another file for modularity or reuse if later needed.
       include "/absolute/path/to/nginx-includes/location-cache.config";
    }
}

在你的“location-cache.config”(随便命名)中,你命名一个缓存,我们称之为“images_cache”:

proxy_cache            images_cache;
proxy_cache_valid      200 1d; # Cache HTTP 200 responses for up to 1 day.

# Keep using a stale cache during the short time it takes to refresh it (so
# we don't get a bunch of requests through # at the instant the cache becomes
# invalid).
# See: https://www.nginx.com/blog/mitigating-thundering-herd-problem-pbs-nginx/
proxy_cache_use_stale  error timeout invalid_header updating
                        http_500 http_502 http_503 http_504;

# "Allows starting a background subrequest to update an expired cache item,
# while a stale cached response is returned to the client."
# See: https://www.nginx.com/blog/nginx-caching-guide/#proxy_cache_background_update
proxy_cache_background_update on;

最后,在 http {...} 块中,您设置了我们上面命名的“images_cache”缓存:

proxy_cache_path
    /tmp/nginx-cache

    # Use a two-level cache directory structure, because the default
    # (single directory) is said to lead to potential performance issues.
    # Why that is default then... your guess is as good as mine.
    levels=1:2

    # A 10MB zone keeps ~80,000 keys in memory. This helps quickly determine
    # if a request is a HIT or a MISS without having to go to disk.
    keys_zone=images_cache:10m

    # If something hasn't been used in quite a while (60 days), evict it.
    inactive=60d

    # Limit on total size of all cached files.
    max_size=100m;

在您的自定义图像压缩服务(在上面的 example.com)中,您可能想要编写一个小服务(使用 Node、Python、Rust 或其他语言)来获取传递给它的 URL,从中获取 URL磁盘位置(在 .../images/originals 或任何地方),压缩并返回它。我会把它留给读者:-)