NGINX的重写与反向代理机制解析_nginx set指令-程序员宅基地

技术标签: nginx  运维  

目录

引言

一、重写功能

(一)if指令

1.判断访问使用的协议

2.判断文件

(二)return指令

1.设置返回状态码

2.返回指定内容

3.指定URL

(三)set指令

1.手动输入变量值

2.调用其它变量值为自定义变量

(四)break指令

(五)rewrite指令

1.permanent(永久重定向301)

2.redirect(临时重定向302)

3.break

4.last

(六)防盗链

1.实现盗链

2.实现防盗链

二、反向代理

(一)实现代理

(二)针对一个URL进行代理

(三)动静分离

(四)反向代理缓存

(五)反向代理客户端 IP 透传

1.单机代理透传

2.多机代理透传

(六)反向代理负载均衡

1.Nginx负载均衡策略

①.轮询

②.加权轮询

③hash

2.状态参数


引言

在现代Web架构中,NGINX以其高性能、稳定性和灵活性而广受青睐。本文将深入探讨NGINX中的两个核心功能:URL重写和反向代理,以帮助您更好地理解和配置这些强大的特性。

一、重写功能

在Nginx中,重写(rewriting)功能主要用于改变请求的URI,以实现URL美化、路径映射、SEO优化等目的。这主要通过 rewrite 指令来完成

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。

例如在上文的https功能中,比如客户去访问京东或者淘宝,在不开启重写功能的清空下,如果直接输入www.toabao.com去访问网址,会通过http协议去访问网址(http://www.taobao.com),它会提示这是一个不安全的网址,这样会使访问者担心网址的安全性,从而放弃访问。所以会开启重写功能,通过修改URL去使用https去访问(https://www.taobao.com)

官方文档: Module ngx_http_rewrite_module

(一)if指令

用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断

官方文档:Module ngx_http_rewrite_module

其基本用法为:

if (条件匹配) {   
执行语句
}

使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接

=

比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false

!=

比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false

~

区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假

!~

区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假

~*

不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假

!~*

不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真

-f和!-f

判断请求的文件是否存在和是否不存在

-d和!-d

判断请求的目录是否存在和是否不存在

-x和!-x

判断文件是否可执行和是否不可执行

-e和!-e

判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)

如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false

1.判断访问使用的协议

使用其它客户端进行访问

2.判断文件

判断文件是否存在或不存在

$request_filename:访问文件的绝对路径

使用客户端进行访问

(二)return指令

return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置

官方文档:Module ngx_http_rewrite_module

return code; 
#返回给客户端指定的HTTP状态码

return code [text]; 
#返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号

return code url; 
#返回给客户端的URL地址

1.设置返回状态码

当访问一个文件不存在时,正常的状态码为404,可以通过配置去修改返回的状态码

使用客户端进行访问

2.返回指定内容

return code [text]; 
返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号

使用客户端访问

curl是文字版的浏览器可以看到指定的信息,但是图形版浏览器不可以

需要使用default_type定义文本格式

3.指定URL

当用户访问到一个不存在的文件时,可以通过return指定状态码,并重定向到新指定的URL下

修改配置文件,并创建指定的URL

使用客户端访问不存在的文件时,就会跳转到主页面

可以看到,两次访问的结果并不一样

第一次执行命令:curl  192.168.83.40/xxx

这个命令没有添加任何参数来处理服务器返回的HTTP重定向响应。在配置中设置了将 /xxx 路径重定向到另一个URL。因此,curl 只显示了服务器发送的302 Found响应的内容,而没有自动跟随重定向到新的URL。

第二次执行命令:curl  192.168.83.40/xxx -L

这次执行时添加了 -L  参数,它告诉 curl 在接收到服务器返回的重定向响应时自动跟随并获取最终的目标页面内容。所以这次您看到了 "welcome to nginx",这是重定向目标页面的实际内容。

也可以跳转到其它网址

使用谷歌浏览器访问不存在的页面时,确实可以跳转到指定的URL,但是状态码却不是301

而是307

307:表示临时重定向

因为浏览器会自行缓存,而访问的是不存在的文件,并不会对该URL进行永久缓存

可以修改一下配置文件,通过访问存在的页面,跳转到百度

因为URL是真实存在的文件,所以会永久缓存

(三)set指令

指令用于设置变量的值。这些变量可以在后续的配置块或指令中使用

官方文档:Module ngx_http_rewrite_module

1.手动输入变量值

使用客户端访问不存在的文件时,就会输出变量内容

2.调用其它变量值为自定义变量

也可以通过调用其它变量值,定义为自己设置的变量的值

使用客户端访问/ip

(四)break指令

用于中断当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令(set、if等)就不再执行,Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在server块和location、if块中使用

官方文档:Module ngx_http_rewrite_module

使用客户端访问测试

使用客户端访问时,只能看到break以上的 ngx_http_rewrite_module 模块指令

(五)rewrite指令

通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理

官方文档:Module ngx_http_rewrite_module

其语句块写法为:

rewrite 原始访问URL  实际访问的URL  标志[premanent(301) redirect(302) break、last]

正则匹配格式为:

. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字    [0-9]   
\b #匹配单词的开始或结束
^ #匹配字付串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
(n) #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W  #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^kgc] #匹配除了kgc 这几个字母以外的任意字符

注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,标志位用于控制此循环机制如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301

rewrite 标志位 使用介绍

利用nginx的rewrite的指令,可以实现url的重新跳转,rewrtie有四种不同的flag,分别是redirect(临时重定向302)、permanent(永久重定向301)、break和last。其中前两种是跳转型的flag,后两种是代理型

1.permanent(永久重定向301)

server {
  listen 80;
  server_name www.china.com;
  root /data/html;
location /computer {
rewrite ^/computer/(.*)  /pc/$1 permanent;
#客户端请求以 /computer 开头并且后面跟随任意内容(通过 (.*) 正则表达式捕获)
#Nginx会使用rewrite指令将原始请求路径重写:/pc/$1(后向引用)也就是(.*)的内容
#permanent表示状态码为301
}
}
mkdir /data/html/pc
#创建指定URL
echo  "welcome to txt" > /data/html/pc/txt
#创建数据文件,并添加内容

使用客户端访问时,访问的绝对路径为/data/html/computer/(.*)

这样做的目的是永久性地将 /computer 下的所有资源映射到 /pc 相应的路径下,以便进行URL结
构的调整或优化搜索引擎收录等目的。

可以使用-vL查看跳转的详细信息

分析一下为什么需要加-L,查看不加-L的信息

可以看到,不加-L只得知状态码及新的URL,并没有跟随重定向跳转,所以需要加上-L跟随重定向

2.redirect(临时重定向302)

临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求

redirect会返回状态码为302

permanent(永久重定向301)、redirect(临时重定向302)的区别

永久重定向的,当nginx服务关闭后,它会从浏览器的缓存记录中打开缓存的URL;而临时重定向的关闭服务后无法进行访问

当状态码为301时

curl是模拟浏览器,无法看到具体信息,可以使用谷歌浏览器的F12,查看信息。而谷歌浏览器因为文件类型限制原因,无法直接打开txt,需要将txt文件该命为以.txt结尾或.html结尾的等其它类型文件

mv  /data/html/pc/txt   /data/html/pc/1.txt

此时关闭nginx服务,依然可以访问到

如果状态码为302,只是临时缓存,当服务关闭后就无法访问

关闭服务后再次访问就会访问失败

3.break


重写完成后,停止对当前URL在当前location中后续的其它重写操作,而后直接跳转至重写规则配置(如return、set)块之后的其它配置;结束循环

使用客户端访问

当用户访问/data/html/computer/txt文件时,会正则匹配到第11行的内容,从而重定向URL到/data/html/pc/txt

4.last

重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用
适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户301

根据配置,在用户访问的时候,重定向后结束return 302;的指令,而后根据新的URL(/data/html/pc/txtx)匹配下面的location去执行新的location语句块中的指令返回301状态码

当新的URL匹配不到任何语句块时,则会直接访问该URL

last与break的区别

last: 当使用 last 标志时,Nginx会停止当前location块内剩余的所有 rewrite 规则,并重新开始寻找与新的URI匹配的location块。这意味着Nginx会继续检查配置文件中的其他location块以找到一个最适合处理已重写请求的location。 如果没有找到其他匹配的location,Nginx将使用最接近原始请求URI的location块来处理请求。

break: 使用 break 标志时,Nginx同样会停止当前location块内剩余的所有 rewrite 规则,但是它不会重新查找新的location块进行匹配。相反,它会在当前location块内继续执行后续的配置指令(如 proxy_pass、echo 等),或者直接返回响应给客户端。

实战:

使用重写功能将HTTP协议转换成HTTPS协议访问

输入http://192.168.83.40进行访问

(六)防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

none
#请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked
#请求报文有referer首部,但无有效值,比如为空。
server_names
#referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string
#自定义指定字符串,但可使用*作通配符。示例: *.kgc.org www.kgc.*
regular expression
#被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.kgc\.com

1.实现盗链

使用两台机器,两个机器同时开启http服务(nginx、httpd均可)

通过pc1去访问pc2的图片,且留在pc1的页面

首先在pc2的主站点目录上建一个文件

在pc1的web服务的主站点目录上建立index.html文件,并输入以下内容

这段HTML代码定义了一个简单的网页结构,当在浏览器中打开时,会显示以下内容:

页面标题(Heading 1)显示文本 "this is 192.168.83.100",

页面中嵌入了一张图片,其 src 属性设置为 "http://192.168.83.40/nginx.jpg"。
这意味着浏览器将尝试从 192.168.83.40 这个服务器上的 /nginx.jpg 路径加载并显示一张图片

开启pc1的http服务

使用真机去访问pc1(192.168.83.100),就会显示pc2(192.168.83.40)web服务主站点目录下的nginx.jpg文件

也可以通过域名实现访问

在192.168.83.100的web服务配置文件中添加域名解析

在pc2的配置文件中,添加server_name www.china.com;而后重新加载配置文件

在主机的C:\Windows\System32\drivers\etc/hosts文件中添加域名解析

解析pc1的主机

这个时候就可以使用域名进行访问了

2.实现防盗链

在pc2的web服务配置文件中添加配置信息

