nginx反向代理、负载均衡

发布时间:2023年12月30日

负载均衡、反向代理

在 Nginx 中,HTTP七层代理和四层代理是两种不同的代理方式,具有不同的特点和用途。

HTTP七层代理是指基于HTTP协议进行代理转发的方式,
HTTP七层代理可以分为反向代理和正向代理,代理的是HTTP请求和响应。
具体而言,反向代理是代理服务器接收客户端的HTTP请求,然后将请求转发到内部的一组服务器上进行处理,
再将服务器返回的响应返回给客户端。客户端不知道请求的是代理服务器还是内部服务器,
而代理服务器隐藏了内部服务器的真实IP地址。正向代理则是客户端通过代理服务器来访问其他服务器,
代理服务器会将客户端的请求转发给目标服务器,并将目标服务器的响应返回给客户端。
在这种情况下,客户端知道请求的是代理服务器,但不知道代理服务器后面的目标服务器的IP地址。。
HTTP七层代理的配置Proxy,需要在 Nginx 配置文件中使用“location”指令来进行指定。
±-----------+
| Load |
| Balancer |
±-----------+
|
|
|
±-----------+
| |
| Proxy |
| |
±-----------+
/
/
/
±-----------+ ±-----------+
| Web Server| | Web Server|
| 1 | | 2 |
±-----------+ ±-----------+
在这个分布式集群中,集群由多个服务器组成,这些服务器可以是物理服务器、虚拟机、容器等形式。
其中,Load Balancer(负载均衡器)用于接收用户请求,将请求转发给 Proxy(代理服务器)集群中的某个代理服务器。
Proxy 集群可以包含多个代理服务器,用于代理用户请求并将请求转发给后端的 Web Server 集群中的某个服务器进行处理,
然后将处理结果返回给用户。Web Server 集群中可以包含多个 Web Server,用于处理用户请求并生成响应。
在这个结构中,Load Balancer(负载均衡)、Proxy(代理服务器) 和 Web Server(网站服务器) 都可以部署在不同的物理机器或虚拟机上,以提高系统的可用性和性能。


四层代理则是基于 TCP/IP 协议层的代理转发方式,可以实现基于 IP 地址和端口号的负载均衡和高可用性。
四层代理无法获取 HTTP 请求中的 URL 信息,只能对 TCP/UDP 数据包进行转发和负载均衡。
四层代理的配置需要在 Nginx 配置文件中使用“stream”指令来进行指定。
Client
|
V
±--------------+
| Load Balancer|
±--------------+
|
V
±--------------+
| Proxy Server |
±--------------+
|
V
Real Server
1、客户端向 Load Balancer 发送请求
2、Load Balancer 收到请求,将请求转发给一个代理服务器。
3、代理服务器将请求发送给后端的真实服务器。
4、真实服务器接收到请求,返回响应给代理服务器。
5、代理服务器将响应返回给 Load Balancer。
6、Load Balancer 将响应返回给客户端。

在这个流程中,Load Balancer 负责负载均衡,选择一个可用的代理服务器,将请求转发给它。
代理服务器将请求发送给真实服务器,并将响应返回给 Load Balancer,由 Load Balancer 返回给客户端。

四层代理和七层代理的负载均衡方式有所不同。
四层代理的负载均衡是基于 IP 地址和端口号进行的,它只负责将请求转发到后端服务器上,无法对请求进行深入的解析和处理。
因此,四层代理的负载均衡速度较快,但是无法对请求进行精细的处理和控制,例如无法进行流量控制、内容过滤等等。

七层代理的负载均衡是基于 HTTP 协议进行的,它可以对请求进行深入的解析和处理,
例如可以根据请求的 URL、请求头、请求内容等进行智能路由、流量控制、内容过滤等等。
七层代理的负载均衡速度相对较慢,但是可以提供更高级的功能和更好的用户体验。

因此,四层代理通常适用于需要高效处理大量连接请求的场景,例如 TCP 和 UDP 协议的负载均衡;
而七层代理通常适用于需要对 HTTP 请求进行深入处理和控制的场景,例如 Web 应用程序的负载均衡。

