总结:nginx配置

11 篇文章 1 订阅
11 篇文章 4 订阅

一、nginx rewrite 与 proxy_pass区别

rewriteproxy_pass 都是 Nginx 的常用指令,但它们的功能和使用场景有所不同。

1、rewrite:是一个用来修改请求 URI 的指令。在 Nginx 收到一个请求后,rewrite 指令可以基于特定的条件改变这个请求的 URI,可能是改变文件路径,可能是重定向到一个新的地址。基本的语法为 rewrite regex replacement [flag] 其中 regex 是要匹配的正则表达式,replacement 是匹配的结果要被替换的内容。例如,rewrite ^(/download/.*)/media/(.*)$ $1/mp3/$2,这个会把 "/download/media/abc.mp3"这样的 URL 替换为 "/download/mp3/abc.mp3"。负载越大,对硬件的要求就越高。

2、proxy_pass:这个指令告诉 Nginx 将收到的请求转发到其他的服务器。在做反向代理时经常会用到此命令。例如,proxy_pass http://localhost:8000; 这个配置就会把所有请求转发到运行在 localhost:8000 上的服务器。负载越高,对网络的需求就越大。

而它们之间的主要区别就是,rewrite 是对请求 URL 的修改,而不改变请求的目的地,而 proxy_pass 是不改变 URL,但是改变了请求的后端服务器,这两个指令通常结合起来使用,用以实现一些特定的需求。在实际运用中我们经常看到这两者一起使用,以满足定制化路由的逻辑。

例如:

location / {
    rewrite ^/abc/(.*)$ /xyz/$1 break;
    proxy_pass http://localhost:8000;
}

这个配置中,客户端请求的 URL "/abc/test" 会被重写为 "/xyz/test" ,然后再被转发到 localhost:8000 这个服务器上。

