nginx(六十)proxy模块(一)proxy_pass指令

一   proxy模块处理请求的流程

①  流程图

说明: 这里'假定'nginx从client接收的是'http协议','转发给上游'的也是http协议

备注: 后续根据'处理'请求的流程,来讲解'相关指令'

二    proxy_pass

++++++++++++++ "重点关注proxy_pass的三点" ++++++++++++++

1) dns'解析'

2) 涉及'path、query、uri'等

3) proxy_pass 中attatch_url是否存在对于'uri转码'影响

①  基本解读

说明: proxy_pass是一个'动作'指令,'不会'被继承

备注: 常见'add_header'、'proxy_paas'、rewrite模块指令可以用在'if in location'中

指令的继承机制   值指令和动作类指令

②  proxy_pass的形式  域名解析问题

​重点: 理解'proxy_pass'的构成

1)"协议[http、https]"+"://"+"域名[ip]:端口"+"option[可选]的attach_url"

2)"协议[http、https]"+"://"+"upstream_id"+"[可选]的attach_url"

注意:变量可以用在'proxy_pass'组成的'任何'一部分

++++++++'proxy_pass的形式'++++++++
 
字面值ip、'域名'、'upstream_id'、'变量[表示域名]' -->四种方式设置'上游[源站]'地址
 
1)有'变量',先'预'编译,'reload|restart'不会报错,等'客户端的请求'来了再'handle处理'

    特点: 必须使用nginx的'resolver指令'
 
    方式1: '自定义域名变量'

         # 多个'dns_server' 需要使用'空格'分割

         resolver 114.114.114.114 8.8.8.8 valid=30s; 

         # 通过set自定义变量
 
         set $target www.baidu.com;
 
         proxy_pass http://$target;
 
    方式2: '客户端传递的http变量'  --> "预定义变量"
 
         proxy_pass http://$http_target;

    应用场景: '客户端'如何控制'代理服务器'转发的'后端'服务器 -->'请求头|查询参数'

    安全: 涉及'正向代理出公网',要保证'$http_target'是白名单,只保证对'白名单'的ip开防火墙

    方式3: 裸域名,但变量在'attach_url'中,也必须使用'resolver'  --> "见下面的案例"
 
特性:服务'启动'的时候,'绕过域名检查';有'请求过来'的时候,需要'resolver'指令进行域名解析

2) 无'变量'则使用'os'的DNS解析能力

   方式:常见的'裸域名'

3) 有'变量',但是也使用'os'的DNS解析能力

   方式:使用'upstream_id',但'upstream_id'中使用'域名'  --> "特殊"

说明: proxy_pass   http://source1.wzj.com; '等价' 隐式创建上面的'upstream'

用源码分析proxy_pass、upstream、resolver

最佳实践: os的'/etc/resolv.conf'相关选项配置成和nginx的'resolver'的指令保持一致

最佳做法: 使用openresty 'resolver' 的'local=on'参数

NGINX动态DNS解析原理及源码分析

思考: 如果proxy_pass的形式同时满足'upstream_id'和'域名',哪个优先级'高'? --> "前者"

测试方法:注释'upstream nginx.wzj.com'前后'观察'现象

 

-- 对比'实验'

 

 

③   nginx dns缓存的问题

1) nginx何时使用'os的/etc/resolv.conf'? 何时使用'nginx的resolver 配置指令'?

2) proxy_pass的值有'变量'  

  [0]、常见:域名用'变量(动态域名解析)'代替,其它部分用'变量'同理 

     备注: 用变量表示'upstream_id'除外

  [1]、需要指定'resolver'指令 -->

  [2]、缺点:无法使用'upstream'模块的'健康检查、会话保持'等功能

3) proxy_pass'不使用'变量

  [1]、会使用os的'/etc/hosts或/etc/resolv.conf'进行解析

  [2]、如果'域名对应'多个'A'记录,会导致'负载不均衡',DNS单点故障 -> "解析结果成为常驻内存"

dns解析引发对proxy_pass的思考

nginx dns缓存的问题

dns解析的问题

动态和静态dns解析

+++++++++++++ "nginx关于dns的三种报错" +++++++++++++

归根结底: 用'谁'对域名进行解析

1) no resolver defined to resolve source.wzj.com --> reload不报错,'handle'时报错