一般来说,如果需要对 HTTP 请求进行精确处理和控制,
可以选择使用 HTTP 七层代理;如果只需要进行TCP/UDP数据包的转发和负载均衡,
可以选择使用四层代理。但在实际应用中,也可以同时使用这两种代理方式,
根据不同的需求进行组合和配置。

什么是代理:
代理就是客户端通过代理服务器去访问指定的服务器,例如去买房子,
人门通过中介去买开发商的房子,中介就是代理

1、正向代理:
正向代理:
正向代理是面向客户端的。客户端想要访问一个web服务器,但是客户端的ip被web服务器禁止访问了,
这个时候就可以通过代理服务器,客户端通过代理服务器去访问web服务器,
web服务器只会知道是代理服务器的ip访问的它,而不知道是客户端

应用:正向代理更多的用在公司内网,公司内员工的主机都通过一个代理服务器访问互联网,
而互联网上被访问的服务器,
只知道代理服务器的ip,不知道公司内员工的ip,主要作用:加速,翻墙

nginx常用的内置变量:
$http_host:变量值就是客户端请求的目标ip地址,
例如,客户端已经指向了代理,然后访问192.168.233.22,那么这个变量的值就是192.168.233.22,
同理访问192.168.233.23那么这个变量值就是192.168.233.23

$request_uri:变量值就是客户端访问的资源,
例如,客户端已经指向了代理,然后访问http://192.168.233.22/那么这个变量值就是/,
同理访问http://192.168.233.22/aaa那么这个值就变成了/aaa

$host:客户端请求头中的Host字段

$remote_addr:值为请求客户端的ip

$proxy_add_x_forwarded_for:被访问的web服务器可以看到客户端的真实ip

proxy_set_header X-Real-IP: 是一个 nginx 的指令,用于将 HTTP 请求的客户端IP地址
通过HTTP头信息传递给后端服务器。

$proxy_add_x_forwarded_for变量的值分别是什么:

在代理1上,$proxy_add_x_forwarded_for的值是:客户机的IP。

在代理2上,$proxy_add_x_forwarded_for的值是:客户机的IP,代理1的IP。以逗号隔开。

在Nginx服务器上,$proxy_add_x_forwarded_for的值是:客户机的IP,代理1的IP,代理2的IP。以逗号隔开。

反向代理:客户端直接访问代理服务器
作用:
负载均衡:反向代理可以将请求分配到多台后端服务器上,从而分担服务器的负载,
提高系统的可用性和稳定性。

缓存加速:反向代理可以缓存经常访问的资源,减少后端服务器的负载和提高响应速度。

安全保护:反向代理可以隐藏后端服务器的真实 IP 地址,提高系统的安全性,
同时也可以对请求进行过滤和限制,
保护后端服务器免受恶意攻击。

简化架构:反向代理可以将多个后端服务器整合为一个逻辑服务,简化系统架构,
提高系统的可维护性和可扩展性。

upstream和stream的区别

upstream 和 stream 是 Nginx 中两个不同的模块,用于处理不同类型的流量。它们具有以下区别:

功能:
upstream 模块:upstream 模块用于处理 HTTP 流量,支持反向代理、负载均衡和缓存等功能。
它可以将来自客户端的 HTTP 请求转发到后端的多个服务器,实现负载均衡和高可用性。

stream 模块:stream 模块用于处理 TCP 和 UDP 流量,可以用于构建 TCP/UDP 代理、
负载均衡器和数据包过滤器等。它可以处理非 HTTP 协议的流量,并提供灵活的流量管理和路由功能。

协议支持:
upstream 模块:upstream 模块仅支持 HTTP 协议,用于处理 HTTP 请求和响应。

stream 模块:stream 模块支持 TCP 和 UDP 协议,用于处理基于这两种协议的流量,
无论是 HTTP 还是非 HTTP 流量。

配置语法:
upstream 模块:upstream 模块的配置块位于 http 块内,用于配置反向代理和负载均衡的后端服务器列表,
以及相关的负载均衡算法和参数。

stream 模块:stream 模块的配置块位于 stream 块内,用于配置 TCP 和 UDP 流量的代理、
负载均衡和路由规则等。