问题一:问题来了,那么,使用rewrite后,假设我的配置是location / { rewrite ^/abc/(.*)$ /xyz/$1 break; proxy_pass http://localhost:8000; },那么我在浏览器输入http://10.10.1.2/abc/mm,访问后,浏览器地址是否会变成http://10.10.1.2/xyz/mm?

不会,Nginx的rewrite指令在这种情况下只会更改传递给后端服务器的URI,并不会影响浏览器的地址栏。在浏览器地址栏输入http://10.10.1.2/abc/mm,服务器会接收到这个请求并通过rewrite规则将其更改为/xyz/mm,然后将其转发到proxy_pass设置的地址http://localhost:8000/xyz/mm。但这并不会更改浏览器的地址栏。

如果你想要在rewrite后更改浏览器的地址栏,你需要发送一次HTTP重定向。例如,以下配置可以在rewrite时发送HTTP 301永久重定向:

rewrite ^/abc/(.*)$ /xyz/$1 permanent;

在此情况下,当浏览器尝试访问http://10.10.1.2/abc/mm,服务器会返回HTTP 301响应和新地址http://10.10.1.2/xyz/mm。然后浏览器会在地址栏更新新地址并请求新地址。请注意,这将使浏览器显示新URL,但也将导致两次请求——一次是原始请求,另一次是重定向到新URL的请求。

问题二:那么,使用rewrite后,假设我的配置是location / { rewrite ^/abc/(.*)$ /xyz/$1 break; },那么我在浏览器输入http://10.10.1.2/abc/mm,访问后,浏览器地址是否会变成http://10.10.1.2/xyz/mm?

不会,同样的,即使你没有使用 proxy_pass,Nginx 的 rewrite 指令也只是在服务器内部重写 URL,而不会影响浏览器地址栏显示的 URL。

在你的例子中,当你在浏览器输入 http://10.10.1.2/abc/mm,Nginx 会接收到这个请求,并将请求 URL 通过 rewrite 规则改写为 "/xyz/mm"。然后,Nginx 会在本地查找这个新的 URL 对应的资源。这个过程对客户端浏览器是不可见的,因此浏览器地址栏还是会显示原来输入的 URL。

如果你要想改变浏览器的地址栏显示的 URL,你需要显式地发出一个重定向响应,比如使用 HTTP 的 301 或 302 状态码。这可以通过在 rewrite 指令后面添加 redirectpermanent 标志来实现。例如,

rewrite ^/abc/(.*)$ /xyz/$1 permanent;

这样,当一个请求匹配这个 rewrite 规则时,Nginix 会向客户端浏览器发出一个 301(永久重定向)响应,浏览器接收到这个响应之后,会自动将地址变为新的 URL 并重新发送请求。

问题三:rewrite ^/abc/(.*)$ /xyz/$1 permanent;和rewrite ^/abc/(.*)$ /xyz/$1 redirect;是什么区别

rewrite ^/abc/(.*)$ /xyz/$1 permanent;rewrite ^/abc/(.*)$ /xyz/$1 redirect; 这两个Nginx配置的主要区别在于重定向的HTTP状态码。

  • permanent: 生成一个HTTP 301 Moved Permanently响应。这个响应是永久性的,告诉客户端(比如浏览器)这个资源已经被永久的移动到了新的位置,以后应该直接去新的位置查找这个资源。

  • redirect:生成一个HTTP 302 Moved Temporarily响应。这个响应告诉客户端这个资源被暂时移动到了新的位置,但是可能以后还会回到原来的位置。

因此,在实际使用中,你应该根据实际情况选择恰当的响应。如果你知道资源永久的移动到了新的位置,那么应该使用permanent;如果你知道资源只是暂时移动到新的位置,那么应该使用redirect。

二、proxy_pass会改变路径地址吗?

不会。

如下配置,^~ /main 表示当请求的 URI 以 /main 开头时,将应用这个 location 块中的配置。

proxy_pass 指令用于将请求转发到指定的上游服务器(在这个例子中是 http://hubble-portal)。当请求被转发到上游服务器时,原始请求的路径(/main 及其子路径)会被保留,并不会发生变化。这意味着,如果客户端请求的是 /main/some/path,那么这个请求会被转发到 hubble-portal 服务器,但路径仍然是 /main/some/path

location ^~ /main {
        proxy_pass       http://hubble-portal;
        
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

三、配置分析

location ^~ /api/cm/idc { 
    proxy_pass http://hubble-api-host; 
} 

location ^~ /api/alarm/alarmquery { 
    proxy_pass http://hubble-alarm-query/api/biz/bq/alarm/alarmquery; 
}

分析下这两个配置:

第二个配置是将用户访问的原url(/api/alarm/alarmquery)转到访问另一个url(/api/biz/bq/alarm/alarmquery)。

第一个是转到访问hubble-api-host服务的/api/cm/idc,url没有变,即转发后的路径是:http://hubble-api-host​/api/cm/idc

为啥第一个不配置成如下方式:

location ^~ /api/cm/idc { 
    proxy_pass http://hubble-api-host/api/cm/idc; 
}

原因如下:

第一个配置:

location ^~ /api/cm/idc {
    proxy_pass http://hubble-api-host;
}

这个配置使用了^~修饰符,这意味着对于所有以/api/cm/idc开头的请求,这个location块将会优先于其他正则匹配的location块生效。请求被转发到http://hubble-api-host,转发时不会改变原请求的URI。

第二个配置:

location ^~ /api/alarm/alarmquery {
    proxy_pass http://hubble-alarm-query/api/biz/bq/alarm/alarmquery;
}

这个配置同样使用了^~修饰符,它将以/api/alarm/alarmquery开头的请求转发到新的路径http://hubble-alarm-query/api/biz/bq/alarm/alarmquery。在转发时,原始请求的URI会被替换为proxy_pass中指定的新URI。

你问到为什么第一个配置不写成:

location ^~ /api/cm/idc {
    proxy_pass http://hubble-api-host/api/cm/idc;
}

原因是这样做的话,请求/api/cm/idc会被转发为http://hubble-api-host/api/cm/idc/api/cm/idc,导致URI重复而出现错误。当proxy_pass使用一个不带路径的URL,如http://hubble-api-host时,Nginx会将原始请求的URI不变地传递给上游服务器。这样若上游服务器具体API路径与代理配置路径一致,那么不需要在proxy_pass中再次指定。

为了避免错误和混淆,如果需要在转发时保持原始URI不变,则应该使用域名而不是完整的URL路径作为proxy_pass的参数。如果需要修改转发的URI,再在proxy_pass参数后面加上新的路径

结合第二个配置,如果你想重写目标的URI路径,并且希望保留请求的其他部分(例如查询参数),你可以使用下面的配置方法:

location ^~ /api/alarm/alarmquery {
    rewrite ^/api/alarm/alarmquery(/.*)$ $1 break;
    proxy_pass http://hubble-alarm-query/api/biz/bq/alarm/alarmquery;
}

这样就能够将用户的请求从/api/alarm/alarmquery重写到/api/biz/bq/alarm/alarmquery,同时保留如/api/alarm/alarmquery?param=value这种请求中的查询参数。不过具体是否需要这样做,还需要依据你的实际应用场景及上游服务器的期望请求形式来决定。

总结:

如果proxy_pass配置中不带具体的uri路径,则将原url路径加上。

如果proxy_pass配置中带了具体的uri路径,则直接使用替换后的url路径。

四、分析下此配置

location ^~ /m/ {
    proxy_pass http://hubble_gateway_hubble-static/m/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

如上配置后,假设有一个客户端请求为:

http://yourdomain.com/m/page.html

由于配置了上述的 location 块,Nginx 会代理这个请求到上游服务器。完成后的上游请求会变成:

http://hubble_gateway_hubble-static/m/page.html

相对应的,如果是如下配置:

location ^~ /api/alarm/alarmquery {
    proxy_pass http://hubble-alarm-query/api/biz/bq/alarm/alarmquery;
}

针对这个配置,当接收到请求:

http://yourdomain.com/api/alarm/alarmquery/details?id=1234

它会被 Nginx 处理并代理转发到如下地址:

http://hubble-alarm-query/api/biz/bq/alarm/alarmquery/details?id=1234

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值