Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

nginx 配置之 return 的神奇用法

  在 nginx 的众多指令中 return 是我非常喜欢的一个指令。因为它自带 break 性质,受 rewrite 的影响特别小。我甚至常用它来 debug 某个 location 是否被处理。有时候一些简单的逻辑也可以直接在 nginx 层做,return 一个 JSON 字符串,减少 proxy 或 fastcgi 的处理。
  比如一个用于服务健康状态监测的 /ping 路由我们可以这么定义
location = /ping { default_type application/json; return 200 '"pong"'; }   这比访问一个真实文件要快得多,因为配置是在 nginx 启动时解析的,"pong" 这个字符串是配置文件经过 AST 解析后直接放在内存里的,所以非常快。对于健康检查有时候也有人会用 empty_gif 模块 location = /ping { empty_gif; }   empty_gif 会响应一个内存里的一像素空白 gif 图片,同样没有磁盘 IO,速度非常快。但我还是倾向于使用 return 一个 JSON,因为通常客户端处理 JSON 的成本要比处理图片低得多。除非是用于 HTML 文档中 IMG 标签(或前端代码的 new Image().src = URL)来打点统计才会使用 empty_gif。
  return 除了用于快速响应之外还定义了一些便于重定向的操作方式。比如直接 return 一个 URL 就可以直接 302 重定向到改 URL 上。具体和 rewrite 重定向的区别可以翻阅先前的文章
  最后,return 还有一个神奇的用法。当 return 一个 444 状态码时 TCP 连接会直接从服务器端被断开,客户端甚至连 http 头都接收不到。这可能已经超出了 http 的范畴,但 nginx 的代码中确实有这么一坨神奇的判断代码
  虽然这个 444 在 http 状态码里定义并做特殊处理我是拒绝的(如果可以使用一个单独的指令定义就好了),但是这个从服务器端断开连接的功能确实非常有用。比如我们要禁止 curl 请求可以这么玩
if ($http_user_agent ~ \bcurl\b) { return 444; }
  对于一些爬虫,如果我们响应一个正常的 http 状态码它可能会继续重试,只有这种强行断开才能让爬虫以为是服务器挂了而撤退。
网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^