总体而言,upstream 模块用于处理 HTTP 流量,主要用于反向代理和负载均衡;
而 stream 模块用于处理 TCP 和 UDP 流量,可用于构建 TCP/UDP 代理和负载均衡器。
它们分别针对不同的流量类型提供了特定的功能和配置方式。

正向代理服务器test1:
server {
listen 80;
server_name localhost;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        root   html;
        index  index.html index.htm;
        proxy_pass http://192.168.233.62:8080; #配置代理地址
    }
    location ~ \.(gif|jpg|jepg|png|bmp|ico)$ {
        root html;
        expires 1d;

web服务器:
server {
listen 8080; #改监听地址
server_name www.nginx.com;
index index.html index.htm;
root html;
#charset koi8-r;

    access_log  logs/host.access.log  main;

    location ~ .*\.(jpg|gif|png)$ {
          root html;
    }

访问代理服务器可以跳转到web服务器
具体的原理如下:
客户端向 Nginx 发送请求:当客户端发送请求时,请求会首先到达 Nginx 反向代理服务器。

Nginx 将请求转发到后端服务器:Nginx 根据配置的负载均衡算法将请求转发到后端的一个或多个服务器上。

后端服务器处理请求并返回响应:后端服务器接收到请求后进行处理,并将响应返回给 Nginx 反向代理服务器。

Nginx 将响应返回给客户端:Nginx 接收到来自后端服务器的响应后,将响应返回给客户端。

在实现负载均衡的过程中,Nginx 通过以下两种方式进行后端服务器的选择:

IP Hash:Nginx 根据客户端 IP 的 hash 值选择一个后端服务器,保证同一个客户端的请求始终被转发到同一个后端服务器上,
确保会话的稳定性。

轮询:Nginx 轮流将请求转发到每个后端服务器上,从而实现简单的负载均衡。

此外,Nginx 还支持更加复杂的负载均衡算法,例如基于权重的负载均衡、最少连接数负载均衡等。
通过配置相应的负载均衡算法,可以根据具体的应用场景实现更加灵活和高效的负载均衡策略。

常见的负载均衡算法:

轮询(Round Robin)算法:轮询算法是最简单的负载均衡算法,它将请求轮流分配给后端服务器。
轮询算法适用于后端服务器的处理能力相近的情况。默认算法,可以不加

加权轮询(Weighted Round Robin)算法:加权轮询算法在轮询算法的基础上,为不同的后端服务器分配不同的权重值。
处理能力更强的后端服务器可以分配更高的权重值,从而可以更频繁地接收到请求。
weight

IP Hash算法:IP Hash算法根据客户端的IP地址计算hash值,然后将请求发送到相应的后端服务器。
使用IP Hash算法时,同一个客户端的请求会被分配到同一个后端服务器上,从而保证会话的稳定性。
ip_hash;

最少连接数(Least Connections)算法:最少连接数算法将请求发送到当前连接数最少的后端服务器上。
该算法适用于后端服务器处理任务耗时不同的情况,可以有效地避免请求集中在处理能力更强的后端服务器上的问题。
least_conn;

URL Hash算法:URL Hash算法根据请求的URL地址计算hash值,然后将请求发送到相应的后端服务器。
使用URL Hash算法时,相同URL的请求会被分配到同一个后端服务器上。
hash $request_uri consistent;

基于反向代理实现负载均衡:
基于http协议实现反向代理:

test1配置:
http {
include mime.types;
default_type application/octet-stream;
server_tokens off;
#log_format main '$remote_addr - r e m o t e u s e r [ remote_user [ remoteu?ser[time_local] “KaTeX parse error: Expected 'EOF', got '#' at position 16: request" ' #? …status b o d y b y t e s s e n t " body_bytes_sent " bodyb?ytess?ent"http_referer” ’
# ‘“ h t t p u s e r a g e n t " " http_user_agent" " httpu?sera?gent""http_x_forwarded_for”’;

#access_log  logs/access.log  main;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;
upstream ky30 {                          #这里是负载均衡配置upstream模块,ky30相当于负载均衡的方法名,可以自定义;
server 192.168.233.62:8080 weight=2;     #nginx反向代理负载均衡默认是轮询,不加weight,就是每个服务器一次,加了weight就是指每个服务器访问几次,但是不一定精确
server 192.168.233.63:8080 weight=1;
}
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        root   html;
        index  index.html index.htm;
        proxy_pass http://ky30;                 #这里配置代理地址,调用upstream模块,用ky30的方法;
    }

test2和test3做为web服务器的配置:
test2
server {
listen 8080;
server_name www.kgc.com;
echo this is test > index.html

test3
server {
listen 8080;
server_name www.kgc.com;
echo this is test1 > index.html

ip_hash的方法:
upstream ky30 {
ip_hash; #加上这个即可;
server 192.168.233.21:8080;
server 192.168.233.23:8080;
}
IP Hash算法会根据客户端的IP地址计算哈希值,以保证同一客户端的请求被分配到同一台后端服务器。
具体而言,Nginx会将客户端IP地址的32位二进制值进行哈希计算,得到一个整数值,
然后将这个值对后端服务器的总数进行取模运算,以确定将请求发送到哪一台后端服务器。

例如,假设有三台后端服务器,客户端IP地址为192.168.1.1,使用IP Hash算法计算哈希值的过程如下:

将客户端IP地址转换为32位二进制值:11000000 10101000 00000001 00000001

对这个二进制值进行哈希计算,得到一个整数值:3686790801

将这个整数值对后端服务器的总数(即3)进行取模运算,得到余数1,表示将请求发送到第2台后端服务器。

因此,使用IP Hash算法可以保证同一客户端的请求被发送到同一台后端服务器,从而实现了负载均衡。

需要注意的是,如果后端服务器的数量发生变化,哈希值的计算方式也会相应地改变,
从而可能导致部分请求被重新分配。

基于域名实现负载均衡:
http {
include mime.types;
default_type application/octet-stream;
server_tokens off;
#log_format main '$remote_addr - r e m o t e u s e r [ remote_user [ remoteu?ser[time_local] “KaTeX parse error: Expected 'EOF', got '#' at position 16: request" ' #? …status b o d y b y t e s s e n t " body_bytes_sent " bodyb?ytess?ent"http_referer” ’
# ‘“ h t t p u s e r a g e n t " " http_user_agent" " httpu?sera?gent""http_x_forwarded_for”’;

#access_log  logs/access.log  main;

sendfile        on;
#tcp_nopush     on;

#keepalive_timeout  0;
keepalive_timeout  65;

#gzip  on;

upstream ky30 {
server www.kgc.com:8080;
server www.benet.com:8080;
}
server {
    listen       80;
    server_name  www.12.cc; #通过test域名实现负载均衡

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        root   html;
        index  index.html index.htm;
        proxy_pass http://ky30;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

proxy_set_header Host $host;:将原始请求头中的Host字段的值赋给代理请求头中的Host字段。
这个指令非常重要,因为在HTTP/1.1协议中,客户端请求头中必须包含Host字段,否则会被视为无效请求。

proxy_set_header X-Real-IP $remote_addr;:将客户端的真实IP地址赋给代理请求头中的X-Real-IP字段。
这个指令的作用是在后端服务器中获取客户端的真实IP地址。

在61的操作
echo “192.168.233.61 www.12.cc” >> /etc/hosts

在62的操作
echo “192.168.233.62 www.kgc.com” >> /etc/hosts

在63的操作
echo “192.168.233.63 www.benet.com” >> /etc/hosts

客户机:
echo “192.168.233.61 www.12.cc” >> /etc/hosts

stream 模块的配置方法:
pid /usr/local/nginx/run/nginx.pid;

events {
worker_connections 1024;
}

stream {
upstream test {
server 192.168.233.62:80;
server 192.168.233.63:80;

}
server {

   listen 80;
   proxy_pass test;

}

}

http {
include mime.types;
default_type application/octet-stream;

#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
#                  '$status $body_bytes_sent "$http_referer" '
文章来源:https://blog.csdn.net/m0_65299341/article/details/135213317
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。