学静思语
Published on 2025-02-15 / 0 Visits
0
0

Nginx【反向代理、负载均衡、动静分离】

Nginx【反向代理、负载均衡、动静分离】

一、基本介绍

1. Nginx是什么?能干什么?

  • 是什么
  • Nginx(“engine x”)是一个高性能的HTTP和反向代理WEB服务器
  • 能干什么
  • 反向代理
  • 负载均衡
  • 动静分离
  • 厉害之处
  • 高性能
  • 高负载
  • 有报告表明能支持高达50000个并发连接数
  • 详细说明:https://lnmp.org/nginx.html

2.官方资料

  • 官网:https://nginx.org/
  • 使用文档:https://nginx.org/en/docs/

二、Nginx核心功能

1.正向代理

  • 一句话:如果我们要访问www.google.com 但是直接访问不到,则需要通过代理服 务器来访问,这种代理服务就称为正向代理

  • 正向代理:如科学上网,隐藏客户端信息

  • 解读

  • 我们知道www.google.com,但是访问不到

  • 所以使用代理服务器帮助我们(即客户端)来上网,注意帮助的对象是客户端,这种代理,我们称为正向代理

  • 正向代理同时也隐藏了客户端信息

  • 再次说明,正向代理帮助的是客户端,因此可以把 客户端+正向代理服务,视为一个整体

2.反向代理

  • 一句话:客户端将请求发送到代理服务器,由代理服务器去选择目标服务器获取数 据后,返回给客户端,这种代理方式为反向代理
  • 反向代理:屏蔽内网服务器信息,负载均衡访问

  • 解读
  • 项目设计者,不希望客户端直接访问目标Web服务器(比如目标Web服务器是集群,如果直接访问就会提供多个公网IP),而是希望提供一个统一的访问IP,这个是理解反向代理的前提,即为什么要反向代理
  • 反向代理帮助的对象是目标Web服务器
  • 当客户端请求达到反向代理服务后,由反向代理服务来决定如何访问目标Web服务器 (或者是哪个Web服务器),这个过程对客户端是透明的
  • 反向代理服务会暴露公共的IP,只要能上网,就可以访问,但是对于反向代理服务器管理的/代理的 Web服务器通常是在局域网内,不能直接访问,只能通过反向代理来访问
  • 我们可以将反向代理服务+反向代理服务代理的Web服务器视为一个整体
  • 反向代理会屏蔽内网服务器(也就是他代理的服务)信息,并实现负载均衡访问

3.负载均衡

  • 一句话:当客户端向反向代理服务器(比如Nginx)发出请求,如果Nginx代理了多个 WEB服务器(集群),Nginx会将请求/负载分发到不同的服务器,也就是负载均衡

  • 示意图

    image-20241013151042445

4.动静分离

  • 一句话:为了加快网站的解析速度,可以把动态资源和静态资源由不同的服务器来 解析,降低单个服务器的压力

  • 传统的项目资源部署

    image-20241013152132650

  • 动静分离项目资源部署

    image-20241013152202933

三、Nginx下载和安装以及启动

1. 下载

  • 下载网址:https://nginx.org/en/download.html
  • 版本:nginx-1.20.2.tar.gz

2. 安装

2.1首先是需要安装Linux系统

