Nginx
Nginx 转发规则
在处理转发的时候,如果location后面 直接跟 /path,那么就会按path匹配,以及匹配/path后的其他地址。
但如果使用 location = /path ,那么就精确到只匹配/path
如果location 后面跟 ~ 那么再后面可以跟正则,并且可以用()进行分组,方便在location内部使用分组的结果进行处理。需要注意的是,此时是区分大小写的。比如下面的示例,就是将所有/zts/的请求,转发到目标地址的/
如果location后面跟 ~* 那么是不区分大小写的正则
默认情况下location里的=优先级最高,其次是是最长prefix.
有关Nginx 转发原理
如果 proxy_pass 后面跟的是域名(可以包含端口),但没有包含路径,注意,哪怕只有一个 / 也叫做路径,比如这个格式: http://127.0.0.1:8080; 而不是这个格式 http://127.0.0.1:8080/;那么location 后面的 /path/to/path,只要路径匹配,则将原来的路径追加到 proxy_pass 的地址后面。示例,访问 http://nginx/api 这个地址,则会被转发到 http://127.0.0.1:8080/api 这里,包括/apixxx 以及/api/xxx,以及/apixxx?id=xxx 都会转发
但是,如果proxy_pass 后面跟了路径,则 location 后面的路径会被 proxy_pass 地址的路径替换。示例:访问 http://nginx/api,实际访问地址是 http://127.0.0.1:8080/;如果访问的是 http://nginx/apixxxx ,则实际路径是 http://127.0.0.1/xxxx,如果访问的是 http://nginx/api/xxxx ,则实际路径是 http://127.0.0.1//xxxx。主要关注的是 /api 被替换成了 /。同时,这种方式,如果路径里带了? 参数,则不会转发到proxy_pass的地址上。
指定 dns 解析并转发
在Nginx的配置中,可以在 http {} 区块中指定dns resolver,这样在nginx中配置的转发域名,将会用这个dns做解析
有关 rewrite 修改路径
在 server {} 区块中,如果通过 set 设置了变量 (在设置变量的时候,会强制 dns 解析),那么可以用 rewrite 模块,将 某一个路径,替换为另外一个路径,这里也支持正则,然后在 proxy_pass 的时候,指定请求转发的具体位置.比如下面的配置,则表示请求 http://nginx/gw1/hash/aa/bb/cc?dd=ee 转发到 https://BACKEND_URL_ADDRESS/aa/bb/cc?dd=ee
注意上述 rewrite 后面的proxy_pass 的地址,是不包含路径的,实际情况是:即使包含了路径,那么由于用了rewrite模块,也会被忽略。
学习资料
https://xuexb.github.io/learn-nginx/example/proxy_pass.html#url-%E5%8F%AA%E6%98%AF-host
Nginx upstream的路由
nginx upstream支持 hash, ip hash, least_conn 等负载均衡算法,如果想要让某一个业务的流量,固定到达后端,我们可以使用 sticky cookie的方式,这样客户端只要带上这个cookie,就能到达同一个后端。但是也可以通过自定义的header来做路由。一个简单示例如下:
在上述使用中,通过 curl 的时候,带上header名字就可以。需要注意:在map里是http_开头,并且变量是下划线,但实际header是中横线
如果是使用 k8s 的 nginx ingress(k8官方的那个,并非f5的),配置起来就更简单了
nginx map 变量
在nginx中,如果想要将某一个header存到变量里,比如 biz-team (注意是中横线),那么在map里要用 $http_biz_team
在 nginx 中通过判断访问的path,决定转发路径
Nginx proxy_pass保留域名
当nginx的proxy_pass要转发到后面多个域名的时候,如果访问的地址必须要求Host是一致的(比如做了SNI),但最前端域名又与upstream域名不一致。那么可以使用两层proxy_pass解决。为了不占用过多端口,在内层proxy_pass的监听中,可以监听一个unix socket.
最后更新于