Steins;Lab

  • 项目
  • 折腾
  • 笔记
  • 图册
  • 杂谈
  • 文章索引 - 博主自荐博文
  • 关于/留言
Steins;Lab
某团的自留研究所
  1. 首页
  2. 学习笔记
  3. 正文

Nginx 根据 HTTP method 分流 upstream

2022年9月24日 432点热度 0人点赞 0条评论

本文是一篇简要的技术笔记。Nginx 作为反向代理,根据不同的 HTTP 方法,选择不同的 upstream。

1 if is evil

根据需求,我们很自然的想到在 location 块中添加 if 判断语句。 如

if ($request_method = POST ) {
  return 405;
}

在 location 块编排逻辑是可以完成分流的。但请务必参考 nginx 官网的警告文章:

  • If is Evil… when used in location context
  • How nginx "location if" works

文章中警告,在 location 使用多个 if 编排逻辑时,容易出现反直觉的异常现象。并提示到这不是 bug,是因为 nginx 对 if 的实现原理。这种错误甚至可以严重到 SIGSEGV。

笔者也直接在这里粘贴官方给的 evil 实例,看看是否符合读者的预期呢?

# Here is collection of unexpectedly buggy configurations to show that
# if inside location is evil.

# only second header will be present in response
# not really bug, just how it works

location /only-one-if {
    set $true 1;

    if ($true) {
        add_header X-First 1;
    }

    if ($true) {
        add_header X-Second 2;
    }

    return 204;
}

# request will be sent to backend without uri changed
# to '/' due to if

location /proxy-pass-uri {
    proxy_pass http://127.0.0.1:8080/;

    set $true 1;

    if ($true) {
        # nothing
    }
}

# try_files wont work due to if

location /if-try-files {
     try_files  /file  @fallback;

     set $true 1;

     if ($true) {
         # nothing
     }
}

# nginx will SIGSEGV

location /crash {

    set $true 1;

    if ($true) {
        # fastcgi_pass here
        fastcgi_pass  127.0.0.1:9000;
    }

    if ($true) {
        # no handler here
    }
}

# alias with captures isn't correcly inherited into implicit nested
# location created by if

location ~* ^/if-and-alias/(?<file>.*) {
    alias /tmp/$file;

    set $true 1;

    if ($true) {
        # nothing
    }
}

另外文中指出,对于复杂的 if 逻辑,可以使用 lua-nginx-module。

2 使用 map 分流 upstream

如果不使用额外的 lua 脚本,笔者在生产环境中使用 map 数据结构,参考了这篇 segmentfault 答案。

        upstream webdav_default {
                server ...;
        }
        upstream webdav_upload {
                server ...;
        }
        upstream webdav_download {
                server ...;
        }
        map $request_method $upstream_location {
            GET     webdav_download;
            HEAD    webdav_download;
            PUT     webdav_upload;
            LOCK    webdav_upload;
            default webdav_default;
        }
        server {
            location / {
                proxy_pass https://$upstream_location;
            }
        }

注:

  • map 可以和 upstream 同级共同管理,储存在 server 块之外。
  • 实际生产环境比较复杂,有各类 header 和 rewrite 等操作。避免在 locaiton 中使用 if。

3 多级 map 分流

可以使用多个连续 map, 如:

location / {
    proxy_pass http://$upstream_server_by_host;
    ...

在 upstream.conf 中:

map $host $upstream_server_by_host {
    example.com  $upstream_server_1_by_method;
    default      $upstream_server_2_by_method;
}
map $request_method $upstream_server_1_by_method {
    GET     upstream_server1;
    HEAD    upstream_server2;
    default upstream_server3;
}

参考

  • Nginx proxy by Request Method
  • Nginx map document

相关

标签: HTTP nginx 反向代理
最后更新:2022年12月13日

SPtuan

SPtuan 是一名普通的工程师,最大的愿望是度过平静的时光。 研究生时做过一点自动驾驶算法,当前对网络/后端技术比较感兴趣。

点赞
< 上一篇
下一篇 >
0 0 votes
文章评分
Subscribe
Login
提醒
guest

guest

0 评论
Inline Feedbacks
View all comments

SPtuan

SPtuan 是一名普通的工程师,最大的愿望是度过平静的时光。
研究生时做过一点自动驾驶算法,当前对网络/后端技术比较感兴趣。

  • 1 if is evil
  • 2 使用 map 分流 upstream
  • 3 多级 map 分流
  • 参考
分类
  • Uncategorized
  • 图册
  • 学习笔记
  • 库
  • 折腾
  • 杂谈
  • 瞎**扯
  • 碎碎念
  • 项目跟踪
最近评论
三五笑话 发布于 2 个月前(01月23日) 不知道说啥,开心快乐每一天吧!
rantrism 发布于 3 个月前(01月13日) 您好~我是腾讯云开发者社区运营,关注了您分享的技术文章,觉得内容很棒,我们诚挚邀请您加入腾讯云自媒体...
qw23123 发布于 4 个月前(11月22日) 你好,我也是这个问题,怎么确认板子有没有正常联网呢?板子用网线和电脑连了,可以正常使用pynq的ju...
luckf 发布于 5 个月前(11月12日) 谢谢博主的回复,的确是pynq-z2开发板的时间有问题,后来自己发现pynq板没有联网,连上网以后便...
luckf 发布于 5 个月前(11月11日) pip安装时报错信息“ERROR: Command errored out with exit st...
热门主题 & 页面
  • 100 Go Mistakes 阅读随记 - 01 Code and project organization
  • 基于openvpn的校园网ipv6免流量方案 |ipv6|校园网|免流量
  • 自建NAS,树莓派可还行? - Raspberry Pi 3B+ 开箱与实测对比
  • 在Nvidia Jetson Xavier开发者套件上启用CAN总线
  • PYNQ上手体验:以目标检测应用为例
归档
  • 2023年1月
  • 2022年12月
  • 2022年10月
  • 2022年9月
  • 2022年7月
  • 2022年6月
  • 2022年2月
  • 2021年12月
  • 2021年11月
  • 2021年2月
  • 2021年1月
  • 2020年9月
  • 2020年4月
  • 2020年3月
  • 2020年1月
  • 2019年8月
  • 2019年7月
  • 2019年5月
  • 2019年4月
  • 2019年3月
  • 2019年2月
  • 2018年12月
  • 2018年10月
  • 2018年9月
  • 2018年8月
  • 2018年5月
  • 2018年2月
  • 2018年1月
  • 2017年11月
  • 2017年9月
  • 2017年7月
  • 2017年6月
  • 2017年5月
  • 2017年4月
  • 2017年3月
  • 2017年2月
  • 2017年1月
  • 2016年12月
  • 2016年11月
  • 2016年10月
  • 2016年9月
  • 2016年8月
  • 2016年7月
  • 2016年6月
  • 2016年5月
  • 2016年4月
  • 2016年3月
  • 2016年2月
  • 2016年1月
  • 2015年12月
  • 2015年11月
  • 2015年9月

友情链接:

Blessing Studio hahaschool 绘枫和畅 魔法少女Fandy monsterx Clarke的博客 Luminous’ Home Shintaku's Blog
蓝黑的博客 haruhi.club Yida的博客 Bo2SS 涛叔 TangBao 同和君Hocassian

Steins;Lab 团子神社 zdfmc.net

steinslab.io built with ❤. Thanks for all 2015-2022.

Theme Kratos Made By Seaton Jiang

wpDiscuz