关于 Nginx 配置的一些疑惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nameldk
V2EX    NGINX

关于 Nginx 配置的一些疑惑

  •  
  •   nameldk 2015-03-04 09:53:44 +08:00 6576 次点击
    这是一个创建于 3886 天前的主题,其中的信息可能已经有所发展或是发生改变。

    网站目录结构如下:
    /public/en.html
    /public/zh_cn.html
    /public/index.php

    之前所有的非静态资源请求都交给 index.php
    现在要把首页的请求 不走PHP了,提高下网站性能。Nginx会根据cookie值 lang=en 直接返回en.html 根据 lang=zh_cn 直接返回 zh_cn.html。如果没有cookie的话,默认返回 zh_cn.html.
    首页请求地址有3个,分别为:
    /
    /index
    /index/index
    求Nginx 配置。
    现在的Ngxin配置如下:
    location / {
    index index.php;
    if ($http_cookie ~* "lang=en"){
    rewrite ^/$ /en.html;
    rewrite /index /en.html;
    rewrite /index/index /en.html;
    }

    if ($http_cookie ~* "lang=zh_cn"){
    rewrite ^/$ /zh_cn.html;
    rewrite /index /zh_cn.html;
    rewrite /index/index /zh_cn.html;
    }

    root /www/wwwroot/public;
    try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    但是不好使啊,网上说 location里,if 和 try_files同时使用会有问题,http://wiki.nginx.org/IfIsEvil
    搞了一天了,还是没整好,好郁闷。感觉到了瓶颈了。

    38 条回复    2015-03-23 15:29:07 +08:00
    invite
        1
    invite  
       2015-03-04 10:31:43 +08:00   1
    这种设计,完全就是渣。
    mahone3297
        2
    mahone3297  
       2015-03-04 10:58:47 +08:00
    单一入口不是很好?。。。性能能提高多少?你遇到性能问题了?
    wingoo
        3
    wingoo  
       2015-03-04 11:09:49 +08:00
    这叫臆想中的性能问题
    nameldk
        4
    nameldk  
    OP
       2015-03-04 11:29:17 +08:00
    这样做的目的是让首页不走PHP了,减少PHP请求,不啥不对呢?
    nameldk
        5
    nameldk  
    OP
       2015-03-04 11:34:02 +08:00
    @invite 求不渣设计。
    @mahone3297 单一入口是不错,现在就是单一入口。不过不是得经过PHP么,现在不想走了。只为遇到攻击,首页请求很频繁,所以才想让Nginx直接吐静态页了。
    invite
        6
    invite  
       2015-03-04 11:40:27 +08:00   1
    @nameldk 你的cookie谁来生成?生成cookie的时间,顺带location已经够了。

    而且遇到攻击,靠这点来减缓,基本跟没有一样。

    先判断cookie,set变量,在try_files里用变量。
    jarlyyn
        7
    jarlyyn  
       2015-03-04 11:50:02 +08:00   1
    @nameldk 个人觉得,减少php请求意义不大,因为一般瓶颈不在php上,网速/mysql的压力会更大。php的话开个apc预编译基本不会是瓶颈。
    更靠谱的是在php里耗时/mysql的地方做缓存。

    而且个人意见,觉得语言信息靠cookie有点不太符合我的审美。
    invite
        8
    invite  
       2015-03-04 12:28:09 +08:00
    @jarlyyn

    @nameldk 而且按这个配置,所有404页面都请求到了index.php,哪来什么攻击防范功能。
    sophymax
        9
    sophymax  
       2015-03-04 12:59:57 +08:00 via iPad
    这种场景你去搜下ngx_lua模块,需要重新编译nginx ,最近很多问题都是它解决的,好吧,我们只是不喜欢nginx配置的蛋疼语法而已,http://wiki.nginx.org/HttpLuaModule
    qq286735628
        10
    qq286735628  
       2015-03-04 14:13:55 +08:00
    index参数里面,你在index.php前面加一个index.html,这样就不默认先请求index.html,没有才会请求index.php
    ryd994
        11
    ryd994  
       2015-03-04 14:28:24 +08:00
    If is evil,官方已经多次强调过了。能不用就不用。
    另外我比较喜欢利用header判断,然后302。这样会更符合http规范,如果错了,用户依然可以手动改回去。网页里的链接全部指向相同语言的对应页面,也就是说不同语言不同入口,不知道这个对你来说会不会很难实现。
    但是即使用cookie也是类似的。用cookie代替header,用try_files代替rewrite而已。Well, you know the pattern.

    map ${http_accept_language} ${index_name} {
    ~^zh.* zh_cn.html;
    ~^en.* en.html;
    default en.html;
    }
    location / {
    rewrite ^(.*)$ /${1}/${index_name}.html redirect;
    }

    未测试,但是思路应该没大问题。
    效果参考: http://www.crystalacg.com/help会根据使用的系统转向help-win或help-mac

    其实我是因为本来网站全静态不想引入动态内容罢了。如果你已经是用PHP的话我建议你继续用,这点成本应该不是瓶颈。做个timing看看哪里消耗最多和最值得优化吧。
    ryd994
        12
    ryd994  
       2015-03-04 14:35:33 +08:00 via Android
    首页请求频繁,你应当考虑的是如何缓存和如何限制不正常请求频率。遇到攻击应该研究安全设置。判断语言这点消耗,说白了是O(1)的,能有多少?哪怕你不判断语言,把这部分完全去掉,人家加一台肉鸡也就补上了。

    @sophymax Nginx配置文件本来就是配置文件,而非脚本语言。是declarative而不是imperative。这一点搞错了当然会不顺手。
    nameldk
        13
    nameldk  
    OP
       2015-03-04 15:01:05 +08:00
    @jarlyyn mysql 的查询有缓存的,首页如果直接抛静态页面,就是不想再连mysql redis。
    语言信息不靠cookie就在url体现吧,差别不大吧,只是展现形式不同。
    luw2007
        14
    luw2007  
       2015-03-04 15:16:45 +08:00
    @nameldk @jarlyyn

    首先做的是分析日志, 直接iptables 禁止攻击ip访问.
    1. 分析nginx的日志, 看看那些ip 短时间大量访问, 通过简单的linux命令行工具, awk, sort, uniq 就可以统计ip了. 阻止掉前十个ip基本就能保住了
    iptables -A INPUT -s XX.XX.XX.XX -j DROP
    2. 如果不会看日志怎么办, 发给我吧,免费分析.

    解决不掉攻击源的情况下
    1. 配置一个中文页, 等攻击过去. 英文页面纯粹是一般只是为了提升公司的颜值.
    2. 如果一个静态页面还抗不住, 怎么折腾都没辙, 技术上搞不定就给黑客掏钱吧.
    3. 黑客不要钱, 就找运营商看看能不能收费帮你们抗住流量.
    4. 运营商要价高, 那就就把域名指向baidu, 让他攻击吧.


    服务器调整优化:
    如果是自己的vps, 调优tcp 相关的系统参数 ulimit , backlog 之类的, 网上很多.

    至于优化nginx 等攻击完了再说吧. 临时改配置没多大作用.
    毕竟你总有页面访问慢. 找到了,继续攻击之.

    优化可以看看 @ryd994 写的.
    nameldk
        15
    nameldk  
    OP
       2015-03-04 15:37:45 +08:00
    @luw2007 做这个的根源还是为了防DDOS,网站被打的很厉害,扛不住了就切加速乐了。ip的话很多,肉鸡太多,有次貌似在在加速乐上还是一直打不开。网站已受到了攻击者的敲诈。
    xiaoyaoking
        16
    xiaoyaoking  
       2015-03-04 15:42:43 +08:00 via Android
    @nameldk ddos 打的不是ip么?
    luw2007
        17
    luw2007  
       2015-03-04 16:13:43 +08:00
    肉鸡多不是关键. 分析日志照样可以挡住他的ip.
    你先全站只放一个首页吧. 接下来的事情就是看idc了.
    最大的问题:
    @xiaoyaoking idc的网络带宽才是问题吧, ddos 占满带宽, idc会直接拔网线.
    jarlyyn
        18
    jarlyyn  
       2015-03-04 16:14:44 +08:00
    @nameldk 缓存又不是只有mysql,redis.
    直接存成文件也可以啊,和nginx跑比可能也就是多跑了遍php而已。
    说实话,真的是文件还未必比从redis里取快吧?
    我也被攻击过。被攻击的时候最怕的就是带宽跑满。
    http://v2ex.com/t/145842#reply80
    你的index.php总不可能比yii+我写的一堆到处套的模块重吧?
    有缓存的话mysql根本没压力的。
    哪怕是文件缓存,就算阿里云的烂IO也是妥妥的。
    jarlyyn
        19
    jarlyyn  
       2015-03-04 16:17:50 +08:00
    @luw2007 我上次被人打是refnece为网站首页,行为为下载首页所有图片,一天9000多ip的攻击。
    http://v2ex.com/t/145842
    luw2007
        20
    luw2007  
       2015-03-04 16:20:08 +08:00
    nginx + 静态文件 抗攻击还是可以的.
    前提是vps配置的当. 不然一个1024 can not open files 就让你崩溃.

    @jarlyyn 能做的就是拼封ip的速度, 如果可以分钟级别封ip, 剩下的就是看idc了.
    至于正常业务, 攻击了之下肯定用不了, 赶紧切换个备用域名/服务器 临时用着.
    luw2007
        21
    luw2007  
       2015-03-04 16:26:30 +08:00
    nginx 模块limit_zone与limit_req_zone, 这个不知道效果如何, 楼主可以试试看(至少不用分析日志什么的)

    @jarlyyn 上面那个模块应该适合你们那种. 资源限制.
    jarlyyn
        22
    jarlyyn  
       2015-03-04 16:38:08 +08:00
    @luw2007
    基本上很难判断出来哪个是垃圾攻击ip,哪个不是。日志我也分析过,频率都很低。我都怀疑是不是做了个隐藏iframe嵌在了某个访问量很大的网站里。
    想想其实只有做js跳转+定期调整临时域名才相对靠谱点啊。
    luw2007
        23
    luw2007  
       2015-03-04 16:45:36 +08:00
    @jarlyyn js跳转不解决你的问题, 毕竟图片路径在那里, nginx rewrite 替换掉图片路径中的父目录,让 之前的外链都死掉.
    如果iframe , 看来源url就可以直到怎么过来的.
    GuangXiN
        24
    GuangXiN  
       2015-03-04 18:17:54 +08:00
    不过PHP解释器是能提升不少性能的,我压过nginx,一个Hello world页面,如果后缀是.html不过PHP解器,能得到8000+ rps,如果改后缀名为.php过PHP解释器,就马上降到4900+rps
    nameldk
        25
    nameldk  
    OP
       2015-03-04 23:18:29 +08:00
    @jarlyyn 之前也用过Yii,现在感觉有点重,启动个框架就加载好多文件。感觉文件缓存要比redis缓存强,之前项目里实践过。缓存 内存级xcache>文件>redis. redis的话还得来一次连接,当然也可以做长连接,但远没文件高效。
    @luw2007 没有做过日志的IP分析,不过运维同学说IP很多,满世界都有,有段时间攻击较猛烈加速乐都扛不住了,直接不扛了,把请求直接丢给我们了,于是我们就挂了。
    现在的做法还是拿程序生成静态页,到Nginx直接丢静态页面。
    nameldk
        26
    nameldk  
    OP
       2015-03-04 23:24:59 +08:00
    @jarlyyn 我们受的攻击都是直接上G的。。
    luw2007
        27
    luw2007  
       2015-03-04 23:40:09 +08:00
    @nameldk 求域名,帮看看。
    nameldk
        28
    nameldk  
    OP
       2015-03-05 09:32:08 +08:00
    luw2007
        29
    luw2007  
       2015-03-05 10:16:22 +08:00
    @nameldk 看上去目前访问还行. 静态资源都分到二级域名了.

    让运维同学看日志, 确认正常用户的访问阀值. 设置下 模块limit_zone与limit_req_zone,
    测试机器上用压力测试工具跑下压力看看.
    jarlyyn
        30
    jarlyyn  
       2015-03-05 11:24:12 +08:00
    @nameldk Yii本来就很重,我改的模块后就更重了,这个不提了……
    redis需要链接那就是php本身的锅了,要不换nodejs?
    感觉要优化自然是哪里不足优化哪里了。
    相对而言,php本身应该只影响到内存和cpu占用。且不说个人认为这不是最大的瓶颈。这往往也是最好解决的方案,大不了内网多几个服务器,做一个负载均衡就可以了。
    而之所以我觉得觉得cookie不美。
    除了cookie需要更多的解析/处理步骤,逻辑更复杂外。
    我最喜欢的多语言版本切换是通过域名来的。
    哪怕是在同一个服务器。
    这样在dns这一步就可以开始分流了。
    都仅仅是个人意见,肯定没有受到攻击的你了解清楚。

    而且说实话,打首页我觉得毫无价值,首页是最容易缓存的地方。
    真的要打,打搜索,登录,忘记密码之类,ip多的时候才真心蛋疼。
    desperatecat
        31
    desperatecat  
       2015-03-05 11:24:40 +08:00
    nameldk
        32
    nameldk  
    OP
       2015-03-05 23:34:55 +08:00
    @jarlyyn 不知道对方是怎么想的,一直打的首页,可能首页的链接地址不会变,可能是其他原因。因为首页打不开,其他的页面部分是可以访问的。多语言版本当初没想太多,只是觉得cookie简单,种个cookie方便记住用户的选择。域名的话感觉让不同的模块瞳子域名比较合适。
    @luw2007 回头看下,个人对Nginx的各种模块不是太熟,这回可以好好看看。。
    @desperatecat 这个是正则表达式不严谨的问题。。。

    @ryd994 之前没用过map,这个指令不错,感觉可以代替if。但是为啥rewrite后 首页会404了
    rewrite ^/$ $index_name; 还有rewrite和try_files同时用没问题吧?
    我想 map 根据cookie确定首页lang,通过rewrite 首页 指向静态页。再通过 try_files 把其他请求丢给index.php
    ryd994
        33
    ryd994  
       2015-03-05 23:53:24 +08:00 via Android
    @nameldk 是因为$index_name没有开头的/吧,看errorlog
    没试过rewrite和try_files同时用,一般没必要
    单独给首页开个location会好点
    location = / 这样就会只精确匹配首页了
    ryd994
        34
    ryd994  
       2015-03-05 23:57:19 +08:00 via Android
    @nameldk 还有,最重要的:缓存做了没有?频率限制作了没有?这两条没做,怎么优化都不会有用。
    nameldk
        35
    nameldk  
    OP
       2015-03-06 19:09:07 +08:00
    @ryd994 确实是开头没写/,看errlog发现了。

    同时发现了个Nginx比较好的教程: http://blog.sina.com.cn/s/articlelist_1834459124_0_1.html
    ryd994
        36
    ryd994  
       2015-03-06 19:26:29 +08:00
    @nameldk 这个我以前看过,作为入门是不错,对于语法和变量。
    agentzh就是rewrite模块的主要作者,lua模块也有很多贡献,是大牛。
    不过现在再看,其实感觉这两个模块于Nginx哲学其实不太合拍(纯静态,纯声明)。
    作为Nginx功能的补充很好,对于cdn之类的应用非常有用,但过度依赖就会出问题。

    指令执行顺序什么的不必太纠结,不要钻这个牛角尖。如果你发现你需要纠结指令执行顺序的话,说明这个工作实际并不适合nginx(尽管可以写出来,而且性能很不错,但是有其他更方便的解)。熟悉执行阶段的关系的话,可以快速排除一些不切实际的想法,而不是写了半天配置就是不行。

    如果你英文过得去的话,我最建议的还是官方文档:
    http://nginx.org/en/docs/beginners_guide.html
    http://nginx.com/resources/admin-guide/
    看过之后就能写出不错的配置。要进一步调优就去啃reference里用到的模块的所有指令好了。
    nameldk
        37
    nameldk  
    OP
       2015-03-07 11:15:29 +08:00
    @ryd994 感谢!
    最终搞好了:
    1. nginx.conf 中的http 块添加:
    map $cookie_lang $page_lang {
    zh_cn zh_cn.html;
    zh_tw zh_tw.html;
    en en.html;
    default en.html;
    }
    2.
    location / {
    index index.php;
    root /www/wwwroot/public;

    rewrite ^/index/index$ /${page_lang};
    rewrite ^/index$ /${page_lang};
    rewrite ^/$ /${page_lang};

    try_files $uri $uri/ /index.php?q=$uri&$args;
    }
    其实配置挺简单的
    最关键的还是变量的处理,用map代替了if,之前一直不知道有map。
    取cookie的值可以用 $cookie_变量名。
    写rewrite时 正则要严谨。
    尽量不用if 挺坑。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5229 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 07:14 PVG 15:14 LAX 00:14 JFK 03:14
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86