Nginx做反向代理(五)

背景

         前面介绍了nginx中Server块和Location块的配置,说那些实际上就是为后面配置反向代理和负载均衡做铺垫的。接下来我们就说说nginx的反向代理功能。

反向代理 

         前面在第一章节介绍nginx的功能的时候提到过,nginx实际上也是可以做正向代理的,只是我们在生产环境中很少这么而已,所以我们就不在过多的介绍nginx的正向代理的功能了。

1.    什么是反向代理?

         反向代理是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端。这个服务器所做的功能就是反向代理。

 2.    常用代理协议

 

 3.   反向代理

        3.1    环境介绍

         实际生产中,Client--nginx间是属于互联网,nginx代理---后端web是内网,在这里为了实验方便我们就同一在一个网段中,后续通过抓包等方式来验证结果。

    3.2  配置代理

nginx代理端

server {
    listen 80;
    server_name proxy_web.com www.proxy_web.com;

    location / {
        proxy_pass http://192.168.65.130:8080;

    }
}


##  proxy_pass URL  解析
将请求转发到另一台服务器,在实际的反向代理工作中,会通过 location 功能匹配指定的 URI,然后把接收到的符合匹配 URI 的请求通过 proxy_pass 抛给定义好的upstream节点池(后端服务节点)。
 
    
proxy_pass转发的路径问题
    第一种:proxy_pass后面的url加/,表示绝对根路径,不会代理location后的路径;
    	假设用URL:http://www.proxy_web.com/web/test.html 进行访问。
		location /web/ {
   		 	proxy_pass http://192.168.65.130:8080/;
		}
		# 代理到URL:http://192.168.65.130:8080/test.html

    第二种:相对于第一种,最后少一个 / ,则会把location后的路径代理进去	
		location /web/ {
    		proxy_pass http://192.168.65.130:8080;
		}
		# 代理到URL:http://192.168.65.130:8080/web/test.html

web服务端

server {
	listen 8080;
	server_name proxy_web.com www.proxy_web.com;

	location / {
		root /nginx/web;
		index index.html;
	}
}

Client端请求代理:

##  访问结果
C:\Users\xhz>curl www.proxy_web.com
web1
C:\Users\xhz>


