V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
andybest
V2EX  ›  问与答

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

  •  
  •   andybest · 2015-06-16 21:24:11 +08:00 · 3199 次点击
    这是一个创建于 3466 天前的主题,其中的信息可能已经有所发展或是发生改变。
    访问 URL: http://localhost/abc.jpg
    如果静态资源 abc.jpg 图片不存在,则转至: http://localhost:91/create.php?pic=abc.jpg

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

    Nginx 中如何实现这个需求?如果可能请简单写下配置方案,谢谢!
    20 条回复    2015-06-17 13:29:53 +08:00
    sophymax
        1
    sophymax  
       2015-06-16 21:25:37 +08:00 via iPad
    openresty
    ksword
        2
    ksword  
       2015-06-16 21:32:45 +08:00   ❤️ 1
    可以试下try_files $uri /create.php?pic=$uri =404;
    ryd994
        4
    ryd994  
       2015-06-16 23:37:26 +08:00 via Android   ❤️ 1
    其实想缓存的话并不需要这样
    动态页面直接输出不管创建文件的事
    利用fastcgi_store来保存
    利用try_files来检查

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

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

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

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

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

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

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

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

    如果是fcgi的话就用换成fcgi的指令,反正用法基本一样的
    andybest
        20
    andybest  
    OP
       2015-06-17 13:29:53 +08:00
    @ryd994 感谢!这的确是最优雅并且性能最佳的解决方案 :)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3107 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 04:58 · PVG 12:58 · LAX 20:58 · JFK 23:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.