2.2 具体安装

  • 搭建gcc环境,指令

    yum -y install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
    
  • 本次使用的CentOS8版本,在使用如下指令时遇到报错

    yum -y install gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel
    
    • 报错图

      image-20241013162936972

    • 解决方案

    • 首先可以去换一下yum源,如果换源后运行指令

      yum makecache
      
      • 报如下错误,则参考下面网址方案进行解决

      image-20241013163121467

    • 网址:https://blog.csdn.net/qeqpoququtt/article/details/122855846

  • 提示1:一定要保证当前的linux系统,可以连接外网,因为yum需要到外网,获取数据

  • 提示2: 如何在 Linux 配置网络,可以连接到外网,参考视频 (https://www.bilibili.com/video/BV1Sv411r7vd?p=63).

  • 提示3: 执行上面指令的时候,可能会报CentosAnotherappiscurrentlyholdingtheyumlock..错误,是因为yum不时会自动升级, 占用了端口或文件。

    • 解决方案
    • (1)可以重启Linux,立即执行该指令
    • (2)或者等一会再执行
    • (3) 或者参考 https://www.cnblogs.com/lzxianren/p/4254059.html
  • 将nginx-1.20.2.tar.gz 上传到 Linux /opt 目录

  • 切换到/opt目录, 解压nginx-1.20.2.tar.gz,指令:

    tar -zxvf nginx-1.20.2.tar.gz
    
  • 将解压后的文件放到指定位置

    mv nginx-1.20.2 /usr/local/nginx
    
  • 进入文件目录

    cd /usr/local/nginx
    
  • 配置nginx路径

    ./configure --prefix=/usr/local/nginx 
    --pid-path=/var/run/nginx/nginx.pid 
    --lock-path=/var/lock/nginx.lock 
    --error-log-path=/var/log/nginx/error.log 
    --http-log-path=/var/log/nginx/access.log 
    --with-http_gzip_static_module 
    --http-client-body-temp-path=/var/temp/nginx/client 
    --http-proxy-temp-path=/var/temp/nginx/proxy
    --http-fastcgi-temp-path=/var/temp/nginx/fastcgi 
    --http-uwsgi-temp-path=/var/temp/nginx/uwsgi 
    --http-scgi-temp-path=/var/temp/nginx/scgi 
    --conf-path=/usr/local/nginx/nginx.conf
    
  • 补全nginx配置目录

    mkdir /var/temp/nginx -p
    
  • 编译并安装,需要在/usr/local/nginx下进行

    make && make install
    
  • 测试配置与nginx是否正常,当出现successful即可

    ./sbin/nginx -t
    

    image-20241013173757884

  • 启动nginx

    ./sbin/nginx -c nginx.conf
    
  • 查看进程/或端口(默认端口是80)

    ps -ef | grep nginx
    

    image-20241013174055880

2.3启动Nginx 可能的错误 和解决方案

  • 解决nginx 启动报错nginx:[emerg] open() “/var/run/nginx/nginx.pid” failed (2: No such file or directory)

  • 解决方法

  • 进入nginx.conf配置文件:指令

    cd /usr/local/nginx/conf/
    vim nginx.conf
    

    image-20241013201528060

  • 将注释解开,键入i修改自定义 logs/nginx.pid目录路径

  • 修改为pid /usr/local/nginx/logs/nginx.pid

  • 键Esc进入命令模式,键入:wq保存退出

  • 在/usr/local/nginx,目录下创建logs目录

    mkdir /usr/local/nginx/logs
    
  • 启动nginx

    /usr/local/nginx/sbin/nginx -c nginx.conf
    

3. 验证是否安装成功

  • Nginx默认端口是80

  • 在浏览器输入http://localhost,看是否会出现界面

    image-20241013202459379

4. 配置防火墙,让Windows访问Nginx

  • 说明:默认情况下 Windows 是不能访问Nginx, 因为防火墙是关闭80端口的

  • 具体配置

  • 查看开放的端口号

    firewall-cmd --list-all
    

    image-20241013202736421

  • 设置开放端口

    firewall-cmd --add-service=http --permanent #增加Http服务,默认会监听80端口
    firewall-cmd --add-port=80/tcp --permanent
    
  • 重启防火墙

    firewall-cmd --reload
    
  • 防火墙配置,可参考视频: https://www.bilibili.com/video/BV1Sv411r7vd?p=77

  • 在Windows系统测试连接:http://192.168.180.130

四、Nginx命令行参数

1. 指令说明

  • 网址:https://nginx.org/en/docs/switches.html

2. 使用演示

  • 启动

    /usr/local/nginx/sbin/nginx -c nginx.conf
    
  • 停止

    /usr/local/nginx/sbin/nginx -s stop
    
  • 重新加载(不需要重启)

    /usr/local/nginx/sbin/nginx -s reload
    
  • 查看版本

    /usr/local/nginx/sbin/nginx -v
    
  • 查看版本、配置参数

    /usr/local/nginx/sbin/nginx -V
    

五、nginx.conf配置文件

1.基本说明

  • Nginx 的配置文件位置

  • 文件位置

    • 安装目录/conf/nginx.conf
    • 安装目录/nginx.conf
  • 两个文件是一样的

  • 使用/usr/local/nginx/sbin/nginx启动Nginx,默认用的是安装目录 \nginx.conf配置文件

  • 作用:完成对Nginx的各种配置,包括端口,并发数,重写规则等

  • nginx.conf组成

  • 全局块

  • events块

  • http块

  • nginx.conf详细文档

  • 文档地址:https://blog.csdn.net/liuchang19950703/article/details/110792007

  • 详细内容

    #Nginx用户及组:用户 组。window下不指定
    #user  nobody;
    
    #工作进程:数目。根据硬件调整,通常等于CPU数量或者2倍于CPU。
    worker_processes  1;
    
    #错误日志:存放路径。
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid(进程标识符):存放路径
    pid       /usr/local/nginx/logs/nginx.pid;
    
    #一个进程能打开的文件描述符最大值,理论上该值因该是最多能打开的文件数除以进程数。
    #但是由于nginx负载并不是完全均衡的,所以这个值最好等于最多能打开的文件数。
    #LINUX系统可以执行 sysctl -a | grep fs.file 可以看到linux文件描述符。
    worker_rlimit_nofile 65535;
    
    
    events {
        #使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。
        use epoll;
    
        #单个进程最大连接数(最大连接数=连接数*进程数)
        worker_connections  1024;
    
        #客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,
        #一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
        #client_header_buffer_size 4k;
    }
    
    
    http {
        #设定mime类型,类型由mime.type文件定义
        include       mime.types;
    
        default_type  application/octet-stream;
    
        #日志格式设置
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
    
        #用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径
        #记录了哪些用户,哪些页面以及用户浏览器、ip和其他的访问信息
        #access_log  logs/host.access.log  main;
        #access_log  logs/host.access.404.log  log404;
    
        #服务器名字的hash表大小
        server_names_hash_bucket_size 128;
    
        #客户端请求头缓冲大小。
        #nginx默认会用client_header_buffer_size这个buffer来读取header值,
        #如果header过大,它会使用large_client_header_buffers来读取。
        #如果设置过小HTTP头/Cookie过大 会报400 错误 nginx 400 bad request
        #如果超过buffer,就会报HTTP 414错误(URI Too Long)
        #nginx接受最长的HTTP头部大小必须比其中一个buffer大
        #否则就会报400的HTTP错误(Bad Request)
        #client_header_buffer_size 32k;
        #large_client_header_buffers 4 32k;
    
    
        #隐藏ngnix版本号
        #server_tokens off;
    
        #忽略不合法的请求头
        #ignore_invalid_headers   on;
    
        #让 nginx 在处理自己内部重定向时不默认使用  server_name设置中的第一个域名
        #server_name_in_redirect off;
    
    
        #客户端请求体的大小
        #client_body_buffer_size    8m;
    
    
        #开启文件传输,一般应用都应设置为on;若是有下载的应用,则可以设置成off来平衡网络I/O和磁盘的I/O来降低系统负载
        sendfile        on;
    
    
        #告诉nginx在一个数据包里发送所有头文件,而不一个接一个的发送。
        #tcp_nopush     on;
    
        #tcp_nodelay off 会增加通信的延时,但是会提高带宽利用率。在高延时、数据量大的通信场景中应该会有不错的效果
        #tcp_nodelay on,会增加小包的数量,但是可以提高响应速度。在及时性高的通信场景中应该会有不错的效果
        tcp_nodelay on;
    
    
        #长连接超时时间,单位是秒
        keepalive_timeout  65;
    
        #gzip模块设置,使用 gzip 压缩可以降低网站带宽消耗,同时提升访问速度。
        #gzip  on;                     #开启gzip
        #gzip_min_length  1k;          #最小压缩大小
        #gzip_buffers     4 16k;       #压缩缓冲区
        #gzip_http_version 1.0;        #压缩版本
        #gzip_comp_level 2;            #压缩等级
        #gzip_types   text/plain text/css text/xml text/javascript application/json application/x-javascript application/xml application/xml+rss;#压缩类型
    
    
    
    
        #负载均衡
        #max_fails为允许请求失败的次数,默认为1
        #weight为轮询权重,根据不同的权重分配可以用来平衡服务器的访问率。
        # upstream myServer{
        #   server  192.168.247.129:8080 max_fails=3 weight=2;
        #   server  192.168.247.129:8081 max_fails=3 weight=4;  
        # }
    
    
    
        #server {
        #    listen       80;
        #   
        #   #IP/域名可以有多个,用空格隔开
        #   server_name  192.168.247.129;
        #   #server_name  www.test.com;
        #
        #    #charset koi8-r;
        #
        #    #access_log  logs/host.access.log  main;
        #   
        #   #反向代理配置,
        #   #将所有请求为www.test.com的请求全部转发到upstream中定义的目标服务器中。
        #   location / {
        #               
        #       #此处配置的域名必须与upstream的域名一致,才能转发。
        #       proxy_pass http://myServer;
        #       #proxy_pass http://192.168.247.129:8080;
        #       
        #        proxy_connect_timeout 20;          #nginx跟后端服务器连接超时时间(代理连接超时)
        #       
        #        #client_max_body_size       10m;   #允许客户端请求的最大单文件字节数
        #        #client_body_buffer_size    128k;  #缓冲区代理缓冲用户端请求的最大字节数
        #        #proxy_send_timeout         300;   #后端服务器数据回传时间(代理发送超时)
        #        #proxy_read_timeout         300;   #连接成功后,后端服务器响应时间(代理接收超时)
        #        #proxy_buffer_size          4k;    #设置代理服务器(nginx)保存用户头信息的缓冲区大小
        #        #proxy_buffers              4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
        #        #proxy_busy_buffers_size    64k;   #高负荷下缓冲大小(proxy_buffers*2)
        #        #proxy_temp_file_write_size 64k;   #设定缓存文件夹大小,大于这个值,将从upstream服务器传         
        #       
        #       root   html;
        #       
        #       #定义首页索引文件的名称
        #       index  index.html index.htm;
        #    }
        #
        #   #动静分离 静态资源走linux 动态资源走tomcat
        #   # 注意 /source/image/下面寻找资源
        #   location /image/ {
        #       root /source/;
        #       autoindex on;
        #   }       
        #
        #
        #    # 出现50x错误时,使用/50x.html页返回给客户端
        #    error_page   500 502 503 504  /50x.html;
        #    location = /50x.html {
        #        root   html;
        #    }
        #}
    
    
    
        #下面是配置生产环境中既支持HTTP又支持HTTPS,保证用户在浏览器中输入HTTP也能正常访问
    
        # SSL证书 配置                                 
        ssl_certificate         cert/yphtoy.com.pem;   #加密证书路径
        ssl_certificate_key cert/yphtoy.com.key;       #加密私钥路径
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;     #加密协议
        ssl_session_cache   shared:SSL:1m;             #加密访问缓存设置,可以大大提高访问速度
        ssl_session_timeout 10m;                       #加密访问缓存过期时间
        ssl_ciphers     HIGH:!aNULL:!MD5;              #加密算法
        ssl_prefer_server_ciphers on;                  #是否由服务器决定采用哪种加密算法
    
        # 负载均衡
        upstream api_upstream
        {
            server 127.0.0.1:8080 max_fails=3 weight=1;
            server 127.0.0.1:8081 max_fails=3 weight=1;
        }
    
        #api 接口(兼容HTTP)
        server{
            listen 80;
            server_name api.test.com;
            # 301重定向跳转到HTTPS接口
            return 301 https://$server_name$request_uri;
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
        }
    
        #api 接口(兼容HTTPS)
        server{
            listen 443 ssl;
            server_name api.test.com;
            location / {
               root html;
               index  index.html index.htm;
               proxy_pass http://api_upstream;
    
               #语法: proxy_cookie_path oldpath replacepath;
               #oldpath就是你要替换的路径 replacepath 就是要替换的值
               #作用:同一个web服务器下面多个应用之间能获取到cookie
               proxy_cookie_path /api/ /;
    
               #服务端接收的请求头Cooke值不变
               proxy_set_header Cookie $http_cookie;
            }
        }
    
        #管理后台端(兼容HTTP)
        server{
            listen 80;
            server_name manage.test.com;
            # 301重定向跳转到HTTPS接口
            return 301 https://$server_name/$request_uri;
            error_page 500 502 503 504 /50x.html;
            location = /50x.html{
                 root html  
            }
        }
    
        #管理后台端(兼容HTTPS)
        server{
            listen 443 ssl;
            server_name manage.test.com;
            location / {
                root /home/test/web/dist
    
                index /index.html;
    
    
                #语法:try_files 【$uri】 【 $uri/】 【参数】
                #当用户请求https://manage.test.com/login时,
                #一.如果配置了上面的默认index,会依次请求
                #1./home/test/web/dist/login       查找有没有login这个文件,没有的话
                #2./home/test/web/dist/index.html  有就直接返回
    
                #二.如果没有配置了上面的默认index或者配置了没有找到对应的资源,会依次请求
                #1./home/test/web/dist/login        查找有没有login这个文件,没有的话
                #2./home/test/web/dist/login/       查找有没有login这个目录,没有的话
                #3.请求https://manage.test.com/index.html  nginx内部做了一个子请求
    
                #三.总的来说,index的优先级比try_files高,请求会先去找index配置,这里最后一个参数必须存在
                try_files $uri $uri/ /index.html;   
    
    
    
                #解决跨域问题
                #允许跨域请求地址(*表示全部,但是无法满足带cookie请求,因为cookie只能在当前域请求)
                add_header Access-Control-Allow-Origin $http_origin;
                #允许接收cookie和发送cookie
                add_header Access-Control-Allow-Credentials 'true';
                #允许请求的方法
                add_header Access-Control-Allow-Methods 'GET,POST,DELETE,PUT,OPTIONS';
                #允许请求头(Content-Type:请求数据/媒体类型 x-requested-with:判断请求是异步还是同步 自定义header 比如 token)
                add_header Access-Control-Allow-Headers $http_access_control_request_headers;
                #浏览器缓存请求头信息,1800秒内,只会有1次请求,不会出现"OPTIONS"预请求,节约资源
                #add_header Access-Control-Max-Age '1800';
                if ($request_method = 'OPTIONS') {
                        return 204;
                }
    
    
                #服务端HttpServletRequest可以获得用户的真实ip
                proxy_set_header X-Real-IP $remote_addr;
    
                #服务端HttpServletRequest可以获得用户的真实ip和经过的每一层代理服务器的ip
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
                #服务端接收的请求头Host值不变
                proxy_set_header Host  $http_host;
    
                proxy_set_header X-Nginx-Proxy true;
            }
        }
    
    
    
    
    }
    

2.nginx.conf讲解

  • 一张图说明nginx.conf结构

  • 看一下/usr/local/nginx/conf/nginx.conf

    #user  nobody;
    worker_processes  1;
    
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    
    
    events {
      worker_connections  1024;
    }
    
    
    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" '
      #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
      #access_log  logs/access.log  main;
    
      sendfile        on;
      #tcp_nopush     on;
    
    #keepalive_timeout  0;
      keepalive_timeout  65;
    
      #gzip  on;
    
      server {
          listen       80;
          server_name  localhost;
    
          #charset koi8-r;
    
          #access_log  logs/host.access.log  main;
    
          location / {
              root   html;
              index  index.html index.htm;
          }
    
          #error_page  404              /404.html;
    
          # redirect server error pages to the static page /50x.html
          #
          error_page   500 502 503 504  /50x.html;
          location = /50x.html {
              root   html;
          }
    
        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
          #
          #location ~ \.php$ {
          #    proxy_pass   http://127.0.0.1;
          #}
    
          # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
          #
          #location ~ \.php$ {
          #    root           html;
          #    fastcgi_pass   127.0.0.1:9000;
          #    fastcgi_index  index.php;
          #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
          #    include        fastcgi_params;
          #}
    
          # deny access to .htaccess files, if Apache's document root
          # concurs with nginx's one
          #
          #location ~ /\.ht {
          #    deny  all;
          #}
      }
    
    
      # another virtual host using mix of IP-, name-, and port-based configuration
      #
      #server {
      #    listen       8000;
      #    listen       somename:8080;
      #    server_name  somename  alias  another.alias;
    
      #    location / {
      #        root   html;
      #        index  index.html index.htm;
      #    }
      #}
    
    
      # HTTPS server
      #
      #server {
      #    listen       443 ssl;
      #    server_name  localhost;
    
      #    ssl_certificate      cert.pem;
      #    ssl_certificate_key  cert.key;
    
      #    ssl_session_cache    shared:SSL:1m;
      #    ssl_session_timeout  5m;
    
      #    ssl_ciphers  HIGH:!aNULL:!MD5;
      #    ssl_prefer_server_ciphers  on;
    
      #    location / {
      #        root   html;
      #        index  index.html index.htm;
      #    }
      #}
    
    }                                                                           
    
  • 全局块

  • 说明

    • 从配置文件开始到events块之间的内容

    • 主要会设置一些影响nginx服务器整体运行的配置指令,主要包括配置运行Nginx 服务器的用户(组)、允许生成的worker process数,进程PID存放路径、日志存放路径 和类型以及配置文件的引入等

  • 简单分析

    • 这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持 的并发处理量也越多,但是会受到硬件、软件等设备的制约

    • 配置举例

      worker_processes  1;
      
  • events块

  • 说明

    • events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接
    • 常用的设置包括是否开启对多 workprocess 下的网络连接进行序列化,是否允许同时 接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 workprocess 可以同 时支持的最大连接数等
  • 简单分析

    • 上述例子就表示每个 workprocess 支持的最大连接数为 1024, 这部分的配置对 Nginx 的性能影响较大,在实际中应根据实际情况配置

    • 配置举例

      events {
        worker_connections  1024;
      }
      
  • http块

  • 说明

    • 这是 Nginx 服务器配置中最复杂的部分,代理、缓存和日志定义等绝大多数功能和第 三方模块的配置都在这里
    • http 块也可以包括 http 全局块、server 块
  • http全局块

    • http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单连接请求数上限等

    • 配置举例

      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" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
      
        #access_log  logs/access.log  main;
      
        sendfile        on;
        #tcp_nopush     on;
      
        #keepalive_timeout  0;
        keepalive_timeout  65;
      
        #gzip  on;
      }
      
  • server块

    • 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全 一样的,该技术的产生是为了节省互联网服务器硬件成本。

    • 每个http块可以包括多个server块,而每个server块就相当于一个虚拟主机。

    • 每个server块也分为全局server块,以及可以同时包含多个location块。

    • 全局server块

      • 最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或IP配置
    • location块

      • 一个server块可以配置多个location块
      server {
            listen       80;
            server_name  localhost;
      
            #charset koi8-r;
      
            #access_log  logs/host.access.log  main;
      
            location / {
                root   html;
                index  index.html index.htm;
            }
      
            #error_page  404              /404.html;
      
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
      }
      
    • 小结:这块的主要作用是基于Nginx服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如前面 的/uri-string)进行匹配,对特定的请求进行处理。比如地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

