• 网络基础以及Nginx实现反向代理


    1. MAC地址、IP地址、TCP、UDP

    • MAC地址Media Access Control (MAC),是绑定到网卡上的固定地址,由12个16进制数组成,每两个一组,每组之间用冒号分隔(例如:2C:54:91:88:C9:E3)。MAC地址全球唯一,用以唯一标识一个网卡设备。在网络通信中,MAC地址是很重要的,在网络通信中,通过数据链路层的MAC地址定位到特定的网络设备。

    • IP地址:是用户分配给指定网卡的逻辑地址,不同于MAC地址,是网卡设备的生产厂商在出厂的时候就指定好的,IP地址则是由用户分配给网卡的。其工作在网络层,用于识别网络通信中特定的主机。目前的IP协议分为两种,IPv4协议以及IPv6协议,后者是考虑到前者的地址范围无法满足现今社会网络设备的爆发式增长带来的IP地址巨量需求,所以又制定了IPv6协议。IPv4协议由位长位32的数字组成,形式为点分十进制数组成,每8位位一组,每组之间用点号分隔(比如:192.168.122.221)。IPv6协议则由8组包含4个十六进制数组成,共计128位(比如:3001:0da8:75a3:0000:0000:8a2e:0370:7334),它提供的地址空间远远大于IPv4协议提供的地址空间。

      TCP/IP协议包头结构如下图所示:
      在这里插入图片描述

    • TCP协议Transmission Control Protocol (TCP),即传输控制协议,是工作在传输层的网络协议,在网络层的基础上可以确保可靠的网络数据包传输。TCP协议是面向连接的协议,所以在开始传数据之前,需要通过三次握手建立连接,此后才开始进行数据传输。TCP协议在传输数据的时候,可以确保数据包被接收方正确接收到,如果数据接收出现问题,发送端可以启动数据重发。通过这个机制,可以解决基于数据包的网络通信中的一些问题:比如丢包、包序错乱、重复发包、数据包损坏等问题。当数据传输完成之后,会通过四次挥手断开TCP连接。当数据到被送到传输层的时候,如果采用的是TCP协议,那么就会在这一层加上包头。TCP协议的包头共计占用4个字节(32位)。具体如下图所示:
      在这里插入图片描述

    • UDP协议User Datagram Protocol (UDP),即用户数据报协议,也是工作在传输层的网络协议,UDP协议是无连接协议,所以其虽然可以检测损坏的数据包,但是其并不会尝试解决这个问题,所以UDP通常被认为是不可靠链接(Unreliable Data Protocol)。UDP协议的包头(3个字节,共计32位)很简单,所以传输速度相对于TCP协议,也更快,对于传输过程中的数据可靠性要求不高,能够容忍数据传输过程中的丢包、乱序等问题,且要求数据传输效率的场景中,适合使用UDP协议传输数据。UDP协议的包头如下图所示:
      在这里插入图片描述

    2. 主机A向主机B发送数据包在网络上经过的各个步骤

    当主机A上的用户应用程序通过网络向主机B发送数据的时候,应用程序根据所使用的应用层协议确定通信端口以及传输协议(TCP/UDP)以及通信的目标主机IP地址。具体如下图所示:
    在这里插入图片描述
    在这里插入图片描述
    如果使用的是TCP协议进行数据传输,在开始发送数据之前,需要通过3次握手建立TCP连接,连接建立完成之后,将要发送的数据封装上TCP包头包尾。

    如果使用的是UDP协议进行数据传输,由于其是无连接协议,所以无需建立连接,封装是UDP协议包头包尾之后,即可直接向接收端发送数据包。

    然后将封装了传输层协议包头的数据包通过IP协议栈封装上IP包头形成IP数据报。

    上述传输过程如下图所示:
    在这里插入图片描述
    当IP数据报到达数据链路层和物理层的时候,将IP数据报的开头附加上帧头帧尾,将其格式化为数据帧,并在帧头中填入网卡的MAC地址。随后数据包从主机A的网卡送到路由器、交换机等设备,最终到达接收端的网卡。帧头的数据结构如下图所示:
    在这里插入图片描述

    3. nginx实现反向代理

    3.1. nginx安装

    在CentOS-7.6上通过yum命令安装nginx,为此需要向系统中添加yum镜像源。具体如下所示:

    [root@c7u6s8:~]# cat >> /etc/yum.repos.d/nginx.repo << EOF
    > [nginx-stable]
    > name=nginx stable repo
    > baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    > gpgcheck=1
    > enabled=1
    > gpgkey=https://nginx.org/keys/nginx_signing.key
    > module_hotfixes=true
    >
    > [nginx-mainline]
    > name=nginx mainline repo
    > baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
    > gpgcheck=1
    > enabled=0
    > gpgkey=https://nginx.org/keys/nginx_signing.key
    > module_hotfixes=true
    > EOF
    [root@c7u6s8:~]#
    [root@c7u6s8:~]# cat /etc/yum.repos.d/nginx.repo
    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos///
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=http://nginx.org/packages/mainline/centos///
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    默认情况下,nginx镜像源使用stable版本,如果要使用mainline版本的软件包,可以执行命令sudo yum-config-manager --enable nginx-mainline启用mainline版本。

    配置好镜像源之后,yum makecahe创建本地缓存,然后就可以执行安装命令了。具体如下所示:

    [root@c7u6s8:~]# yum makecache
    ...
    http://nginx.org/packages/centos///repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found
    
    • 1
    • 2
    • 3

    上述命令执行的时候提示nginx镜像源无法解析额。切换为USTC的镜像源之后,问题解决,具体如下所示:

    [root@c7u6s8:~]# !vim
    vim /etc/yum.repos.d/nginx.repo
    [root@c7u6s8:~]# cat /etc/yum.repos.d/nginx.repo
    [nginx-stable]
    name=nginx stable repo
    # baseurl=http://nginx.org/packages/centos///
    baseurl=https://mirrors.ustc.edu.cn/nginx/centos/7/x86_64/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=https://mirrors.ustc.edu.cn/nginx/centos/7/x86_64/
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    [root@c7u6s8:~]#
    [root@c7u6s8:~]# yum makecache
    [root@c7u6s8:~]# yum repoinfo nginx-stable
    Loaded plugins: fastestmirror, langpacks
    Loading mirror speeds from cached hostfile
     * base: mirrors.huaweicloud.com
     * epel: mirror.lzu.edu.cn
     * extras: ftp.sjtu.edu.cn
     * updates: ftp.sjtu.edu.cn
    Repo-id      : nginx-stable
    Repo-name    : nginx stable repo
    Repo-status  : enabled
    Repo-revision: 1640782175
    Repo-updated : Wed Dec 29 20:49:36 2021
    Repo-pkgs    : 258
    Repo-size    : 135 M
    Repo-baseurl : https://mirrors.ustc.edu.cn/nginx/centos/7/x86_64/
    Repo-expire  : 21,600 second(s) (last: Mon Jan 24 14:17:48 2022)
      Filter     : read-only:present
    Repo-filename: /etc/yum.repos.d/nginx.repo
    
    repolist: 258
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    接下来安装nginx软件包,具体如下所示:

    [root@c7u6s8:~]# yum info nginx
    Loaded plugins: fastestmirror, langpacks
    Loading mirror speeds from cached hostfile
     * base: mirrors.huaweicloud.com
     * epel: mirror.lzu.edu.cn
     * extras: ftp.sjtu.edu.cn
     * updates: ftp.sjtu.edu.cn
    Available Packages
    Name        : nginx
    Arch        : x86_64
    Epoch       : 1
    Version     : 1.20.2
    Release     : 1.el7.ngx
    Size        : 790 k
    Repo        : nginx-stable
    Summary     : High performance web server
    URL         : https://nginx.org/
    License     : 2-clause BSD-like license
    Description : nginx [engine x] is an HTTP and reverse proxy server, as well as
                : a mail proxy server.
    
    [root@c7u6s8:~]#
    [root@c7u6s8:~]# yum install -y nginx
    [root@c7u6s8:~]# rpm -q nginx
    nginx-1.20.2-1.el7.ngx.x86_64
    [root@c7u6s8:~]# rpm -qi nginx
    Name        : nginx
    Epoch       : 1
    Version     : 1.20.2
    Release     : 1.el7.ngx
    Architecture: x86_64
    Install Date: Mon 24 Jan 2022 02:23:59 PM CST
    Group       : System Environment/Daemons
    Size        : 2891487
    License     : 2-clause BSD-like license
    Signature   : RSA/SHA1, Tue 16 Nov 2021 11:20:17 PM CST, Key ID abf5bd827bd9bf62
    Source RPM  : nginx-1.20.2-1.el7.ngx.src.rpm
    Build Date  : Tue 16 Nov 2021 11:03:33 PM CST
    Build Host  : ip-10-1-17-130.eu-central-1.compute.internal
    Relocations : (not relocatable)
    Vendor      : NGINX Packaging <nginx-packaging@f5.com>
    URL         : https://nginx.org/
    Summary     : High performance web server
    Description :
    nginx [engine x] is an HTTP and reverse proxy server, as well as
    a mail proxy server.
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    上述就完成了nginx-1.20的安装。

    安装好nginx之后,启动nginx服务,并进行访问测试,具体如下所示:

    [root@c7u6s8:~]# systemctl status nginx
    ● nginx.service - nginx - high performance web server
       Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
       Active: inactive (dead)
         Docs: http://nginx.org/en/docs/
    [root@c7u6s8:~]# systemctl enable --now nginx
    Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
    [root@c7u6s8:~]# systemctl status nginx
    ● nginx.service - nginx - high performance web server
       Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
       Active: active (running) since Mon 2022-01-24 14:30:51 CST; 3s ago
         Docs: http://nginx.org/en/docs/
      Process: 23360 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
     Main PID: 23361 (nginx)
        Tasks: 4
       Memory: 2.7M
       CGroup: /system.slice/nginx.service
               ├─23361 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
               ├─23362 nginx: worker process
               ├─23363 nginx: worker process
               └─23364 nginx: worker process
    
    Jan 24 14:30:51 c7u6s8 systemd[1]: Starting nginx - high performance web server...
    Jan 24 14:30:51 c7u6s8 systemd[1]: Started nginx - high performance web server.
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    命令行访问nginx的web服务,具体如下所示:

    [root@c7u6s8:~]# curl localhost
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    nginx服务已经正确启动。

    3.2. nginx实现反向代理

    正向代理(proxy)是为客户端配置的,其目的是为客户端实现隐私以及内容过滤;反向代理(reverse proxy)是为服务器配置的,其目的是拦截客户端到服务器的流量,将流量路由到其代理的其他服务器上,并将服务器的返回数据回传给客户端。

    如果有多个服务器对外提供服务,那么通过反向代理,可以实现流量的负载均衡,从而在一定程度上提升性能,除此之外,还可以缓存经常被访问的内容以及额外的安全层。不过缺点是反向代理服务器直接面对客户端,从而易形成单点故障。

    nginx反向代理的示意图如下所示:
    在这里插入图片描述

    3.2.1. 服务器角色信息

    要实现nginx的反向代理,此处使用nginx反向代理http的web服务。要完成这个实验,此处使用三台虚拟机,其中两台虚拟机作为后端web服务器,另外一台虚拟机作为nginx反向代理服务器;另外使用宿主机作为客户端,进行反向代理测试。

    虚拟机以及宿主机的配置信息如下表所示:

    Server RoleServer NameOS ReleaseIP AddressRunning ServicePort Num
    Nginx反向代理服务器c7u6s8CentOS-7.6 x64192.168.122.27nginx-1.2080
    后端Web服务器c7u6s9CentOS-7.6 x64192.168.122.28httpd-2.4.680
    后端Web服务器c7u6s10CentOS-7.6 x64192.168.122.29httpd-2.4.680
    客户端u20u04m1Ubuntu-20.04 x64192.168.1.107curl-7.68/

    在上述的服务器中,只有客户端不需要进行配置。剩下的三个服务器都需要进行必要的配置。

    3.2.2. http后端web服务器配置

    本实验中,使用c7u6s9和c7u6s10这两台服务器作为后端web服务器,为此需要在这两台服务器上安装httpd软件包,并且启动相应的服务。

    通过yum命令安装httpd软件包,具体如下所示:

    [root@c7u6s9:~]# yum install -y httpd
    [root@c7u6s9:~]# rpm -q httpd
    httpd-2.4.6-97.el7.centos.2.x86_64
    
    • 1
    • 2
    • 3

    软件包安装完成之后,启动httpd服务,具体如下所示:

    [root@c7u6s9:~]# systemctl status httpd
    ● httpd.service - The Apache HTTP Server
       Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
       Active: inactive (dead)
         Docs: man:httpd(8)
               man:apachectl(8)
    [root@c7u6s9:~]# systemctl enable --now httpd
    Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
    [root@c7u6s9:~]# systemctl status httpd
    ● httpd.service - The Apache HTTP Server
       Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
       Active: active (running) since Mon 2022-01-24 16:21:49 CST; 4s ago
         Docs: man:httpd(8)
               man:apachectl(8)
     Main PID: 3817 (httpd)
       Status: "Processing requests..."
       CGroup: /system.slice/httpd.service
               ├─3817 /usr/sbin/httpd -DFOREGROUND
               ├─3818 /usr/sbin/httpd -DFOREGROUND
               ├─3819 /usr/sbin/httpd -DFOREGROUND
               ├─3820 /usr/sbin/httpd -DFOREGROUND
               ├─3821 /usr/sbin/httpd -DFOREGROUND
               └─3822 /usr/sbin/httpd -DFOREGROUND
    
    Jan 24 16:21:49 c7u6s9 systemd[1]: Starting The Apache HTTP Server...
    Jan 24 16:21:49 c7u6s9 httpd[3817]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.122.28. Set the 'ServerName' directiv... this message
    Jan 24 16:21:49 c7u6s9 systemd[1]: Started The Apache HTTP Server.
    Hint: Some lines were ellipsized, use -l to show in full.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    至此,服务已经启动,接下来自定义主页的内容。具体如下所示:

    [root@c7u6s9:~]# echo 'Web Server1 on 192.168.122.28' > /var/www/html/index.html
    [root@c7u6s9:~]# curl localhost
    Web Server1 on 192.168.122.28
    
    • 1
    • 2
    • 3

    上述就完成了后端web服务器的配置,在c7u6s10上执行相同的操作步骤即可,此处省略。

    3.2.3. nginx反向代理服务器配置

    本实验中使用c7u6s8这个节点作为反向代理服务器,所以需要在其上安装nginx-1.20软件包,并且修改配置文件,启动nginx服务。

    前面的3.1节中已经安装了nginx软件包,并且启动了服务,接下来只需要准备好反向代理相关的配置文件即可。

    nginx的默认配置文件路径如下所示:

    [root@c7u6s8:~]# ls /etc/nginx/ -F
    conf.d/  fastcgi_params  mime.types  modules@  nginx.conf  scgi_params  uwsgi_params
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3

    上述路径中的nginx.conf是默认的主配置文件;conf.d/目录是自定义配置文件的路径。接下来就会将增加的反向代理配置文件加到conf.d/这个目录中。配置文件的内容如下所示:

    [root@c7u6s8:~]# vim /etc/nginx/conf.d/reverse_proxy_2webs.conf
    [root@c7u6s8:~]# cat /etc/nginx/conf.d/reverse_proxy_2webs.conf
    upstream webserver {
        server 192.168.122.28:80 weight=1 fail_timeout=5s max_fails=3;    # backserver monitor
        server 192.168.122.29:80 weight=1 fail_timeout=5s max_fails=3;
    }
    
    server {
        listen 80;
        server_name www.penguin.org;
    
        location / {
            index index.html index.php;
            root /data/nginx/html;
        }
    
        location /mainpage {
            index index.html;
            proxy_pass http://webserver/;    # 反向代理
        }
    }
    [root@c7u6s8:~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    修改完上述配置文件之后,执行测试,如果测试通过,则重载配置文件。具体如下所示:

    [root@c7u6s8:~]# nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful
    [root@c7u6s8:~]# nginx -s reload
    
    • 1
    • 2
    • 3
    • 4

    至此,nginx反向代理服务器也就配置完成了。

    3.2.4. 客户端配置

    此时客户端还不能使用www.penguin.org这个主机名进行web访问,因为此时系统还无法解析这个主机名。要么为这个域名配置DNS服务,增加对应的记录;要么采用更简单的方法,就是编辑***/etc/hosts***这个配置文件,在nginx反向代理服务器的对应IP地址后面增加一项主机名即可。具体如下所示:

    root@u20u04m1:~$ vim /etc/hosts
    root@u20u04m1:~$ cat /etc/hosts | egrep penguin
    192.168.122.27  c7u6s8  www.penguin.org
    root@u20u04m1:~$
    
    • 1
    • 2
    • 3
    • 4

    此时就可以使用www.penguin.org这个主机名,通过访问反向代理服务器,进而获取到后端web服务器的内容了。具体测试如下所示:

    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server1 on 192.168.122.28
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server1 on 192.168.122.28
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server2 on 192.168.122.29
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server1 on 192.168.122.28
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server1 on 192.168.122.28
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server2 on 192.168.122.29
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server1 on 192.168.122.28
    root@u20u04m1:~$ curl www.penguin.org/mainpage
    Web Server2 on 192.168.122.29
    root@u20u04m1:~$
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    从上述的测试中可以看出,客户端的访问请求被调度到两个后端服务器上。

    4. References

    [1]. Transmission Control Protocol (TCP)
    [2]. User Datagram Protocol (UDP)
    [3]. How the TCP/IP Protocols Handle Data Communications
    [4]. TCP/IP Packet Headers
    [5]. Ethernet Frame Format
    [6]. What is Address Resolution Protocol (ARP)?
    [7]. nginx: Linux packages

  • 相关阅读:
    Unity使用新输入系统InputSystem制作飞机大战Demo(实现生命系统等)
    vue页面跳转
    《最新出炉》系列初窥篇-Python+Playwright自动化测试-3-离线搭建playwright环境
    【JavaEE】 饿汉模式与懒汉模式详解与实现
    java-net-php-python-ssm电影影评网站计算机毕业设计程序
    【电商运营】社交媒体营销策略该如何制定?
    【数字图像处理】Gamma 变换
    假结婚取得北京户口,效力如何认定
    百度指数 Cipher-Text、百度翻译 Acs-Token 逆向分析
    ELK运维文档
  • 原文地址:https://blog.csdn.net/ikkyphoenix/article/details/125881143