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


    一   proxy模块处理请求的流程

    ①  流程图

    1. 说明: 这里'假定'nginx从client接收的是'http协议','转发给上游'的也是http协议
    2. 备注: 后续根据'处理'请求的流程,来讲解'相关指令'

    二    proxy_pass

    1. ++++++++++++++ "重点关注proxy_pass的三点" ++++++++++++++
    2. 1) dns'解析'
    3. 2) 涉及'path、query、uri'
    4. 3) proxy_pass 中attatch_url是否存在对于'uri转码'影响

    ①  基本解读

    1. 说明: proxy_pass是一个'动作'指令,'不会'被继承
    2. 备注: 常见'add_header''proxy_paas'、rewrite模块指令可以用在'if in location'

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

    ②  proxy_pass的形式  域名解析问题

    1. ​重点: 理解'proxy_pass'的构成
    2. 1)"协议[http、https]"+"://"+"域名[ip]:端口"+"option[可选]的attach_url"
    3. 2)"协议[http、https]"+"://"+"upstream_id"+"[可选]的attach_url"
    4. 注意:变量可以用在'proxy_pass'组成的'任何'一部分
    5. ++++++++'proxy_pass的形式'++++++++
    6. 字面值ip、'域名''upstream_id''变量[表示域名]' -->四种方式设置'上游[源站]'地址
    7. 1)有'变量',先'预'编译,'reload|restart'不会报错,等'客户端的请求'来了再'handle处理'
    8. 特点: 必须使用nginx的'resolver指令'
    9. 方式1: '自定义域名变量'
    10. # 多个'dns_server' 需要使用'空格'分割
    11. resolver 114.114.114.114 8.8.8.8 valid=30s;
    12. # 通过set自定义变量
    13. set $target www.baidu.com;
    14. proxy_pass http://$target;
    15. 方式2: '客户端传递的http变量' --> "预定义变量"
    16. proxy_pass http://$http_target;
    17. 应用场景: '客户端'如何控制'代理服务器'转发的'后端'服务器 -->'请求头|查询参数'
    18. 安全: 涉及'正向代理出公网',要保证'$http_target'是白名单,只保证对'白名单'的ip开防火墙
    19. 方式3: 裸域名,但变量在'attach_url'中,也必须使用'resolver' --> "见下面的案例"
    20. 特性:服务'启动'的时候,'绕过域名检查';有'请求过来'的时候,需要'resolver'指令进行域名解析

    1. 2) 无'变量'则使用'os'的DNS解析能力
    2. 方式:常见的'裸域名'
    3. 3) 有'变量',但是也使用'os'的DNS解析能力
    4. 方式:使用'upstream_id',但'upstream_id'中使用'域名' --> "特殊"

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

    用源码分析proxy_pass、upstream、resolver

    1. 最佳实践: os的'/etc/resolv.conf'相关选项配置成和nginx的'resolver'的指令保持一致
    2. 最佳做法: 使用openresty 'resolver''local=on'参数

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

    1. 思考: 如果proxy_pass的形式同时满足'upstream_id''域名',哪个优先级'高'? --> "前者"
    2. 测试方法:注释'upstream nginx.wzj.com'前后'观察'现象

     

    -- 对比'实验'

     

     

    ③   nginx dns缓存的问题

    1. 1) nginx何时使用'os的/etc/resolv.conf'? 何时使用'nginx的resolver 配置指令'?
    2. 2) proxy_pass的值有'变量'
    3. [0]、常见:域名用'变量(动态域名解析)'代替,其它部分用'变量'同理
    4. 备注: 用变量表示'upstream_id'除外
    5. [1]、需要指定'resolver'指令 -->
    6. [2]、缺点:无法使用'upstream'模块的'健康检查、会话保持'等功能
    7. 3) proxy_pass'不使用'变量
    8. [1]、会使用os的'/etc/hosts或/etc/resolv.conf'进行解析
    9. [2]、如果'域名对应'多个'A'记录,会导致'负载不均衡',DNS单点故障 -> "解析结果成为常驻内存"

    dns解析引发对proxy_pass的思考

    nginx dns缓存的问题

    dns解析的问题

    动态和静态dns解析

    1. +++++++++++++ "nginx关于dns的三种报错" +++++++++++++
    2. 归根结底: 用'谁'对域名进行解析
    3. 1) no resolver defined to resolve source.wzj.com --> reload不报错,'handle'时报错
    4. 2) host not found in upstream source.wzj.com --> reload报错,os'无法'解析dns
    5. 补充场景: 或'不存在'此upstream_id
    6. 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为'/'

    1. request_uri: '/ceshi/index.html'
    2. location 匹配 '/ceshi/',剩余'index.html' 添加到 'attach_url --> / ' 后面
    3. 后端收到的请求: '/index.html'

    (3) 案例3

    1. +++++++++++ "解读" +++++++++++
    2. 1)request_uri: '/ceshi/hello.html'
    3. 2) location: '/ceshi/'
    4. 3) attatch_url: '/abc'
    5. 4) location匹配后,剩余的'hello.html'追加到proxy_pass的'attach_url'
    6. --> '/abchello.html'

    ⑤    nginx无法确认attach_url  重点

    1. 1) 某些情况下,'无法确定'请求URI中'替换'的部分,需要用到'正则'表达式
    2. 2) rewrite、proxy_pass、break '结合'使用

    (1)案例1

    1. 1)原来'错误'的理解
    2. 'location'带有'~、~* [以~开头]'正则时,proxy_pass'不允许'有URI
    3. URI表现: 变量、文本、或'混合'的形式
    4. 2) '修证后'的理解
    5. 如果location使用正则表达式,proxy_pass中'不能指定[裸]path',除非proxy_pass中包含'变量'
    6. +++++++++ "以下是两个对比案例" +++++++++
    7. 重点'关注': location中指定"正则表达式"和proxy_pass配置的"attach_url中带变量"混合场景

    参考连接 

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

    重写url的案例

    1. ++++++++++++++ "扩展学习" ++++++++++++++
    2. location /abc/d {
    3. if ( $request_uri ~ /abc/d/(.+) ) {
    4. set $args $1;
    5. }
    6. proxy_pass https://backend/ef/$args;
    7. }
    8. ============'等价'方式============
    9. location ~ /abc/d/(.+) {
    10. proxy_pass https://backend/ef/$1;
    11. }

    (2)案例2

    1. 1) rewrite通过'break'改变'uri',此时'proxy_pass''attach_url''ignored'忽略
    2. 场景:proxy_pas有'attach_url',但是又要将'原始请求'转发到'后端',使用'$request_uri'变量
    3. 2)使用proxy_pass中指定的域名加上'rewrite中指定的path路径'即为转发后的url
    4. 补充解读: 先'重定向',再'proxy_pass反向代理'

      

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

    (3) 案例3

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

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

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

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

    1. 1) proxy_paas 想'改变url'
    2. [1]、通过'attach_url'+'localtion',这里假定'没有'rewrite
    3. 1、'没有'attach_url
    4. 特点:将客户端'发来的 path 部分'拼接到proxy_paas中,然后发送到'上游'
    5. 2、attach_url为'裸path'
    6. 1、nginx 会把'解码过的'由客户端发来的 URI 里的 path 部分;
    7. 2、'去掉'和当前 location 的'公共前缀',再进行'编码',按 'NGX_ESCAPE_URI' 来操作;
    8. 3、然后和 proxy_pass 指令指定 的 'path 拼接',发送到上游;
    9. 3、attach_url'带变量' --> 将解析变量,然后直接将'解析后的 URI' 发送到上游
    10. 说明: 带attach_url,涉及'url编码','decode解码后'传递给后端服务
    11. [2]、rewrite break的方式 --> 也可以'改变最终uri''通过?改变查询参数''传递#锚点'

    proxy_paas带attach_url涉及decode解码   URI编码

  • 相关阅读:
    TDengine 入门教程⑦——数据库管理工具 | IDEA 连接 TDengine
    java计算机毕业设计高校迎新管理系统源码+数据库+系统+lw文档+部署
    k8s 命令提示
    【数据聚类】第八章第二节:谱聚类算法之切图聚类、算法流程及其实现
    机器学习EM算法
    反射(获取成员变量,获取成员方法)
    1、数据库-ACID理论
    R语言ggplot2可视化:使用ggplot2可视化散点图、aes函数中的colour参数指定不同分组的数据点使用不同的颜色显示
    STM32F429主控TB6612驱动直流电机----解决PWM波形未输出bug
    基本计算器 [括号匹配的变形]
  • 原文地址:https://blog.csdn.net/wzj_110/article/details/128005138