六、反向代理-快速入门

1.反向代理配置-思路分析/图解

image-20241014200343111

2.实现步骤

2.1 安装JDK-jdk11

  • 参考视频网址:https://www.bilibili.com/video/BV1Sv411r7vd?p=86

  • 安装步骤

  • 在opt目录下创建java_jdk目录

    mkdir /opt/java_jdk
    
  • 通过xftp6 将jdk包上传到 /opt/java_jdk 下

  • 切换到java_jdk目录

    cd /opt/java_jdk
    
  • 解压jdk

    tar -zxvf jdk-11.0.23_linux-x64_bin.tar.gz
    
  • 创建实际存放目录

    mkdir /usr/local/java
    
  • 将java_jdk下解压的jdk剪切到/usr/local/java目录下

    mv /opt/java_jdk/jdk-11.0.23 /usr/local/java
    
  • 配置环境变量,在/etc/profile文件中添加环境变量

    export JAVA_HOME=/usr/local/java/jdk-11.0.23
    export PATH=$JAVA_HOME/bin:$PATH
    
  • 让文件立即生效指令

    source /etc/profile 
    
  • 然后输入指令查看是否配置成功

    java -version
    

    image-20241015100231581

2.2 安装Tomcat

  • 参考视频网址:https://www.bilibili.com/video/BV1Sv411r7vd?p=87

  • 安装步骤

  • 创建存放目录

    mkdir /opt/tomcat
    
  • 通过xftp6 将tomcat包上传到 /opt/tomcat 下

  • 将文件进行解压

    tar -zxvf apache-tomcat-9.0.89.tar.gz
    
  • 创建实际存放目录

    mkdir /usr/local/tomcat9
    
  • 将tomcat剪切到tomcat9

    mv /opt/tomcat/apache-tomcat-9.0.89 /usr/local/tomcat9
    
  • 进入到指定目录

    cd /usr/local/tomcat9/apache-tomcat-9.0.89/bin
    
  • 启动tomcat

    ./startup.sh
    

    image-20241015101627381

  • 是否成功

    image-20241015102236668

