Nginx 如何优雅的实现这个需求?

2015-06-16 21:24:11 +08:00
 andybest
访问 URL: http://localhost/abc.jpg
如果静态资源 abc.jpg 图片不存在,则转至: http://localhost:91/create.php?pic=abc.jpg

create.php 会生成 abc.jpg 并直接输出该图片
(所以下次访问会直接访问静态资源 abc.jpg 而不会再去请求 create.php)

Nginx 中如何实现这个需求?如果可能请简单写下配置方案,谢谢!
3191 次点击
所在节点    问与答
20 条回复
sophymax
2015-06-16 21:25:37 +08:00
openresty
ksword
2015-06-16 21:32:45 +08:00
可以试下try_files $uri /create.php?pic=$uri =404;
gamexg
2015-06-16 21:36:21 +08:00
ryd994
2015-06-16 23:37:26 +08:00
其实想缓存的话并不需要这样
动态页面直接输出不管创建文件的事
利用fastcgi_store来保存
利用try_files来检查

http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_store

当然,如果你需要的只是对热页面的缓存的话,fastcgi_cache会好用得多
pupboss
2015-06-16 23:45:59 +08:00
rewrite ^/(.*.jpg)$ :91/create.php?pic=$1 permanent;
cevincheung
2015-06-16 23:49:16 +08:00
难道这不是个rewrite完成的工作么?
ryd994
2015-06-17 03:15:02 +08:00
@cevincheung
@pupboss
明明就是个静态化缓存,用什么rewrite
LazyZhu
2015-06-17 07:24:45 +08:00
这个只需要try_files配合一个命名location来proxy_pass就可以了:

https://gist.github.com/LazyZhu/2cbfbeea75eae63a450e

具体参数自己修正.
gs038538
2015-06-17 08:09:27 +08:00
rewrite
重定向应该可以的。
andybest
2015-06-17 08:11:01 +08:00
@pupboss @cevincheung

rewrite 似乎无法实现当静态资源存在的时候访问静态资源,而是永远请求 create.php ,不符合需求啊似乎
andybest
2015-06-17 08:24:47 +08:00
@gamexg 非常感谢,请问 if (!-f $request_filename) 中的 !-f 是什么意思?
gamexg
2015-06-17 09:15:06 +08:00
msg7086
2015-06-17 09:32:39 +08:00
就是try_files嘛。要复杂的实现可以写lua。
我之前写过一个论坛头像CDN就是用lua比对本地和远程服务器上的写入时间,本地新就返回本地,本地和远程一样就重定向到远程CDN去。
jasontse
2015-06-17 10:24:10 +08:00
@andybest
if not file
pupboss
2015-06-17 11:16:49 +08:00
@andybest 你先判断一个404,再重定向也行

自己的项目没用过静态缓存,所以不太清楚楼上说的
cevincheung
2015-06-17 11:17:01 +08:00
ryd994
2015-06-17 12:28:58 +08:00
@cevincheung if很好玩么?if is evil,更别说用if判断文件存在了,
早就该用try_files代替的东西,各种文档吐槽无数遍,偏有半桶水: http://wiki.nginx.org/Pitfalls#Check_IF_File_Exists

fastcgi_cache 或 fastcgi_store + try_files,根据需求使用即可
ryd994
2015-06-17 12:32:10 +08:00
@LazyZhu 配合proxy_store食用,效果更佳
ryd994
2015-06-17 13:05:27 +08:00
https://gist.github.com/renyidong/f93ca0a3beed67abe02a

两种风格任选
proxy_cache 部分在内存,性能更好,适合比较简单的缓存规则
proxy_store 读的是硬盘,而且要自己删文件来实现过期,但规则可以更复杂

如果是fcgi的话就用换成fcgi的指令,反正用法基本一样的
andybest
2015-06-17 13:29:53 +08:00
@ryd994 感谢!这的确是最优雅并且性能最佳的解决方案 :)

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/199097

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX