一文搞懂Nginx代理

7,591 阅读9分钟

这是我参与11月更文挑战的第25天,活动详情查看:2021最后一次更文挑战

写在前面

Nginx服务器的反向代理服务是其最常用的重要功能,由反向代理服务也可以衍生出很多与此相关的Nginx服务器重要功能,比如后面会介绍的负载均衡。

我们会先介绍Nginx的反向代理,当然在了解反向代理之前,我们需要先知道什么是代理以及什么是正向代理。

代理

在Java设计模式中,代理模式是这样定义的:给某个对象提供一个代理对象,并由代理对象控制原对象的引用。

可能大家不太明白这句话,在举一个现实生活中的例子:比如我们要买一间二手房,虽然我们可以自己去找房源,但是这太花费时间精力了,而且房屋质量检测以及房屋过户等一系列手续也都得我们去办,再说现在这个社会,等我们找到房源,说不定房子都已经涨价了,那么怎么办呢?最简单快捷的方法就是找二手房中介公司(为什么?别人那里房源多啊),于是我们就委托中介公司来给我找合适的房子,以及后续的质量检测过户等操作,我们只需要选好自己想要的房子,然后交钱就行了。

代理简单来说,就是如果我们想做什么,但又不想直接去做,那么这时候就找另外一个人帮我们去做。那么这个例子里面的中介公司就是给我们做代理服务的,我们委托中介公司帮我们找房子。

Nginx主要能够代理如下几种协议,其中用到的最多的就是做Http代理服务器。

image.png

正向代理

弄清楚什么是代理了,那么什么又是正向代理呢?

这里我再举一个例子:大家都知道,现在国内是访问不了Google的,那么怎么才能访问Google呢?我们又想,美国人不是能访问Google吗(这不废话,Google就是美国的),如果我们电脑的对外公网IP地址能变成美国的IP地址,那不就可以访问Google了。你很聪明,VPN就是这样产生的。我们在访问Google时,先连上VPN服务器将我们的IP地址变成美国的IP地址,然后就可以顺利的访问了。

这里的VPN就是做正向代理的。正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端是要进行一些正向代理的设置的。

反向代理

反向代理和正向代理的区别就是:正向代理代理客户端,反向代理代理服务器。

反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

理解这两种代理的关键在于代理服务器所代理的对象是什么,正向代理代理的是客户端,我们需要在客户端进行一些代理的设置。而反向代理代理的是服务器,作为客户端的我们是无法感知到服务器的真实存在的。

总结起来还是一句话:正向代理代理客户端,反向代理代理服务器。

Nginx反向代理

范例:使用nginx反向代理www.123.com直接跳转到127.0.0.1:8080

①、启动一个tomcat,浏览器地址栏输入127.0.0.1:8080,出现如下界面

image.png

②、通过修改本地host文件,将www.123.com映射到127.0.0.1

127.0.0.1 www.123.com 将上面代码添加到 Windows 的host 文件中,该文件位置在:

image.png

配置完成之后,我们便可以通过www.123.com:8080访问到第一步出现的Tomcat初始界面。

那么如何只需要输入www.123.com便可以跳转到Tomcat初始界面呢?便用到nginx的反向代理。

③、在nginx.conf配置文件中增加如下配置:

image.png

如上配置,我们监听80端口,访问域名为www.123.com,不加端口号时默认为80端口,故访问该域名时会跳转到127.0.0.1:8080路径上。

我们在浏览器端输入www.123.com结果如下:

image.png ④、总结

其实这里更贴切的说是通过nginx代理端口,原先访问的是8080端口,通过nginx代理之后,通过80端口就可以访问了。

Nginx反向代理相关指令介绍

①、listen

该指令用于配置网络监听。主要有如下三种配置语法结构:

一、配置监听的IP地址

listenaddress[:port][default_server][setfib=number][backlog=number]
[rcvbuf=size][sndbuf=size][deferred]
    [accept_filter=filter][bind][ssl];

二、配置监听端口

listenport[default_server][setfib=number][backlog=number][rcvbuf=size]
[sndbuf=size][accept_filter=filter]
    [deferred][bind][ipv6only=on|off][ssl];

三、配置UNIX Domain Socket

listenunix:path[default_server][backlog=number][rcvbuf=size][sndbuf=size]
[accept_filter=filter]
    [deferred][bind][ssl];

上面的配置看似比较复杂,其实使用起来是比较简单的:

1  listen*:80|*:8080#监听所有80端口和8080端口
2  listenIP_address:port#监听指定的地址和端口号
3  listenIP_address#监听指定ip地址所有端口
4  listenport#监听该端口的所有IP连接

下面分别解释每个选项的具体含义:

  • 1、address:IP地址,如果是IPV6地址,需要使用中括号[]括起来,比如[fe80::1]等。
  • 2、port:端口号,如果只定义了IP地址,没有定义端口号,那么就使用80端口。
  • 3、path:socket文件路径,如var/run/nginx.sock等。
  • 4、default_server:标识符,将此虚拟主机设置为address:port的默认主机。(在nginx-0.8.21之前使用的是default指令)
  • 5、setfib=number:Nginx-0.8.44中使用这个变量监听socket关联路由表,目前只对FreeBSD起作用,不常用。
  • 6、backlog=number:设置监听函数listen()最多允许多少网络连接同时处于挂起状态,在FreeBSD中默认为-1,其他平台默认为511.
  • 7、rcvbuf=size:设置监听socket接收缓存区大小。
  • 8、sndbuf=size:设置监听socket发送缓存区大小。
  • 9、deferred:标识符,将accept()设置为Deferred模式。
  • 10、accept_filter=filter:设置监听端口对所有请求进行过滤,被过滤的内容不能被接收和处理,本指令只在FreeBSD和NetBSD 5.0+平台下有效。filter可以设置为dataready或httpready。
  • 11、bind:标识符,使用独立的bind()处理此address:port,一般情况下,对于端口相同而IP地址不同的多个连接,Nginx服务器将只使用一个监听指令,并使用bind()处理端口相同的所有连接。
  • 12、ssl:标识符,设置会话连接使用SSL模式进行,此标识符和Nginx服务器提供的HTTPS服务有关。

②、server_name

该指令用于虚拟主机的配置。

通常分为以下两种:

1、基于名称的虚拟主机配置语法格式如下:

server_name name...;

一、对于name来说,可以只有一个名称,也可以有多个名称,中间用空格隔开。而每个名字由两段或者三段组成,每段之间用“.”隔开。

server_name 123.com www.123.com

二、可以使用通配符“*”,但通配符只能用在由三段字符组成的首段或者尾端,或者由两端字符组成的尾端。

server_name *.123.com www.123.*

三、还可以使用正则表达式,用“~”作为正则表达式字符串的开始标记。

server_name  ~^www\d+\.123\.com$;

该表达式"~"表示匹配正则表达式,以www开头(“^”表示开头),紧跟着一个0~9之间的数字,在紧跟“.123.co”,最后跟着“m”($表示结尾)

以上匹配的顺序优先级如下:

1 ①、准确匹配server_name
2 ②、通配符在开始时匹配server_name成功
3 ③、通配符在结尾时匹配server_name成功
4 ④、正则表达式匹配server_name成功

2、基于IP地址的虚拟主机配置

语法结构和基于域名匹配一样,而且不需要考虑通配符和正则表达式的问题。

server_name 192.168.1.1

③、location

该指令用于匹配URL。

语法如下:

1  location[=|~|~*|^~]uri{
2  
3  }

1、=:用于不含正则表达式的uri前,要求请求字符串与uri严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。

2、~:用于表示uri包含正则表达式,并且区分大小写。

3、~*:用于表示uri包含正则表达式,并且不区分大小写。

4、^~:用于不含正则表达式的uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配。

注意:如果uri包含正则表达式,则必须要有或者*标识。

④、proxy_pass

该指令用于设置被代理服务器的地址。可以是主机名称、IP地址加端口号的形式。

语法结构如下:

proxy_pass URL;

URL为被代理服务器的地址,可以包含传输协议、主机名称或IP地址加端口号,URI等。

proxy_pass http://www.123.com/uri;

⑤、index

该指令用于设置网站的默认首页。

语法为:

index filename...;

后面的文件名称可以有多个,中间用空格隔开。

index index.html index.jsp;

通常该指令有两个作用:第一个是用户在请求访问网站时,请求地址可以不写首页名称;第二个是可以对一个请求,根据请求内容而设置不同的首页。

弦外之音

感谢你的阅读,如果你感觉学到了东西,您可以点赞,关注。也欢迎有问题我们下面评论交流

加油! 我们下期再见!

给大家分享几个我前面写的几篇骚操作

copy对象,这个操作有点骚!

干货!SpringBoot利用监听事件,实现异步操作