2.3 修改Nginx的nginx.conf配置文件

  • 修改/usr/local/nginx/nginx.conf

  • 操作指令

    vim /usr/local/nginx/nginx.conf
    

    image-20241015105514575

  • 如何查看nginx.conf的配置错误

  • 检测默认配置文件,操作指令:

    /usr/local/nginx/sbin/nginx -t
    

    image-20241015110059728

  • 指定检测配置文件,操作指令

    /usr/local/nginx/sbin/nginx -t -c nginx.conf
    

    image-20241015110357458

3.注意事项和细节

  • Nginx对外提供访问入口,充当反向代理服务器,Tomcat的端口就无需对外暴露

  • 开启和关闭防火墙端口

  • 开启防火墙端口,以8080端口为例

    firewall-cmd --add-port=8080/tcp --permanent
    firewall-cmd --reload
    
  • 关闭防火墙端口,以8080端口为例

    firewall-cmd --remove-port=8080/tcp --permanent
    firewall-cmd --reload
    
  • 查看防火墙的状态

    firewall-cmd --list-all
    

七、反向代理配置-Location实例

1.反向代理配置-思路分析/图解

image-20241015143252222

2.Location语法规则

  • 解读1-location 语法规则,参考文件:location语法规则.docx

  • 解读2-nginx 的 location 解析过程

    image-20241015144327141

