IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

记我配置Nginx代理的遭遇

火丁笔记 2014-11-23 20:57:04 累计浏览 2,294 次
本机暂存

   我一直觉得自己的Nginx知识还算过得去,可是我错了,配置Nginx代理的遭遇让我苦不堪言,即便如此,我还是挣扎着记录一二,以便让后来者能够踩着我的足迹继续前进。

   说起来非常简单:某项目的搜索功能升级了,需要把请求从旧的服务代理到新的服务上面去,其中有点儿不一样的地方是参数的传递形式发生的变化,例子如下:

  • 旧:http://www.old.com/search/lamp

  • 新:http://www.new.com/search?q=lamp

  • 第一次尝试:

location ~ ^/search/(.+) {
    proxy_pass http://www.old.com/search?q=$1;
}

   可惜当测试的时候发现在错误日志里出现如下信息:

   no resolver defined to resolve …

   大概意思是说没有配置resolver指令来解析域名。我就奇怪了:印象中以前用proxy_pass的时候没配置resolver也能工作啊?带着疑问搜索了一下,发现这是一个老坑了,其原因在于如果代理地址中包含变量的话,那么必须配置resolver指令!

第二次尝试:

   因为我不太喜欢在Nginx配置文件里硬编码resolver指令,所以我想既然问题出现在变量身上,那么只要想办法把变量从代理地址中移除应该就可以了:

location ~ ^/search/(.+) {
    set $args $args&q=$1;
    proxy_pass http://www.old.com/search;
}

   可惜当我重启Nginx的时候发现出错了:

   “proxy_pass” cannot have URI part in location given by regular expression, or inside named location, or inside “if” statement, or inside “limit_except” block …

   大概意思是说在如下情况下,proxy_pass指令不能包含URI,相关情况分别是:正则表达式location;命名location;if;limit_except。本例正好用到了正则。

第三次尝试:

   既然URI的存在妨碍了我们,那么就想办法从代理地址中移除它:

location ~ ^/search/(.+) {
    rewrite . /search?q=$1 break;
    proxy_pass http://www.new.com;
}

   事不过三,我想这次应该成功了吧,可惜事与愿违,代理过后查询变量消失了!原因是正则表达式location中的变量无法直接在rewrite指令中使用。

第四次尝试:

   在QQ群里描述了一下自己悲惨的遭遇,大家都很高兴,好在有朋友提醒我试试set

location ~ ^/search/(.+) {
    set $q $1;
    rewrite . /search?q=$q break;
    proxy_pass http://www.new.com;
}

   终于工作了,眼泪哗哗的,不过历史不止一次教育我不要高兴的太早,很快我就发现编码问题,具体点来说就是location中的字符串是解码(urldecode)的,当以此做正则匹配获取查询关键字后再发起代理请求,肯定就出问题了。

第五次尝试:

   解决的关键在于数据必须是编码(urlencode)的,好在可以使用$request_uri

location /search/ {
    if ($request_uri ~ "/search/([^?]+)") {
        set $q $1;
        rewrite . /search?q=$q break;
    }

    proxy_pass http://www.new.com;
}

   三国时期,诸葛亮六出祁山无果,结果客死他乡,还好我在第五次成功了。

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 配置Nginx+uwsgi更方便地部署python应用 (累计阅读 107,164)
  2. 搜狐闪电邮箱的 Nginx/Postfix 使用模式 (累计阅读 33,895)
  3. 记录一个软中断问题 (累计阅读 16,954)
  4. 解析nginx负载均衡 (累计阅读 16,622)
  5. server日志的路径分析 (累计阅读 11,239)
  6. Nginx模块开发入门 (累计阅读 11,169)
  7. 检查nginx配置,重载配置以及重启的方法 (累计阅读 10,896)
  8. Cacti 添加 Nginx 监控 (累计阅读 10,641)
  9. fsockopen 异步处理 (累计阅读 10,343)
  10. 使用Squid缓存视频 (累计阅读 10,339)