🧑‍🏫
liualexiang
  • Introduction
  • Azure
    • AKS Basic
    • AKS Spark
    • AZ ACR SYNC
    • Azure CMI SDWAN
    • Azure LB DeepDive
      • Azure LB DeepDive
    • Azure Service Principal Basic
    • Azure Internal VM Network Connectivity
      • Azure Internal VM Network Connectivity
    • Azure Cli Build
    • Azure Vm Memory Monitor
  • Blockchain
    • BTC
  • CRISPR
    • 使用Parallel_Cluster提升CRISPA效率
  • OpenSource
    • ElasticSearch
      • ES Get Started
      • ES Search Query
      • Kibana 可视化
      • Logstash配置
    • Ansible 基础
    • Infra As Code
      • Pulumi Get Started
      • Terraform Basic
    • ZooKeeper 基础
    • RPC与REST
    • 使用Python申请大量内存测试
    • 使用TPC_DS产生压测数据
    • Superset
      • Superset部署手册
    • 代码扫描
    • Git
      • Git Basic
      • Github Action Basic
      • Gitlab与AzureAD集成
      • Gitbook 基础教程
    • K8S
      • enter_node
      • K8s X509 Client Cert
      • K8s Basic
      • K8s Oidc
      • Docker 基础
      • helm基础
      • K8S_Secrets管理
      • 深入了解K8S
      • 混沌工程
      • Istio
      • 生态
      • CRD开发
      • k8s网络
    • Cloud_Custodian
    • Jenkins Basic
    • Nginx
    • ETCD
    • 正则
    • VictoriaMetrics
    • Kafka
  • MySQL
    • MySQL 调优
  • Linux
    • SSH Tunnel 上网
    • 内存管理
    • 在Linux系统中通过LUKS加密磁盘
    • 量子计算 Basic
    • IO多路复用
    • Iptables
    • tmux和screen
    • Systemd
    • OS 基础
    • jq基础
    • yum
    • neovim
  • Web
    • Html Css
    • Web部署
    • 缓存
  • Programming
    • 算法
      • 返回list中最大生序子序列长度
    • Python技巧
      • Python的语法糖
      • Python常用装饰器
      • AsyncIO基础
      • 自动化测试pytest
      • python中的下划线
      • 面向对象
      • Python的坑
      • Python配置文件管理
      • HTTP Stream Response
      • Python项目管理
    • 设计模式
      • 设计模式
      • 面向对象的思想
      • 编程概念
    • Go
      • Go 基础
      • Go常用功能
      • 结构体入门
    • 前端
    • Vue
    • NodeJS
  • Math
    • 多项式插值法
  • Security
    • HTTP常见攻击
    • 加密与签名
    • RSA
    • ECDSA
  • Solidity
    • Solidity基础
    • Blockchain Testnet Faucet
  • Tools
    • 视频处理ffmpeg
    • IDE配置
    • iTerm2美化
    • 密码管理
    • FRP配置
    • 工具集
由 GitBook 提供支持
在本页
  • Nginx 转发规则
  • 有关Nginx 转发原理
  • 指定 dns 解析并转发
  • 有关 rewrite 修改路径
  • Nginx upstream的路由
  • nginx map 变量
  • Nginx proxy_pass保留域名
  1. OpenSource

Nginx

Nginx 转发规则

  1. 在处理转发的时候,如果location后面 直接跟 /path,那么就会按path匹配,以及匹配/path后的其他地址。

  2. 但如果使用 location = /path ,那么就精确到只匹配/path

  3. 如果location 后面跟 ~ 那么再后面可以跟正则,并且可以用()进行分组,方便在location内部使用分组的结果进行处理。需要注意的是,此时是区分大小写的。比如下面的示例,就是将所有/zts/的请求,转发到目标地址的/

  4. 如果location后面跟 ~* 那么是不区分大小写的正则

	location ~ ^/path/(.*) {
		set $backend BACKEND_URL;
		proxy_pass http://$backend/$1;
	}
  1. 默认情况下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 都会转发

location /api {
	proxy_pass http://127.0.0.1:8080;
}

但是,如果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的地址上。

location /api {
	proxy_pass http://127.0.0.1:8080/;
}

指定 dns 解析并转发

在Nginx的配置中,可以在 http {} 区块中指定dns resolver,这样在nginx中配置的转发域名,将会用这个dns做解析

    resolver 10.0.0.2 valid=60s;
    resolver_timeout 3s;

有关 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

    location /gw1/svc1 {
      set $hash_backend BACKEND_URL_ADDRESS;
      rewrite /gw1/svc1/(.+)$ /$1 break;
      proxy_pass https://$hash_backend;
    }

注意上述 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来做路由。一个简单示例如下:

    upstream backend{
      hash $http_biz_team;
      server 127.0.0.1:8081;
      server 127.0.0.1:8082;
    }
    server {
        listen 80;
        location / {
        proxy_pass http://backend;
        }
    }
    server {
     listen 8081;
     location / {
     return 200 "server 8081";
     }
    }
    server {
     listen 8082;
     location / {
     return 200 "server 8082";
     }
    }

在上述使用中,通过 curl 的时候,带上header名字就可以。需要注意:在map里是http_开头,并且变量是下划线,但实际header是中横线

 curl -H "biz-team: b" http://127.0.0.1

如果是使用 k8s 的 nginx ingress(k8官方的那个,并非f5的),配置起来就更简单了

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-test-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/upstream-hash-by: $http_biz_team
spec:
  ingressClassName: nginx
  rules:
  - host: nginx-test.test.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-test-svc
            port:
              number: 80

nginx map 变量

在nginx中,如果想要将某一个header存到变量里,比如 biz-team (注意是中横线),那么在map里要用 $http_biz_team

    map $http_biz_team $biz_team {
      default "";
      ~^(.*)$ $1;
    }

在 nginx 中通过判断访问的path,决定转发路径

map $uri $is_api_match {
    default 0;
    ~^/api/v1/sol(_mainnet|_testnet)?/(query|update) 1;
    ~^/api/v1/polkadot(_mainnet|_testnet)?/(query|update) 1;
}

server {
        listen 80;
        server_name  _;
        client_max_body_size 8M;
        resolver 10.0.0.2 valid=60s;
        resolver_timeout 3s;
        location ~* ^/api/v1/ {
          if ($is_api_match) {
            set $backend aaa.com;
            proxy_pass http://$backend;
        }
            set $backend bbb;
            proxy_pass http://$backend;
    }
}

Nginx proxy_pass保留域名

当nginx的proxy_pass要转发到后面多个域名的时候,如果访问的地址必须要求Host是一致的(比如做了SNI),但最前端域名又与upstream域名不一致。那么可以使用两层proxy_pass解决。为了不占用过多端口,在内层proxy_pass的监听中,可以监听一个unix socket.

upstream lambda {
      server  unix:/tmp/nginx1.sock;
      server  unix:/tmp/nginx2.sock;
}
server {
        listen unix:/tmp/nginx1.sock;
        location / {
                set $backend abc.lambda-url.ap-northeast-1.on.aws;
                proxy_set_header Host      $backend;
                proxy_pass https://$backend;
        }
    }
server {
        listen unix:/tmp/nginx2.sock;
        location / {
                set $backend bcd.lambda-url.ap-northeast-1.on.aws;
                proxy_set_header Host      $backend;
            proxy_pass https://$backend;
        }
    }
server {
        listen 80;
        server_name 123.com;
        location / {
            proxy_pass http://lambda;
        }
    }
上一页Jenkins Basic下一页ETCD

最后更新于11个月前