3.实现步骤

3.1 修改Nginx的nginx.conf配置文件

image-20241015150353980

3.2 在 Linux 的 两个Tomcat中的webapps目录下创建\product\hi.html和\member\hi.html

  • 首先在8080端口下的tomcat的webapps目录下创建product目录,然后在创建hi.html

    image-20241015151121604

    image-20241015151154735

    image-20241015151215906

  • 首先在8000端口下的tomcat的webapps目录下创建member目录,然后在创建hi.html

image-20241015151453915

  • 然后启动这两个tomcat

八、负载均衡-配置实例

1. 负载均衡配置-思路分析/图解

image-20241015154750077

2. 负载均衡配置规则

  • 负载均衡就是将负载分摊到不同的服务单元,既保证服务的可用性,又保证响应足够快

  • linux 下有 Nginx、LVS、Haproxy 等等服务可以提供负载均衡服务, Nginx 提供了几种分 配方式(策略):

  • 轮询(默认

    • 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除
  • weight

    • weight代表权,重默认为1,权重越高被分配的客户端越多

    • 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

      upstreamhspservers{
      server192.168.180.130:8080 weight=1;
      server192.168.180.130:8000 weight=2;
      }
      
  • ip_hash

    • 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决 session的问题

      upstreamhspservers{
      ip_hash;
      server192.168.180.130:8000;
      server192.168.180.130:8080;
      }
      
  • fair(第三方)

    • 按后端服务器的响应时间来分配请求,响应时间短的优先分配

      upstreamhspservers{
      server192.168.12.134:8080;
      server192.168.12.134:8081;
      fair;
      }
      

3. 实现步骤

3.1 修改Nginx的nginx.conf配置文件

image-20241015160321525

3.2 在两个tomcat的webapps目录下添加search目录,再添加look.html文件

image-20241015160927925

image-20241015161001854

image-20241015161040156

image-20241015161249954

4. 注意事项和避免的坑

  • 两个tomcat如果要启动需要注意,要去修改其中一个tomcat的server.xml文件,以防端口冲突,启动不了,报错
  • nginx.conf的upstream不能带下划线,否则会失败,但是语法检测不到
  • 如果你的浏览器是无痕上网,负载均衡可能失效,因为Nginx无法采集到相关信息,遇到这个情况。改用其它浏览器即可(比如chrome)
  • 提示:如果某tomcat没有监听对应端口,说明启动失败了,可以尝试先执行 shutdown.sh再执行startup.sh解决
  • 文档:Nginx的upstream配置技巧
  • 基本介绍
    • Nginx是一个反向代理软件,大部分的网站都采用Nginx作为网站/平台的 服务器软件。Nginx除了可以直接作为web服务器使用外,更多的情况是 通过反向代理将请求转发给上游服务器
    • 配置上游服务器可以使用upstream进行设置,通过upstream可以实现服 务的负载均衡规则,可以提高服务器的高可用性。
  • 参考地址:https://zhuanlan.zhihu.com/p/409693332

九、动静分离-应用实例

1. 什么动静分离

  • Nginx 动静分离简单来说就是把动态跟静态请求分开,可以理解成使用 Nginx 处理静态 页面/资源,Tomcat 处理动态页面/资源。

  • 动静分离可以减轻Tomcat 压力,静态请求由Nginx处理,提供系统整体性。

  • 回顾前面-示意图

2. 动静分离配置-思路分析/图解

image-20241015165029922

3.先使用传统方式实现

  • 创建tomcat\webapps\search\cal.jsp [老韩说明: 为了测试方便, 在tomcat2也对应创建一份]

  • cal.jsp文件

    <%--
    To change this template use File | Settings | File Templates.--%>
    <%@pagecontentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>hello, jsp</title>
    </head>
    <body>
    <img src="image/cal.jpg"/>
    <h1>JSP, 计算器</h1>
    <%
    int i = 20;
    int j = 70;
    int res = i + j;
    out.println(i + " + " + j + " = " + res);
    %>
    </body>
    </html>
    

4.动静分离优化步骤

  • 修改Nginx的nginx.conf配置文件

image-20241015171644738

  • 创 建 /usr/local/nginx/html/search/image 目 录 , 因 为 图 片 路 径 其 实 是ip/search/image
  • 将 Linux 的 两 个 Tomcat\webapps\search\image 目 录 删 除 , 在/usr/local/nginx/html/search/image 目录下放入图片

5. 注意事项和细节

  • 注意:配置的静态资源路径要和页面上的路径相匹配否则找不到
  • 这里的路径要是实际请求的静态资源路径
  • 如果还有其它的静态资源,按照配置规则配置即可

十、Nginx工作机制和参数设置

1. master-worker机制

1.1 master-worker工作原理图

image-20241015173456821

  • 图解

  • 一个master 管理多个worker

    image-20241015173627440

1.2 一说master-worker机制

  • 争抢机制示意图

    image-20241015205845540

  • 图解

  • 一个masterProcess 管理多个workerprocess, 也就是说Nginx采用的是多进程结构, 而不是多线程结构

  • 当client 发出请求(任务)时,masterProcess 会通知管理的 workerprocess

  • worker process 开始争抢任务, 争抢到的workerprocess 会开启连接,完成任务

  • 每个 worker 都是一个独立的进程,每个进程里只有一个主线程

  • Nginx 采用了 IO 多路复用机制(需要在Linux环境), 使用IO多路复用机制, 是Nginx在使用为数不多的workerprocess 就可以实现高并发的关键

1.3 二说master-worker机制

  • 二说master-worker模式

    image-20241015210128864

  • 解说

  • master-worker模式

    • Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程
    • Master 进程 接收来自外界的信号,向各worker进程发送信号,每个进程都有可能来处理这个连接。
    • Master 进程能监控Worker进程的运行状态,当 worker 进程退出后(异常情况下),会 自动启动新的 worker 进程
  • accept_mutex 解决 “惊群现象”/理论

    • 所有子进程都继承了父进程的 sockfd,当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”
    • 大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,会消耗系统资源
    • Nginx 提供了一个accept_mutex,这是一个加在accept上的一把共享锁。即每个worker进程在执行accept之前都需要先获取锁,获取不到就放弃执行accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),就不会有惊群问题了。
    • 当一个 worker 进程在 accept() 这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,完成一个完整的请求。
    • 一个请求,完全由 worker 进程来处理,而且只能在一个 worker 进程中处理。
  • 用多进程结构而不用多线程结构的好处/理论

    • 节省锁带来的开销, 每个 worker 进程都是独立的进程,不共享资源,不需要加锁。在编程以及问题查上时,也会方便很多。
    • 独立进程,减少风险。采用独立的进程,可以让互相之间不会影响,一个进程退出后, 其它进程还在工作,服务不会中断,master进程则很快重新启动新的worker进程
  • 实现高并发的秘密-IO多路复用

    • 对于Nginx来讲,一个进程只有一个主线程,那么它是怎么实现高并发的呢?
    • 采用了IO多路复用的原理,通过异步非阻塞的事件处理机制,epoll模型,实现了轻量级和高并发
    • nginx 是如何具体实现的呢,举例来说:每进来一个request,会有一个worker进程去 处理。但不是全程的处理,处理到什么程度呢?处理到可能发生阻塞的地方,比如向上游(后 端)服务器转发request,并等待请求返回。那么,这个处理的worker不会这么傻等着,他 会在发送完请求后,注册一个事件:“如果upstream返回了,告诉我一声,我再接着干”。 于是他就休息去了。此时,如果再有request 进来,他就可以很快再按这种方式处理。而 一旦上游服务器返回了,就会触发这个事件,worker才会来接手,这个request才会接着 往下走。由于webserver的工作性质决定了每个request的大部份生命都是在网络传输中, 实际上花费在server机器上的时间片不多,这就是几个进程就能解决高并发的秘密所在
  • 小结:Nginx的master-worker工作机制的优势

    • 支持 nginx-sreload 热部署, 这个特征在前面使用过
    • 对于每个 worker 进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多
    • 每个 worker 都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的 方式/IO多路复用 来处理请求, 即使是高并发请求也能应对
    • 采用独立的进程,互相之间不会影响,一个worker进程退出后,其它worker进程还在 工作,服务不会中断,master 进程则很快启动新的worker 进程
    • 一个worker 分配一个CPU , 那么worker 的线程可以把一个 cpu 的性能发挥到极致

