热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【译】Ngnix实现一个缓存和缩略处理的反向代理服务器

一两个月前,我决定从我的站点中移除Varnish,并用Nginx内置的缓存系统替代它。我本来已经在我的python站点上用了nginx来反向代理

一两个月前,我决定从我的站点中移除Varnish ,并用Nginx内置的缓存系统替代它。我本来已经在我的python站点上用了nginx来反向代理,所以摆脱Varnish意味着少了一个麻烦。我花了好几天时间阅读怎样配置nginx的缓存,翻遍了我的python站点的不同的配置文件(是的,很讽刺)。在阅读过程中我标记了一些有趣的nginx的模块,这中间就有 Image Filter module(图像过滤处理模块)。

我觉得结合nginx的反向代理,缓存和图像过滤处理三大模块来为我托管在S3上的图片来创建一个缩略图服务器会很优雅。如果你仔细的查看下面的(甚至整个站点的)标签,你就可以看到nginx实战了。

clipboard.png

在本文中,我将描述我是怎样配置nginx来有效安全的为S3上的图片产生缩略图。作为额外奖励,我也会描述我是怎样使用 Secure Links module (安全链接模块)来防止人们恶意使用该服务器产生缩略图。

准备开始

为了让不同部分能协同工作,你的nginx需要编译进图像滤波,代理和安全链接三个模块。你可以通过nginx –V 来检查你所具有的模块。如果你使用的Ubuntu(Debian也行),你可以很轻易的安装其它任意的nginx模块(apt-get install 命令)。

一旦nginx准备好了,我们可以开始配置nginx了。

配置

首先需要申明的是我们的代理缓存。这个申明位于nginx.conf文件的http部分并且描述了基于文件的缓存所在,该缓存将会存储我们产生的缩略图。因为一次缓存未命中即意味着要从S3服务器上获取完整的图并且改变它的大小,我们希望配置缓存足够大以使其能包含我们大部分的缩略图。对于我的站点,我估计200MB足够了。

为了确定你的缓存,把下面的代码添加到nginx配置文件的http部分的某个地方:

# Nginx will create a cache capable of storing 16MB of keys and 200MB of data.
proxy_cache_path /tmp/nginx-thumbnails levels=1:2 keys_zone=thumbnail_cache:16M inactive=60d max_size=200M;

现在我们需要说明两个服务器定义:一个缓存服务器和一个调整大小服务器。后者将作为S3的反向代理,产生并提供调整大小后的图像。缓存服务器位于调整大小服务器的前面,缓存并提供调整大小后的图像。虽然我不认为必须要两个服务器,因为我的站点访问量并不是特别大,但在谷歌了一下后,我看见的一些文章表明,就是应该这样。

缓存服务器

缓存服务器会暴露给公共访问(我的位于m.charlesleifer.com)。因为该服务器的唯一任务就是缓存从调整大小服务器获得的响应,所以配置相当简单。下面是我的配置:

server {listen 80;server_name m.charlesleifer.com;location / {proxy_pass http://localhost:10199;proxy_cache thumbnail_cache;proxy_cache_key "$host$document_uri$is_args$arg_key";proxy_cache_lock on;proxy_cache_valid 30d; # Cache valid thumbnails for 30 days.proxy_cache_valid any 15s; # Everything else gets 15s.proxy_cache_use_stale error timeout invalid_header updating;proxy_http_version 1.1;expires 30d;}
}

无论何时缓存服务器得到一个请求,“thumbnail_cache”将首先被检测。如果没找到匹配项,那就将请求转发至调整大小服务器(运行在本地localhost)。它返回有效的响应,缓存服务器将缓存该响应30天,其它任何东西都只缓存15秒。

调整大小的服务器

所有有趣的事情都在调整大小服务器。它的任务是从S3上获得图片并基于URL上的参数实时调整图片大小。另外,该服务器会检查每个请求的安全秘钥以防止其他人随意产生缩略图。

因为该服务器配置有几个不同的部分,所以让我们从我们已经见过的部分开始:代理

server {listen 10199;server_name localhost;set $backend 'your.s3.bucket_name.s3.amazonaws.com';resolver 8.8.8.8; # Use Google for DNS.resolver_timeout 5s;proxy_buffering off;proxy_http_version 1.1;proxy_pass_request_body off; # Not needed by AWS.proxy_pass_request_headers off;# Clean up the headers going to and from S3.proxy_hide_header "x-amz-id-2";proxy_hide_header "x-amz-request-id";proxy_hide_header "x-amz-storage-class";proxy_hide_header "Set-COOKIE";proxy_ignore_headers "Set-COOKIE";proxy_set_header Host $backend;proxy_method GET;
}

这里除了告诉我们该服务器如何与S3通讯外并没有多余的其他内容,所以我们继续看下一部分。接下来要配置的是nginx的图像滤波模块。只需要几个指令,其中一些我们会定义到服务器级别。

下面是代理设置,添加如下的图像滤波模块:

server {# ...image_filter_jpeg_quality 85; # Adjust to your preferences.image_filter_buffer 12M;image_filter_interlace on;
}

最后,我们定义一个代码块,完成如下功能:

  1. 检查形式合法的URL
  2. 校验请求的签名
  3. 从URL中提取图片大小参数
  4. 从S3获得图像并把它载入 image_filter_buffer
  5. 调整图片大小并响应

第二项相当有趣。一篇类似的文章的作者使用Lua来校验请求的签名,但那样好像步骤比较繁琐。 Nginx的 secure_link 扩展相当容易使用。

secure_link模块原理是:用被请求的图片的URL和只有你的app知道的密钥串连接起来的串来产生一个哈希(hash)。由于hash长度扩展,我们最后附加我们的密钥而不是预先考虑它。因为你知道秘钥,所以无论何时你想在你的应用中展示图片缩略图时你都可以产生有效的hash。

下面是配置的最后一部分:

server {# ...error_page 404 =404 /empty.gif;location ~ ^/t/([\d-]+)x([\d-]+)/(.*) {secure_link $arg_key; # The hash is stored in the `key` querystring arg.secure_link_md5 "$uri my-secret-key";if ($secure_link = "") {# The security check failed, invalid key!return 404;}set $image_path '$3';image_filter resize $1 $2;proxy_pass http://$backend/$3;}
}

这就是所有的。

产生hash

如果你使用python,下面是我写的代码用以在特定URI下产生hash:

import base64
import hashlibdef thumbnail_url(filename, width, height='-'):uri = '/t/%sx%s/%s' % (width, height, filename)md5_digest = hashlib.md5(uri + ' my-secret-key').digest()key = base64.b64encode(md5_digest)# Make the key look like Nginx expects.key = key.replace('+', '-').replace('/', '_').rstrip('=')return 'http://m.charlesleifer.com%s?key=%s' % (uri, key)

感谢阅读

感谢你花时间阅读这篇文章,我希望你找到了乐趣。请留下评论,我会尽力回答。如果你发现了我上面的说明有什么错误也请让我知道,我会更新本文。



推荐阅读
  • 本文探讨了Go语言(Golang)的学习价值及其在Web开发领域的应用潜力,包括其独特的语言特性和为什么它是现代软件开发的理想选择。 ... [详细]
  • Linux环境下PostgreSQL的安装、配置及日常管理
    本文详细介绍了在Linux环境下安装、配置PostgreSQL数据库的过程,包括环境准备、安装步骤、配置数据库访问以及日常服务管理等方面的内容。适合初学者和有一定经验的数据库管理员参考。 ... [详细]
  • 本文详细介绍了MySQL 5.5及以上版本中事务管理的全过程,包括事务的启动、设置、锁机制以及解锁方法,旨在为开发者提供一个清晰、全面的操作指南,避免因网络资料分散而导致的学习障碍。 ... [详细]
  • ANSI最全介绍linux终端字体改变颜色等ANSI转义序列维基百科,自由的百科全书由于国内不能访问wiki而且国内关于ANSI的介绍都是简短的不能达到,不够完整所以转wiki到此 ... [详细]
  • 浏览器、中间件与服务器的交互机制
    本文详细探讨了浏览器、中间件和服务器之间的交互过程,特别是HTTP请求的完整流程,包括DNS解析、TCP连接建立及数据传输等关键步骤。 ... [详细]
  • Python安全实践:Web安全与SQL注入防御
    本文旨在介绍Web安全的基础知识,特别是如何使用Python和相关工具来识别和防止SQL注入攻击。通过实际案例分析,帮助读者理解SQL注入的危害,并掌握有效的防御策略。 ... [详细]
  • 解析 HTTP 头 'Vary: Accept-Encoding' 的作用与重要性
    本文详细探讨了 'Vary: Accept-Encoding' HTTP 头的作用,即指导缓存系统(如代理服务器和 CDN)根据不同的编码需求存储和提供适当的资源版本,确保不同类型的客户端能够接收到适合自己的内容。 ... [详细]
  • 本文深入探讨了分布式文件系统的核心概念及其在现代数据存储解决方案中的应用,特别是针对大规模数据处理的需求。文章不仅介绍了多种流行的分布式文件系统和NoSQL数据库,还提供了选择合适系统的指导原则。 ... [详细]
  • 本文详细介绍了Oracle数据库的基本架构,包括数据文件和内存结构的概念。文章重点解释了Oracle实例的组成部分,如系统全局内存区域(SGA)和后台进程,以及客户端进程与服务器进程的交互方式。此外,还探讨了SGA中的共享池、库高速缓存、锁存器及SGA缓冲区缓存等关键组件的功能和运作机制。 ... [详细]
  • 增强Tomcat安全性:有效防止后台攻击
    在构建可靠的系统架构时,确保安全是至关重要的一步。本文将重点探讨Tomcat这一流行的开源Web应用服务器的安全配置,以帮助开发者和运维人员提高其应用程序的安全性。 ... [详细]
  • CentOS 7.4 KVM虚拟化平台搭建指南
    本文详细介绍了如何在CentOS 7.4系统上搭建KVM虚拟化平台,包括环境准备、网络配置、KVM安装与管理等步骤,适用于希望利用KVM进行虚拟化部署的技术人员。 ... [详细]
  • 开发笔记:Mongodb副本集集群搭建 ... [详细]
  • 2023年最新:PHP本地端口配置详解
    本文详细介绍了PHP在不同环境下的本地端口配置方法及常见问题解决方案,帮助开发者更好地理解和配置PHP端口。 ... [详细]
  • 地理信息、定位技术及其在物联网中的应用
    地理位置信息是物联网系统中不可或缺的关键要素,它不仅提供了物理世界的坐标,还增强了物联网应用的实用性和准确性。本文探讨了位置服务的基本概念、关键技术及其在物联网中的重要作用,特别介绍了定位技术的最新进展。 ... [详细]
  • 深入解析ZooKeeper:Java组件化开发必备技能
    本文详细介绍了ZooKeeper作为分布式服务协调框架的核心功能与应用场景,包括其数据一致性解决方案、数据结构特点、监听通知机制及选举机制等,帮助开发者更好地理解和应用ZooKeeper。 ... [详细]
author-avatar
KisS汐唲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有