location ~* \.(jpg|gif|swf|jpeg|bmp)$ {
#匹配所有以.jpg、.gif、.swf、.jpeg和.bmp结尾的URL路径。
valid_referers none blocked *.china.com china.com;
#设置了有效的referer来源列表,允许以下几种情况:
#none:表示没有referer(直接访问或通过链接工具打开)。
#blocked:表示referer被浏览器阻止了。
#*.china.com:表示所有以 .china.com 结尾的域名下的referer都是有效的。
#china.com:表示 china.com 主域名本身的referer也是有效的
if ( $invalid_referer ){
#如果请求的referer不在有效referer列表内,则 $invalid_referer 变量会被设置为真
return 403;
#返回HTTP状态码403

再去使用浏览器访问时,就会拒绝访问该文件

使用允许的域名可以访问到

二、反向代理

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式

Nginx 除了可以在企业提供高性能的web服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能

ngx_http_proxy_module: 这个模块实现了HTTP反向代理功能。它允许Nginx接收客户端的HTTP请求,并将请求转发到上游服务器(如应用服务器),同时将上游服务器的响应返回给客户端。通过此模块,可以实现负载均衡、缓存等功能。

代理原理有两种

同构代理:

  • 当Nginx作为代理服务器时,如果其后端服务采用的是相同的技术栈、协议或者数据格式,我们可以称这些后端为“同构”。例如,所有的后端都是基于HTTP/HTTPS协议提供RESTful API服务,并且返回的数据格式(如JSON)也一致。在这种情况下,Nginx只需要根据配置文件中的规则将请求转发到合适的后端服务器即可,无需对请求或响应内容做过多的转换处理。

异构代理:

  • 而在异构环境中,Nginx后面的后端服务可能采用了不同的技术栈、协议或者数据格式。比如一部分是HTTP REST API,另一部分是PHP Python等服务,或者是不同版本的同一服务接口。此时,Nginx不仅需要正确地路由请求,还可能需要进行额外的协议转换、负载均衡策略调整等复杂操作来适应不同后端的需求

ngx_http_upstream_module: 这个模块与ngx_http_proxy_module紧密相关,用于定义一组后端服务器(upstream)作为代理的目标。它可以配置负载均衡算法,健康检查等高级功能,以确保对后端服务器的高效和可靠访问。

ngx_stream_proxy_module: 这个模块提供了TCP/UDP协议层面上的代理服务,适用于非HTTP协议的应用场景,例如SMTP、IMAP、MySQL等基于TCP或UDP的服务。ngx_http_fastcgi_module: Nginx中的FastCGI代理模块,用于处理PHP、Python等动态语言生成的内容。当接收到需要执行FastCGI程序的请求时,此模块会将请求传递给FastCGI服务器(如PHP-FPM),并将执行结果返回给客户端

ngx_http_uwsgi_module: 类似于ngx_http_fastcgi_module,这个模块用于处理使用uWSGI协议的应用,通常用于Python(尤其是Django和Flask框架)应用程序的部署。该模块将HTTP请求转换为uWSGI协议格式并发送到支持uWSGI协议的后端应用服务器。

官方文档: Module ngx_http_proxy_module

最简单的理解方式就是客户访问web服务,通过代理服务器获取web服务的数据信息

也可以设置多个代理服务器,主从服务,防止代理服务器挂了之后,导致整个服务崩坏

(一)实现代理

在配置文件中添加proxy_pass  真实web服务地址;

代理服务器IP

192.168.83.30
web服务器IP 192.168.83.40

首先在代理服务器的配置文件中添加proxy_pass,开启代理服务

在web服务器的根目录下建立好数据文件

此时使用客户端去访问代理服务器就会访问到web服务器的内容

也可以通过监听端口和访问端口进行设置,这样,代理服务器既可以做代理服务器也可以提供web服务

配置代理服务器的配置文件

添加web服务的监听端口

使用客户端访问不同的端口,会得到不同的结果

(二)针对一个URL进行代理

配置代理服务器文件,设置指定的URL

建立web服务器的数据文件

使用客户端进行访问不同的URL

(三)动静分离

动静分离是一种在Web服务器架构设计中常见的策略,它旨在提高系统性能、扩展性和稳定性。动静分离主要是根据请求资源的特性将处理静态内容和动态内容的任务分隔开。

动静分离的概念:

动态内容(Dynamic Content):通常指那些需要服务器实时生成或处理的内容,如通过PHP、Java、Python等语言编写的Web应用程序输出的结果,或者数据库查询返回的数据。这些内容每次请求可能都会产生不同的结果。

静态内容(Static Content):是指那些不会随时间改变且可以被缓存的内容,例如HTML、CSS、JavaScript文件、图片、视频等。这些内容一旦生成,除非有更新,否则可以反复提供给多个用户访问而无需重新生成。

静态资源服务器 192.168.83.40
动态资源服务器 192.168.83.100
代理服务器 192.168.83.30

在静态资源服务器主站点目录下建立静态资源文件

在动态资源服务器主站点目录下建立动态资源文件

修改代理服务器的配置文件

server {
 listen 80;
 server_name www.pla.com;
 root /data/;
#主站点目录为/data
 location ~* /dynamic {
#此location语句块匹配以/dynameic为起点的URL
 proxy_pass http://192.168.83.100;
#开启代理服务,并指定如果访问本机的/dynamic目录下的所有文件,就是去访问
#http://192.168.83.100/dynamic的相同URL的文件
}
 location ~* \.(jpg|html|txt|mp4)$ {
#匹配所有以.(jpg|html|txt|mp4)结尾的文件,用来区分静态资源
 proxy_pass http://a192.168.83.40;
#开启代理服务,如果匹配到以.(jpg|html|txt|mp4)结尾的文件的。
#就会跳转到 http://192.168.83.40下相同URL的文件
}
}

使用客户机访问静态资源

使用客户机访问动态资源

看起来与重写功能区别不大,但是动静分离可以做负载均衡,并有多个优点

提高响应速度:静态资源可以从缓存或专用服务器快速获取,降低延迟。

负载均衡优化:可以根据静态和动态请求的特点分配不同类型的服务器资源,动态服务器可以专注于计算密集型任务,静态服务器则侧重于I/O性能。

扩展性增强:当流量增加时,可以根据需求独立扩展静态资源服务器和应用服务器的规模。

总结来说,动静分离是通过合理的架构设计,使得系统能更高效地应对不同类型请求的一种优化手段,在现代Web服务中广泛应用。

(四)反向代理缓存

反向代理缓存是Nginx作为高性能Web服务器和负载均衡器时提供的一项重要功能。在Nginx的反向代理场景下,它充当客户端与后端应用服务器之间的中间层,可以缓存来自后端服务器的响应结果,并在后续相同的请求中直接提供已缓存的内容,从而减少对后端服务器的请求次数,提高整体系统的响应速度和可用性。同时,当后端服务器宕机后,在一定时间内依然可以访问。

默认缓存功能关闭,通过添加proxy_cache语句开启缓存功能

首先在代理服务器的主配置文件中添加图片中的信息

如果在子配置文件中配置缓存功能,需要写在定义的include子配置文件的上方,读取配置从上往下,写在下方先读取子配置文件,该行指令可能不会生效

proxy_cache_path /data/nginx/proxy_cache
#指定缓存文件存储的路径为 /data/nginx/proxy_cache。

levels=1:1:1
#定义了缓存目录结构层级。这个参数表示将缓存文件按照三级目录进行组织,每一级都是由一个字
#符组成(例如:/0/0/123)。这里的 1:1:1 表示每级目录都只用一个字符来命名,可以根据实际
#需要调整级别和字符长度以适应大量缓存文件的组织需求。

keys_zone=proxycache:20m
#创建了一个名为 proxycache 的共享内存区域,用来存储缓存键值对以及一些元数据,分配给它
#的大小是 20MB。

inactive=120s
#设置缓存项在120秒内未被访问,则被视为过期并可能被清理掉。这意味着如果某个缓存内容在120
#秒内没有被请求,那么它可能会从缓存中移除,释放空间。

max_size=1g
#设置缓存总容量的最大值为1GB。当缓存大小达到1GB时,Nginx会根据其内部策略(如LRU算法)自
#动删除最不活跃或最早添加到缓存中的内容,以便为新内容腾出空间。

在子配置文件中添加信息

proxy_cache proxycache;
#在当前作用域内启用缓存,并关联到之前定义的名为 proxycache 的缓存区域。
#这意味着该server或location内的请求响应将根据策略被存储在 
#/data/nginx/proxy_cache 路径下指定的缓存空间中。重启服务后会自动生成该文件

proxy_cache_key $request_uri;
#设置缓存键(key),这里使用了 $request_uri 变量作为缓存键。这意味着缓存
#会基于每个不同的请求URI进行区分,确保每个唯一的URI对应一个独立的缓存项。

proxy_cache_valid 200 302 301 10m;
#指定了对于HTTP状态码为200、302和301的响应,在成功获取后可以缓存10分钟。在此期
#间内,如果有相同的请求到达,Nginx将直接返回缓存中的内容,而不是再次向后端服务器发起请求。

proxy_cache_valid any 5m;
#任何其他未明确指定状态码的响应(包括但不限于404、500等),其缓存有效时间为5分钟。
#这意味着非200/301/302状态码的响应虽然也会被缓存,但其过期时间较短。

此时缓存目录下是没有任何文件的,需要访问之后才会有缓存

当关闭192.168.83.40这个服务器之后,在一定时间内依然可以访问到该信息

增加头部信息

add_header  自定义头部名称  变量(信息)

add_header server_ip $server_addr;

#这条指令会在响应头中增加一个名为 "server_ip" 的字段,并将其值设置为当前服务器的IP地址
#($server_addr)。这有助于了解请求经过了哪些代理服务器或负载均衡器。

add_header cache $upstream_cache_status;
#此指令添加了一个 "cache" 字段到响应头中,其值由 $upstream_cache_status 变量提供。
#这个变量表示请求是否被缓存服务命中以及具体的缓存状态,例如 "HIT"(命中)、"MISS"(未
#命中)等。这对于判断反向代理缓存策略是否生效及其效果非常有帮助。

add_header server_name $server_name;
#这个指令添加了一个名为server_name的字段,其值是当前服务器的主机名($server_name)。
#server_name;头部与Nginx内部的ngx_http_proxy_module或ngx_http_fastcgi_module 
#等模块结合使用,用来标识内部请求加速或文件内部重定向等相关信息。

使用客户端访问并查看头部信息

(五)反向代理客户端 IP 透传

在Nginx作为反向代理服务器时通常在接受到客户端的请求后,会去访问真实的web服务器,而此时web服务器的IP地址仅仅只有代理服务器的IP,并不能知道,访问服务器资源的客户端的IP地址

在上面的图片中。作为web服务器,经过反向代理后,只能获得代理服务器的IP(192.168.83.30),

并不能获得客户端IP(192.168.83.50)。

为了能够正确地将客户端的真实IP地址传递给后端应用服务器,需要配置Nginx将客户端IP添加到请求头中。这样,即使经过了Nginx的代理,后端服务器也能识别出原始客户端IP

1.单机代理透传

只有一台代理服务器的情况下进行透传

代理服务器IP

192.168.83.30
web服务器IP 192.168.83.40
客户端IP 192.168.83.50

首先在代理服务器中添加:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

指令设置了全局的请求头转发规则,将客户端的真实IP地址(或者其他代理服务器传递过来的IP地址)通过 X-Forwarded-For 请求头传递给后端服务器。$proxy_add_x_forwarded_for 变量会自动将客户端IP添加到现有的 X-Forwarded-For 头部中,如果没有则创建一个新的头部。

使用默认的日志格式,并打开将注释删除

使用客户端访问并查看日志web服务(192.168.83.40)的日志

可以看到,开头的192.168.83.30是代理服务器访问web服务器的$remote_addr,最后的192.168.83.50则是客户端的真实IP

2.多机代理透传

代理服务器可能会有多台

代理服务器1:IP 192.168.83.30

代理服务器2:IP

192.168.83.100
web服务器IP 192.168.83.40
客户端IP 192.168.83.50

首先来配置一号代理服务器

添加:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

此时将客户端的IP地址赋予x_forwarded_for

在配置二号代理服务器

此时再去访问第一台代理服务器,就会通过两层代理到真实的web服务器

这是时候查看日志信息

(六)反向代理负载均衡

在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以基于ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能

反向代理负载均衡是一种将客户端请求分发到一组后端服务器的技术,以分散负载、提高可用性和伸缩性。

由一台代理服务器,指向两台真实的web服务器

代理服务器

192.168.83.30
web服务器1  192.168.83.40
web服务器2 192.168.83.100

在代理服务器上定义地址池,并开启反向代理服务

官方文档:Module ngx_http_upstream_module

upstream只能写在http语句块中

语法为:

upstream  地址池name {

server web服务器IP地址;

server web服务器IP地址;

............

}

建立两个web服务器的数据文件

使用客户端进行访问

可以看到,访问时按地址池中的地址依次访问,而后再次重新依次访问,即访问一次192.168.83.40.再访问192.168.83.100,而后再访问192.168.83.40,这样依次访问,这种方法也是upstream模块默认的负载均衡默认策略。叫做轮询

nginx服务有健康检测机制,如果其中一台服务器宕机,代理服务器并不会将请求发送给宕机的服务器,如果连接超时

1.Nginx负载均衡策略

Nginx负载均衡策略有以下几种

①.轮询

最基本的配置方法,上面的例子就是轮询的方式。每个请求会按时间顺序逐一分配到不同的后端服务器。

②.加权轮询

按分配权重进行轮询,使用weight进行分配

使用客户端进行访问,可以发现,访问比例为3:1

如果设置成5:2,它的访问比例为3:1加2:1

③hash

hash的主要作用是为了保持会话联系。在负载均衡和反向代理的场景下,会话保持(Session Persistence)是一种确保客户端与特定后端服务器之间维持持久连接的技术。当用户在多个请求中需要共享同一会话状态时,例如登录状态、购物车内容等,会话保持尤为重要

hash分为三种

ip_hash

每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上

在地址池中添加ip_hash或hash $remote_addr

这样不论访问多少次都会将访问的客户端的IP地址固定在一个服务器上

url_hash

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器。一旦缓存住了资源,再次收到请求,就可以从缓存中读取。

在地址池中添加hash $request_uri

使用客户端进行访问后,根据路径分配后端服务器后,服务器会进行缓存,后续访问会根据访问路径,调取缓存,访问到同一个后端服务器

3.cookie hash

在Nginx中,实现基于Cookie的会话保持(Session Persistence)通常涉及到使用一个自定义的cookie或利用已存在的session cookie来决定将请求转发到哪个后端服务器。这种技术有时被称为“Cookie Hash”或“Cookie Stickiness”

使用客户机访问时加上不同的关键字

另外还有几种策略

least_conn

把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果

fair

此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配

2.状态参数

max_conns=number  
#给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number  
#后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检测
#多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探
#测后端服务器健康性检查,而非周期性的探测
fail_timeout=time 
#后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再次进行
#检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup  
#设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器
down    
#标记为down状态
resolve 
#当server定义的是主机名的时候,当A记录(DNS解析)发生变化会自动应用新IP而不用重启Nginx

这个时候去访问代理服务器,只会将请求发送到192.168.83.40,当所有的服务器都宕机之后,,才会访问到备用的服务器

再去访问时就会访问到备用机器

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hy199707/article/details/136281410

智能推荐

什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?_成员内部类和局部内部类的区别-程序员宅基地

文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别

分布式系统_分布式系统运维工具-程序员宅基地

文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具

用Exce分析l数据极简入门_exce l趋势分析数据量-程序员宅基地

文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量

宁盾堡垒机双因素认证方案_horizon宁盾双因素配置-程序员宅基地

文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置

谷歌浏览器安装(Win、Linux、离线安装)_chrome linux debian离线安装依赖-程序员宅基地

文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖

烤仔TVの尚书房 | 逃离北上广?不如押宝越南“北上广”-程序员宅基地

文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...

随便推点

java spark的使用和配置_使用java调用spark注册进去的程序-程序员宅基地

文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序

汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用_uds协议栈 源代码-程序员宅基地

文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码

AUTOSAR基础篇之OS(下)_autosar 定义了 5 种多核支持类型-程序员宅基地

文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型

VS报错无法打开自己写的头文件_vs2013打不开自己定义的头文件-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件

【Redis】Redis基础命令集详解_redis命令-程序员宅基地

文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令

URP渲染管线简介-程序员宅基地

文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线