2. 参数设置

2.1 worker_processes

  • 需要设置多少个 worker

  • 每个 worker 的线程可以把一个 cpu 的性能发挥到极致。所以 worker 数和服务器的 cpu 数相等是最为适宜的。设少了会浪费 cpu,设多了会造成 cpu 频繁切换上下文带来的损耗。

  • 设置 worker 数量,Nginx默认没有开启利用多核cpu,可以通过增加worker_cpu_affinity 配置参数来充分利用多核cpu的性能

    #2 核cpu,开启2个进程
    
     worker_processes 2;
     worker_cpu_affinity 01 10;
    
     #2 核cpu,开启4个进程
    
     worker_processes 4;
     worker_cpu_affinity 01 10 01 10;
    
     #4 核cpu,开启2个进程,0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核
    
     worker_processes 2;
     worker_cpu_affinity 0101 1010;
    
     #4 个cpu,开启4个进程
    
     worker_processes 4;
     worker_cpu_affinity 0001 0010 0100 1000;
    
     #8 核cpu,开启8个进程
    
     worker_processes 8;
     worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
    
  • worker_cpu_affinity 理解

    image-20241015211252236

  • 配置实例

    vim /usr/local/nginx/nginx.conf
    

    image-20241015211604509

    • 重新加载nginx
    /usr/local/nginx/sbin/nginx -s reload
    
    • 查看nginx 的 workerprocess 情况

      image-20241015211824775

  • worker_connection

    • worker_connection 表示每个 worker 进程所能建立连接的最大值,所以,一个 nginx 能 建立的最大连接数,应该是 worker_connections*worker_processes

    • 默认:worker_connections: 1024

    • 调大:worker_connections:60000,(调大到6万连接)

    • 同时要根据系统的最大打开文件数来调整

      系统的最大打开文件数>=worker_connections*worker_process
      根据系统的最大打开文件数来调整,worker_connections进程连接数量要小
      于等于系统的最大打开文件数,worker_connections进程连接数量真实数量=  worker_connections*worker_process
      查看系统的最大打开文件数
      ulimit-a|grep"openfiles"
      openfiles (-n)65535
      
    • 根据最大连接数计算最大并发数:如果是支持http1.1的浏览器每次访问要占两个连接, 所以普通的静态访问最大并发数是:worker_connections*worker_processes/2,而如果 是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/4。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端 服务的连接,会占用两个连接,看一个示意图

      image-20241015213052747

  • 配置 Linux 最大打开文件数

  • 使用ulimit-a 可以查看当前系统的所有限制值,使用ulimit-n 可以查看当前的最大打开文件数

  • 新装的linux默认只有1024,当作负载较大的服务器时,很容易遇到error: too many open files。因此,需要将其改大。

  • 使用 ulimit-n 65535 可即时修改,但重启后就无效了。(注ulimit -SHn 65535 等效 ulimit -n 65535,-S 指 soft,-H 指 hard)

  • 有如下三种修改方式:

    • 在/etc/rc.local 中增加一行 ulimit -SHn 65535

    • 在/etc/profile 中增加一行 ulimit -SHn 65535

    • 在/etc/security/limits.conf 最后增加如下两行记录

    • soft nofile 65535

    • hard nofile 65535

    • 在 CentOS中使用第1种方式无效果,使用第3种方式有效果,而在Debian中使用第2种 有效果

    • 参考网址:https://blog.csdn.net/weixin_43055250/article/details/124980838