2) host not found in upstream source.wzj.com     --> reload报错,os'无法'解析dns

补充场景: 或'不存在'此upstream_id

3) source.wzj.com could not be resolved          --> '定义resolver',不能解析域名

 core模块提供resolver指令   upstream模块提供resolver指令  openresty 提供的resolver指令

④  attach_url

说明: 这里的'attach_url'指的是'proxy_pass中除了协议、域名、端口的'uri

(1)案例1

测试1:  proxy_pass '不'携带 'attach_url'

 

结论: proxy_pass '不携带' attach_url,会将'client原始的url'转发给上游

(2)案例2

测试2:  proxy_pass '携带attach_url',attach_url为'/'

request_uri: '/ceshi/index.html'

location 匹配 '/ceshi/',剩余'index.html' 添加到 'attach_url --> / ' 后面

后端收到的请求: '/index.html'

(3) 案例3

+++++++++++ "解读" +++++++++++

1)request_uri: '/ceshi/hello.html'

2) location: '/ceshi/'

3) attatch_url: '/abc'

4) location匹配后,剩余的'hello.html'追加到proxy_pass的'attach_url'中 

   --> '/abchello.html'

⑤    nginx无法确认attach_url  重点

1) 某些情况下,'无法确定'请求URI中'替换'的部分,需要用到'正则'表达式

2) rewrite、proxy_pass、break '结合'使用

(1)案例1

1)原来'错误'的理解
 
 当'location'带有'~、~* [以~开头]'正则时,proxy_pass'不允许'有URI 

 URI表现: 变量、文本、或'混合'的形式
 
2) '修证后'的理解
 
如果location使用正则表达式,proxy_pass中'不能指定[裸]path',除非proxy_pass中包含'变量'
 
+++++++++  "以下是两个对比案例"  +++++++++
 
重点'关注': location中指定"正则表达式"和proxy_pass配置的"attach_url中带变量"混合场景

参考连接 

如果'location'使用'正则表达式',proxy_pass中'不能'指定裸path,除非proxy_pass中包含'变量'

重写url的案例

++++++++++++++  "扩展学习"  ++++++++++++++
 
location /abc/d {
  if ( $request_uri ~ /abc/d/(.+) ) {
    set $args $1;
  }
  proxy_pass https://backend/ef/$args;
}
 
============'等价'方式============
 
location ~ /abc/d/(.+) {
  proxy_pass https://backend/ef/$1;
}

(2)案例2

1) rewrite通过'break'改变'uri',此时'proxy_pass'的'attach_url'被'ignored'忽略

场景:proxy_pas有'attach_url',但是又要将'原始请求'转发到'后端',使用'$request_uri'变量

2)使用proxy_pass中指定的域名加上'rewrite中指定的path路径'即为转发后的url

补充解读: 先'重定向',再'proxy_pass反向代理'

  

解读: rewrite指令是在'rewrite'阶段执行,break'标志位'标示这是'最终'的'资源路径'

(3) 案例3

1)当'attach_url'中携带'变量'

2) 会用'proxy_pass中解析后的uri'替换'原始uri',作为最终转发到后端的'uri'
 
注意: 与'案例1'的差异点

案例讲解  案例学习  使用变量

POST请求经过301重定向后会变成GET请求,并且会丢失请求参数,印证报错"请求的body丢失"

⑥  proxy模块针对 proxy_pass 指令的处理

1) proxy_paas 想'改变url'
 
  [1]、通过'attach_url'+'localtion',这里假定'没有'rewrite

   1、'没有'attach_url     

   特点:将客户端'发来的 path 部分'拼接到proxy_paas中,然后发送到'上游'

   2、attach_url为'裸path'

     1、nginx 会把'解码过的'由客户端发来的 URI 里的 path 部分;

     2、'去掉'和当前 location 的'公共前缀',再进行'编码',按 'NGX_ESCAPE_URI' 来操作;

     3、然后和 proxy_pass 指令指定 的 'path 拼接',发送到上游;

   3、attach_url'带变量'    --> 将解析变量,然后直接将'解析后的 URI' 发送到上游

   说明: 带attach_url,涉及'url编码','decode解码后'传递给后端服务

  [2]、rewrite break的方式 --> 也可以'改变最终uri'或'通过?改变查询参数'或'传递#锚点'

proxy_paas带attach_url涉及decode解码   URI编码

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值