## nginx代理端的访问日志
192.168.65.1 - - [19/Aug/2022:16:22:47 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "-"
192.168.65.1 - - [19/Aug/2022:16:22:48 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "-"
192.168.65.1 - - [19/Aug/2022:16:22:48 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "-"
192.168.65.1 - - [19/Aug/2022:16:27:39 +0800] "GET / HTTP/1.1" 200 5 "-" "curl/7.83.1" "-"


##  web服务端的日志

192.168.65.129 - - [19/Aug/2022:16:22:47 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "-"
192.168.65.129 - - [19/Aug/2022:16:22:48 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "-"
192.168.65.129 - - [19/Aug/2022:16:22:48 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "-"
192.168.65.129 - - [19/Aug/2022:16:27:39 +0800] "GET / HTTP/1.0" 200 5 "-" "curl/7.83.1" "-"

        我们通过client端向代理发送请求,可以看到nginx代理端中的日志,请求ip是客户端的192.168.65.1;在web服务端的日志中可以看到请求ip是192.168.65.129的ip(nginx代理),此时说明代理功能已经实现。

        我们在web后端是看不到前端client的ip的。我们可以优化下。通过设置proxy_set_header,来修改cline请求包中的头部信息,然后携带的传给后端web。

server {
    listen 80;
    server_name proxy_web.com www.proxy_web.com;

    location / {
        proxy_pass http://192.168.65.130:8080;
        proxy_set_header Host $http_host;

        ##携带前端clien ip 发送到web端
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    }
}


此时web后端的日志为:(后端显示client端ip)
192.168.65.129 - - [19/Aug/2022:16:56:07 +0800] "GET / HTTP/1.0" 200 5 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "192.168.65.1"
192.168.65.129 - - [19/Aug/2022:16:56:32 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "192.168.65.1"
192.168.65.129 - - [19/Aug/2022:16:56:32 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "192.168.65.1"
192.168.65.129 - - [19/Aug/2022:16:56:32 +0800] "GET / HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "192.168.65.1"

         至此最基础的nginx反向代理已经完成,至于复杂的无非就是添加更加复杂的参数,下面我们就说说相应模块中的参数。

3.   ngx_http_proxy_module模块解析

 3.1         proxy_set_header 

        用来设定被代理服务器接收到的header信息,如果不设置proxy_set_header,则默认host的值为proxy_pass后面跟的那个域名或者IP

##语法:
proxy_set_header field value
	field :为要更改的项目,也可以理解为变量的名字,比如host;
    value :为变量的值
    
    作用域:http, server, location 
	
## 当后端web服务器存在多个虚拟主机时,该模块是用来区分前端请求,是给反向代理的后端的哪个虚拟主机(即将代理的server_name传递到后端的域名为代理的server_name的虚拟主机上)
	proxy_set_header Host $host;
	
## 用来设置被代理端接收到的远程客户端IP,如果不设置,则header信息中并不会透传远程真实客户端的IP地址。
	proxy_set_header X-Real-IP $remote_addr;
	和
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

## 此时后端服务器记录日志格式要添加:"$http_x_real_ip"和"$http_x_forwarded_for"变量,才能在访问日志中查看到效果
    # 只有一级代理的情况下两者是等效的;如果有多级代理,X-Forwarded-For效果是大于X-Real-IP的,可以记录完整的代理链路



3.2    proxy_http_version

    设置代理的HTTP协议版本。默认情况下,使用版本1.0。
    作用域:http, server, location
    proxy_http_version 1.0 | 1.1;

3.3        proxy_cache_path

定义可用于proxy功能的缓存;

作用域:http 

proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size[inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

3.4     proxy_cache  

proxy_cache zone | off;   

默认off指明调用的缓存,或关闭缓存机制;

作用域:http, server, location

3.5   proxy_cache_key 

proxy_cache_key string; 

缓存中用于“键”的内容默认值:proxy_cache_key $scheme $proxy_host $request_uri;

作用域:http, server, location

3.6    proxy_cache_valid 

proxy_cache_valid [code ...] time; 

定义对特定响应码的响应内容的缓存时长 

 定义在http{...}中 

作用域:http, server, location

示例:
    proxy_cache_valid200 302 10m;

示例:在http配置定义缓存信
    proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_size=1g; 
    调用缓存功能,需要定义在相应的配置段,如server{...};
    proxy_cache proxycache;
    proxy_cache_key $request_uri; 
    proxy_cache_valid 200 302 301 1h; 
    proxy_cache_valid any 1m;

3.7     proxy_cache_use_stale

proxy_cache_use_stale; 
    proxy_cache_use_stale  error | timeout | invalid_header| updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ... 

在被代理的后端服务器出现哪种情况下,可以真接使用过期的缓存响应客户端

作用域:http, server, location

3.8     proxy_cache_methods 

 proxy_cache_methods GET | HEAD | POST ...; 

对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存

作用域:http, server, location

3.9     proxy_hide_header 

 proxy_hide_header field; 

默认nginx在响应报文不传递后端服务器的首部字段Date, Server, X-Pad,  X-Accel-等,用于隐藏后端服务器特定的响应首部

作用域:http, server, location

3.10    proxy_connect_timeout 

proxy_connect_timeout time; 

定义与后端服务器建立连接的超时时长,如超时会出现502错误,默认为60s,一般不建议超出75s,

作用域:http, server, location

3.11     proxy_send_timeout 

proxy_send_timeout time; 

将请求发送给后端服务器的超时时长;默认为60s

作用域:http, server, location

3.12    proxy_read_timeout 

proxy_read_timeout time; 

等待后端服务器发送响应报文的超时时长,默认为60s

作用域:http, server, location

3.13     proxy_buffering

proxy_buffering on | off;

代理会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端

Default: proxy_buffering on;

作用域: http, server, location

3.14    proxy_buffer_size 

proxy_buffer_size size;

设置nginx代理保存用户头信息的缓冲区大小

Default: proxy_buffer_size 4k|8k;	

作用域: http, server, location

3.15   proxy_buffers

proxy_buffers number size; 

设置proxy_buffers缓冲区大小

Default: proxy_buffers 8 4k|8k;		# 8*4=32k 8*8=64k

作用域: http, server, location

         为了避免在配置代理的时候出现参数冗余,我们可以将常用参数配置在相应的文件中,文件名自定义。然后在location通过 include  来加载。

root@nginx-server:~#  vim /etc/nginx/proxy_params
proxy_http_version 1.1;		# 设置代理的HTTP协议版本
proxy_set_header Host $http_host;	# 代理向后端主机请求时携带host域名
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;	# 获取客户端真实IP以及全链路IP
 
proxy_connect_timeout 30;	# 代理连接后端超时时间
proxy_send_timeout 60;		# 后端传递数据至代理的超时时间
proxy_read_timeout 60;		# 后端响应代理的超时时间
 
proxy_buffering on;			# 代理会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传
proxy_buffer_size 32k;		# 代理保存用户头信息的缓冲区大小
proxy_buffers 4 128k;		# 设置代理的缓冲区大小

# 重复使用配置

代理配置location时调用方便后续多个Location重复使用

location / {
    proxy_pass http://IP:PORT;
    include proxy_params;    # 此文件为相对路径,默认会在/etc/nginx/目录下找对应文件
}

         nginx的代理功能只能代理后端的某一台服务器,即proxy_pass 后面只能写一个后端服务器地址,这也是代理的局限性。要想代理多台就需要使用upstream创建代理池,这也是后面负载均衡我们所要说的内容。

本文参考nginx官网:https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小肖同学..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值