十一、搭建高可用集群

1. Keepalived+Nginx高可用集群(主从模式)

1.1 集群架构图

  • 准备两台 nginx 服务器, 一台做主服务器, 一台做备份服务器

  • 两台Nginx服务器的IP地址, 可以自己配置

  • 安装keepalived, 保证主从之间的通讯

  • 对外提供统一的访问IP(虚拟IP-VIP)

  • 示意图

    image-20241015215639562

1.2 具体搭建步骤

  • 搭建高可用集群基础环境

  • 准备两台Linux服务器 192.168.180.130 和 192.168.180.131

    • 可以克隆来完成
    • 也可以直接拷贝一份
  • 在两台Linux服务器, 安装并配置好 Nginx

    • 安装配置Nginx步骤前面讲过, 如果是克隆的Linux, 本身就有安装好了Nginx, 直接使用即可.
    • 验证安装是否成功,在windows可以通过IP访问到Nginx,,具体的操作步骤和注意事项,前面也都是说过了
    • 因为是拷贝了一份Linux, 而新的Linux的IP已经变化了, 所以需要克隆的Linux 的nginx.conf 文件中的IP地址, 做相应的修改
  • 在两台Linux服务器, 安装 keepalived

    • 下载keepalived-2.0.20.tar.gz 源码安装包

    • 官方网址:https://keepalived.org/download.html

    • 上传到两台Linux/root 目录下

      image-20241015221541272

    • 创建keepalived目录

      mkdir /usr/local/keepalived
      
    • 解压文件到指定目录:

      tar -zxvf keepalived-2.0.20.tar.gz -C /usr/local/keepalived
      
    • 切换到解压的目录

      cd /usr/local/keepalived/keepalived-2.0.20
      
    • 将配置文件放在 /etc 目录下, 安装路径在 /usr/local

      ./configure --sysconf=/etc --prefix=/usr/local
      
    • 编译并安装

      make && make install
      
    • 如果成功, 就会安装好keepalived 【可以检查一下】

    • 说明:

      • keepalived 的配置目录在 /etc/keepalived/keepalived.conf
      • keepalived 的启动指令在 /usr/local/sbin/keepalived
    • 提示: 两台Linux都要安装keepalived

  • 完成高可用集群配置

  • 将 其 中 一 台 Linux( 比 如 192.168.180.130) 指 定 为 Master :

     vi /etc/keepalived/keepalived.conf
    

    image-20241015223802453

  • 将其中一台 Linux(比如 192.168.198.131)指定为 Backup(备份服务器):

    vim /etc/keepalived/keepalived.conf
    

    image-20241015224452247

  • 启动 两台Linux的keepalived 指令

    /usr/local/sbin/keepalived
    
  • 观察两台linux的ens160 是否已经绑定 192.168.198.18

    ip a 
    

    image-20241015224710869

    image-20241015224813289

  • 注意事项和细节

    • keepalived 启动后无法ping 通VIP,提示ping:sendmsg:Operationnotpermitted
    • 参考网址: https://blog.csdn.net/xjuniao/article/details/101793935
    • nginx+keepalived 配置说明和需要避开的坑
    • 参考网址:https://blog.csdn.net/qq_42921396/article/details/123074780

1.3 自动检测Nginx异常,终止keepalived

  • 编写shell 脚本:

    vi /etc/keepalived/ch_nginx.sh
    
  • 简单说明: 下面的脚本就是去统计 ps -C nginx –no-header的行数, 如果为0, 说明nginx已经异常终止了, 就执行 killall keepalived

     #!/bin/bash
     num=`ps -C nginx --no-header | wc -l`
     if [ $num -eq 0 ];then
     killall keepalived
     fi
    
  • 修改ch_nginx.sh 权限

    chmod 755 ch_nginx.sh
    
  • 修改192.168.180.130 主 Master 配置文件

    vi /etc/keepalived/keepalived.conf
    

    image-20241015231140341

  • 重新启动192.168.180.130 Master 的 keepalived , 这时因为 Master 的优先级高,会争 夺到VIP优先绑定

    image-20241015231426726

  • 手动关闭 192.168.180.130Master 的 Nginx

    image-20241015231526818

  • 注意观察 keepalived 也终止了

    image-20241015232728926

  • 再次访问nginx, 发现192.168.180.18 这个虚拟IP 又和 192.168.180.131 备份服务器 绑定了.

    image-20241015232744302

  • 注音事项

  • keepalived vrrp_script 脚本不执行解决办法

    • 打开日志观察

      tail -f /var/log/messages
      
    • -重启keepalived

      systemctl restart keepalived.service
      
    • 说明一下:出现文件找不到,可以修改执行脚本文件名,不要有_看一下是否可行

  • 如果配置有定时检查Nginx异常的脚本,需要先启动nginx,在启动keepalived,否则keepalived一起动就被killall了

1.4 配置文件keepalived.conf详解

#这里只注释要修改的地方
global_defs{

    notification_email{

        test@foxmail.com #接收通知的邮件地址

    }
    notification_email_fromAlexandre.Cassen@firewall.loc #发送邮件的邮箱

    smtp_server192.168.200.1 #smtpserver地址

    smtp_connect_timeout 30 

    router_id Node132   #Node132 为主机标识

    vrrp_skip_check_adv_addr

    #vrrp_strict    #这里需要注释,避免虚拟 ip 无法 ping 通

    vrrp_garp_interval 0 vrrp_gna_interval 0

    }   
    vrrp_instance VI_1 { 

    state MASTER    #主节点 MASTER 备用节点为 BACKUP

    interface ens33 #网卡名称

    virtual_router_id 51    #VRRP 组名,两个节点的设置必须一样,指明属于同一 VRRP 组

    priority 100    #主节点的优先级(1-254 之间),备用节点必须比主节点优先级低

    advert_int 1    #组播信息发送间隔,两个节点设置必须一样

    authentication {    #设置验证信息,两个节点必须一致

        auth_type PASS 

        auth_pass 1111

    }
    virtual_ipaddress {#指定虚拟 IP, 两个节点设置必须一样

        192.168.200.16
    }
}   

Comment