Nginx-安装与使用

  • yum 安装nginx 功能受限

    1
    sudo yum install yum-utils
    1
    vim /etc/yum.repos.d/nginx.repo
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [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
    1
    2
    # 稳定和主线的切换
    sudo yum-config-manager --enable nginx-mainline
    1
    sudo yum install nginx
  • Nginx 是什么

    1
    2
    3
    4
    5
    Nginx(engine x) 是一个高性能的 HTTP(解决 C10k的问题)和反向代理服务器,也是一个 IMAP/POP3/SMTP 服务器

    特点:
    占用内存少,并发能力强

  • Nginx 的优势

    1
    2
    3
    4
    5
    IO 多路复用:
    高并发
    epoll
    异步
    非阻塞
  • nginx 目录介绍

    1
    2
    3
    4
    5
    6
    配置目录: /etc/nginx
    执行文件: /usr/sbin/nginx
    日志目录: /var/log/nginx
    启动文件: /var/init.d/nginx
    web 目录: /var/www/html
    nginx配置文件: /etc/nginx/nginx.conf
  • 选择nginx 编译安装

    • yum

      https://lovobin.github.io/2022/07/17/53735.html

      https://developer.aliyun.com/mirror/

    • 环境准备

      1
      2
      3
      # 编译
      # gcc-c++
      yum install -y gcc gcc-c++ autoconf automake make
    • 第三方依赖库

      安装使用 nginx 还得安装nginx 所需的一些第三方系统库的支持,比如nginx 的静态资源压缩功能所需的gzip lib

      nginx 需要支持URL 重写,所需的pcre 开发的依赖库,以及nginx 搭建加密站点https 所需的openssl 依赖库等

      1
      2
      3
      4
      # PCRE库: 用于解析正则表达式
      # zlib-devel: zlib压缩 和 解压
      # openssl openssl-devel 用于 http 安全传输也就是 https
      yum install -y gzip zlib zlib-devel openssl openssl-devel pcre pcre-devel wget httpd-tools vim
    • 安装完毕nginx 所需的基础依赖库,还得检查系统的防火墙是否关闭,selinux,yum配置 网络情况等

      • 检查防火墙

        检查防火墙iptables -L
      • selinux

        SELinux Security Enhanced Linux 的缩写,字面上的意思就是安全强化的Linux,它是由美国国家安全局 (NSA) 开发的,整合到Linux核心的一个模块,是对于强制访问控制(MAC)的实现,是 Linux 历史上最杰出的新安全子系统,提供了比传统的UNIX 权限更好的访问控制。在SELinux的访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。

        SELinux 的启动、关闭和状态:

        • Enforcing:强制模式,表示SELinux 运行中,且已经正确的开始限制 domain/type 了;
        • permissive:宽容模式,表示SELinux 运行中,不过仅会有警告信息,并不会实际限制domain/type 的存取。这种模式可以运来作为 SELinuxdebug 之用;
        • disabled:关闭,SELinux 没有运行。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        # 获取 SELinux 运行模式
        getenforce

        # 获取SELinux的状态
        sestatus
        # SELinux 运行模式切换
        setenforce [0|1]
        选项与参数:
        0:转成 Permissive 宽容模式;
        1:转成 Enforcing 强制模式

        # 只能通过修改配置文件实现修改关闭
        vim /etc/selinux/config
        SELINUX=enforcing # 默认为 enforcing,可设置为 enforcing、permissive、disabled 中的一项。
        SELINUXTYPE=targeted # 目前只能设置成 targeted、mls 中的一项
  • 编译安装Nginx

    • 进入 Nginx 官网 https://nginx.org/

      选择如下任意一个,Eg:点击 nginx-1.13.1 https://nginx.org/download/nginx-1.23.1.tar.gz
      在这里插入图片描述 复制如下的地址
      1
      2
      3
      4
      # 进入 opt 目录
      cd /opt
      # 官网下载
      wget https://nginx.org/download/nginx-1.23.1.tar.gz
    • 淘宝镜像官网地址: https://tengine.taobao.org/

    淘宝镜像,https://tengine.taobao.org/download/tengine-2.3.3.tar.gz
    淘宝镜像
    1
    2
    3
    4
    # 进入 opt 目录
    cd /opt
    # 淘宝镜像下载
    wget https://tengine.taobao.org/download/tengine-2.3.3.tar.gz
    • 解压缩

      1
      2
      3
      4
      5
      6
      7
      8
      9
      # 解压缩
      tar -zxvf tengine-2.3.3.tar.gz
      # 进入解压后的目录
      cd tengine-2.3.3

      # 在 根 目录创建 .vim
      mkdir -p ~/.vim
      # 拷贝 vim 高亮
      cp -r /opt.tbngx2.3.3/contrib/vim/* ~/.vim/
      重要信息解释
      重要信息解释
    • 准备编译,目的是为了创建makefile 文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      ./configure --prefix=/opt/tbngx2.3.3 --with-http_ssl_module  --with-http_flv_module --with-http_gzip_static_module  --with-http_stub_status_module  --with-threads --with-file-aio

      # 淘宝完整(源码复杂安装)
      ./configure \
      --prefix=/opt/tbngx2.3.3 \
      --pid-path=/var/run/mginx/nginx.pid \
      --error-log-path=/var/log/nginx/errror.log \
      --http-log-path=/var/log/nginx/access.log \
      --with-http_gzip_static_model \
      --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
      1
      2
      3
      4
      5
      6
      7
      8
      9
      # 官网完整(源码复杂安装)
      ./configure --prefix=/usr/local/nginx \
      --sbin-path=/usr/local/nginx/sbin/nginx \
      --modules-path=/usr/local/nginx/modules \
      --conf-path=/usr/local/nginx/conf/nginx.conf \
      --error-log-path=/usr/local/nginx/logs/error.log \
      --http-log-path=/usr/local/nginx/logs/access.log \
      --pid-path=/usr/local/nginx/logs/nginx.pid \
      --lock-path=/usr/local/nginx/logs/nginx.lock
      输出为配置信息内容
      命令 解释
      --prefix 指定nginx 安装目录
      -pid-path 指向nginx pid
      --lock-path 锁定安装文件,防止被恶意篡改或误操作
      --error-log 错误日志
      --http-log-path http 日志
      --with-http_gzip_static_model 启用gzip 模块,在线实时压缩输出数据流
      --http-client-body-temp-path 设定客户端请求的临时目录
      --http-proxy-temp-path 设定http 代理临时目录
      -http-factcgi-temp-path 设定fastcgi 临时目录
      --http-uwsgi-temp-path 设定uwsgi 临时目录
      --http-scgi-temp-path 设定scgi 临时目录
    • 安装

      1
      make && make install
    • 自定义环境变量,不在全局修改

      1
      2
      3
      4
      5
      6
      cd /etc/profile.d
      vim nginx.sh
      # 添加如下
      export PATH="$PATH:/opt/tbngx2.3.3/sbin/"
      # 退出当前会话,重新加载生效
      exit
    • 启动

      1
      2
      3
      4
      5
      6
      7
      yum -y install net-tools
      # 查看端口情况
      netstat -tunlp | grep 80

      # 启动
      nginx

    • 停止

      1
      nginx -s stop
    • 重新加载配置文件,nginx 不重新启动

      1
      nginx -s reload
  • 检查配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    [sudo] nginx -t [可选参数: 权限不足添加 Centos无需添加sudo]

    输出以下信息:

    [root@VM-0-3-centos ~]# nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

卸载

  • 需要将nginx 的进程关闭

    1
    2
    3
    # nginx 二进制文件所在目录
    /usr/local/nginx/sbin
    ./nginx -s stop
  • 将安装的nginx 进行删除

    1
    rm -rf /usr/local/nginx
  • 将安装包之前编译的环境清除掉

    1
    make clean
    执行流程

Nginx 目录结构分析

  • 安装目录

    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
    [root@localhost sbin]# tree /usr/local/nginx
    /usr/local/nginx
    ├── conf
    # 是文件的副本 可以用于恢复默认配置
    │   ├── fastcgi.conf
    │   ├── fastcgi.conf.default
    │   ├── fastcgi_params
    │   ├── fastcgi_params.default
    # 编码相关
    │   ├── koi-utf
    │   ├── koi-win
    │   ├──win-utf

    │   ├── mime.types
    │   ├── mime.types.default
    │   ├── nginx.conf
    │   ├── nginx.conf.default
    │   ├── scgi_params
    │   ├── scgi_params.default
    │   ├── uwsgi_params
    │   ├── uwsgi_params.default
    │   └──
    ├── html
    │   ├── 50x.html # 访问失败后的失败页面
    │   └── index.html
    ├── logs
    │   ├── access.log 访问日志
    │   ├── error.log 错误日志
    │   ├── nginx.pid nginx 进程的 PID
    └── sbin
    └── nginx

    4 directories, 18 files
    [root@localhost sbin]#

    • CGI(Common Gateway Interface) 通用网关【接口】,主要解决的问题是从客户端发送一个请求和数据,服务端获取到请求和数据后可以调用CGI【程序】处理及响应结果给客户端的一种标准规范

Nginx服务的信号控制

  • worker master

    关系
    在这里插入图片描述

    从上图中可以看到Nginx 后台进程中包含一个master 进程和多个worker 进程,master 进程主要用来管理worker 进程,包含接收外界的信息,并将接收到的信号发送给各个worker 进程,监控worker 进程的状态,当worker 进程出现异常退出后,会自动重新启动新的worker 进程。而worker 进程则是专门用来处理用户请求的,各个worker 进程之间是平等的并且相互独立,处理请求的机会也是一样的。nginx 的进程模型,我们可以通过下图来说明下:

    我们现在作为管理员,只需要通过给master 进程发送信号就可以来控制Nginx,这个时候我们需要有两个前提条件,一个是要操作的master 进程,一个是信号

  • 查看运行进程

    1
    ps -ef | grep nginx
  • 信号

    信号 作用
    TERM/INT 立即关闭整个服务
    QUIT “优雅”地关闭整个服务
    HUP 重读配置文件并使用服务对新配置项生效
    USR1 重新打开日志文件,可以用来进行日志切割
    USR2 平滑升级到最新版的nginx
    WINCH 所有子进程不在接收处理新连接,相当于给work进程发送QUIT指令
  • 调用命令

    1
    kill -signal PID

快捷配置

  • 获取进程

    1
    2
    3
    4
    5
    6
    7
    vim /root/.bashrc

    alias ps_nginx='ps -ef | grep nginx'
    source ~/.bashrc

    # 编辑器中的快速删除 :/31,36d

Nginx 服务的命令行控制

  • 查看

    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
    [root@localhost sbin]# pwd
    /usr/local/nginx/sbin
    [root@localhost sbin]# ls
    nginx
    [root@localhost sbin]# ./nginx -h
    nginx version: nginx/1.22.0
    Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
    [-e filename] [-c filename] [-g directives]

    Options:
    -?,-h : this help 显示帮助信息
    -v : show version and exit 打印版本号信息并退出
    -V : show version and configure options then exit 打印版本号信息和配置信息并退出
    -t : test configuration and exit 测试nginx的配置文件语法是否正确并退出
    -T : test configuration, dump it and exit 测试nginx的配置文件语法是否正确并列出用到的配置文件信息然后退出
    -q : suppress non-error messages during configuration testing 在配置测试期间禁止显示非错误消息
    -s signal : send signal to a master process: stop, quit, reopen, reload signal信号,后面可以跟
    -p prefix : set prefix path (default: /usr/local/nginx/)
    -e filename : set error log file (default: /usr/local/nginx/logs/error.log)
    -c filename : set configuration file (default: /usr/local/nginx/conf/nginx.conf)
    -g directives : set global directives out of configuration file

    -s:
    stop[快速关闭,类似于TERM/INT信号的作用]
    quit[优雅的关闭,类似于QUIT信号的作用]
    reopen[重新打开日志文件类似于USR1信号的作用]
    reload[类似于HUP信号的作用]

    -p: prefix,指定 Nginx 的 prefix 路径,(默认为: /usr/local/nginx/)
    -c: filename,指定 Nginx 的配置文件路径,(默认为: conf/nginx.conf) -tc搭配使用
    -g: 用来补充 Nginx 配置文件,向 Nginx 服务指定启动时应用全局的配置

Nginx 服务器版本升级和新增模块

  • 当前安装版本以及配置

    当前版本信息
  • 平滑升级

    • 需求:Nginx 的版本最开始使用的是Nginx-1.22.0,由于服务升级,需要将Nginx 的版本升级到Nginx-1.23.1,要求Nginx能中断提供服务

      • 方案一: 使用Nginx 服务信息完成Nginx 的升级

        1. 1.22.0 版本的sbin 目录下的nginx 进行备份

          1
          2
          cd /usr/local/nginx/sbin
          mv nginx nginxold
        2. 1.23.1 安装目录编译后的objs 目录下的nginx 文件,拷贝到原来/usr/local/nginx/sbin 目录下

          1
          2
          3
          4
          5
          6
          cd nginx-1.23.1/
          ./configure xxx
          make

          cd nginx-1.23.1/objs/
          cp nginx /usr/local/nginx/sbin/
          高本版目录中不进行make install
        3. 发送信号USER2 Ngxinx 1.22.0 版本对应的的master 进程

          1
          kill -USER2 `more /usr/local/logs/nginx.pid`
        4. 发送信号给QUIT Nginx 1.22.0 版本对应的master 进程

          1
          kill -QUIT `more /usr/local/logs/nginx.pid.oldbin`
      • 方案二: 使用Nginx 安装目录的make 命令完成升级

        1. 1.22.0 版本的sbin 目录下的nginx 进行备份

          1
          2
          cd /usr/local/nginx/sbin
          mv nginx nginxold
        2. 1.23.1 安装目录中编译后的objs 目录下的nginx 文件,拷贝到原来/usr/local/nginx/sbin

          1
          2
          3
          4
          5
          cd nginx-1.23.1/
          ./configure
          make
          cd objs
          cp nginx /usr/local/nginx/sbin
        3. 进入到1.23.1 安装目录,执行make upgrade

        4. 查看是否更新成功

          1
          ./nginx -v
          查看

Nginx 常见配置

  • 全局段

    1
    配置影响 nginx 全局的指令,一般有运行 nginx 服务器的用户组, nginx 进程 pid 存放路径,允许生成 worker process 数等
  • events

    1
    2
    配置影响 nginx 服务与用户的网络连接,有每个进程的最大链接数、选取那种事件驱动模型处理连接请求,是否允许同时接受多个网络连接,开启多个网络连接序列化等。

    1. accept_mutex: 用来设置Nginx 网络连接序列化

      这个配置主要可以用来解决常说的”惊群”问题。大致意思是在某一个时刻,客户端发来一个请求连接,Nginx 后台是以多进程的工作模式,也就是说有多个worker 进程会被同时唤醒,但是最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响Nginx 的整体性能。如果将上述值设置为on(开启状态),将会对多个Nginx 进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢。

    2. multi_accept: 用来设置是否允许同时接收多个网络连接

      如果multi_accept 被禁止了,nginx 一个工作进程只能同时接受一个新的连接。否则,一个工作进程可以同时接受所有的新连接

    3. worker_connections:用来配置单个worker 进程最大的连接数

    4. use: 用来设置Nginx 服务器选择哪种事件驱动来处理网络消息。

    1
    2
    3
    4
    5
    6
    7
    events{
    accept_mutex on;
    multi_accept on;
    worker_commections 1024;
    # linux 内核版本高于2.6+: 该命令查看内核版本 uname -a
    use epoll;
    }
  • http

    1
    可以嵌套多个 server、配置代理、缓存、日志定义等绝大数功能和第三方模块的配置、如文件引入,mime-type定义,日志自定义,是否使用 sendfile 传输文件、连接超时等时间,单连接请求数等。
  • server

    1
    配置虚拟主机的相关参数,主要有 IP 地址、端口号、域名
  • location

    1
    配置请求的处理方式

Nginx 核心配置文件结构

  • 结构

    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

    worker_processes 1;

    events {
    worker_connections 1024;
    }


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

    sendfile on;

    keepalive_timeout 65;

    server {
    listen 80;
    server_name localhost;

    location / {
    root html;
    index index.html index.htm;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }

    }

    }

自定义服务日志

  • 日志分类

    • access.log: 用来记录用户所有访问请求
    • error.log: 记录nginx 本身运行时的错误信息,不会记录用户的访问请求
  • 日志设置

    Nginx 服务器支持对服务日志的格式,大小,输出等进行设置,需要使用到两个指令,分别是access_loglog_format 指令

  • 查看日志

    1
    tail -f /usr/local/nginx/logs/access.log 
  • log_format 只能在http 段配置

Nginx 配置成系统服务

  • /usr/lib/systemd/system 目录下添加nginx.service,内容如下
1
vim /usr/lib/systemd/system/nginx.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=nginx web service
Documentation=http://nginx.org/en/docs/
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true

[Install]
WantedBy=default.target
  • 添加完成后如果权限有问题需要进行权限设置

    1
    chmod 755 /usr/lib/systemd/system/nginx.service
  • 使用系统命令来操作Nginx 服务

    1
    2
    3
    4
    5
    6
    启动: systemctl start nginx
    停止: systemctl stop nginx
    重启: systemctl restart nginx
    重新加载配置文件: systemctl reload nginx
    查看nginx状态: systemctl status nginx
    开机启动: systemctl enable nginx

添加全局环境变量

  • 编辑

    1
    vim /etc/profile
    1
    export PATH=$PATH:/usr/local/nginx/sbin
    1
    source /etc/profile

静态资源部署配置

  • listen 指令

    1
    2
    3
    4
    listen 127.0.0.1:8000; // listen localhost:8000 监听指定的IP和端口
    listen 127.0.0.1; 监听指定IP的所有端口
    listen 8000; 监听指定端口上的连接
    listen *:8000; 监听指定端口上的连接
  • default_server

    default_server 属性是标识符,用来将此虚拟主机设置成默认主机。所谓的默认主机指的是如果没有匹配到对应的address:port,则会默认执行的。如果不指定默认使用的是第一个server

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server{
    listen 8080;
    server_name 127.0.0.1;
    location /{
    root html;
    index index.html;
    }
    }
    server{
    listen 8080 default_server; # 找不见默认走此处
    server_name localhost;
    default_type text/plain;
    return 444 'This is a error request';
    }
  • server_name: 用来设置虚拟主机服务名称

    • 精确匹配

      1
      2
      3
      4
      5
      server {
      listen 80;
      server_name www.baidu.com;
      ...
      }
    • 通配符匹配: server_name 中支持通配符”*“,但需要注意的是通配符不能出现在域名的中间,只能出现在首段或尾段

      1
      2
      3
      4
      5
      server {
      listen 80;
      server_name *.baidu.cn www.baidu.*;
      ...
      }
    • 正则表达式匹配: server_name 中可以使用正则表达式,并且使用~作为正则表达式字符串的开始标记。

      1
      2
      3
      4
      5
      6
      7
      server{
      listen 80;
      server_name ~^www\.(\w+)\.com$;
      default_type text/plain;
      return 200 $1 $2 ..;
      }
      注意 ~后面不能加空格,括号可以取值
      代码 说明
      ^ 匹配搜索字符串开始位置
      $ 匹配搜索字符串结束位置
      . 匹配除换行符\n之外的任何单个字符
      \ 转义字符,将下一个字符标记为特殊字符
      [xyz] 字符集,与任意一个指定字符匹配
      [a-z] 字符范围,匹配指定范围内的任何字符
      \w 与以下任意字符匹配 A-Z a-z 0-9 和下划线,等效于[A-Za-z0-9_]
      \d 数字字符匹配,等效于[0-9]
      {n} 正好匹配n
      {n,} 至少匹配n
      {n,m} 匹配至少n次至多m
      * 零次或多次,等效于{0,}
      + 一次或多次,等效于{1,}
      ? 零次或一次,等效于{0,1}
  • server_name 执行顺序

    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
    server{
    listen 80;
    server_name ~^www\.\w+\.com$;
    default_type text/plain;
    return 200 'regex_success';
    }

    server{
    listen 80;
    server_name www.baidu.*;
    default_type text/plain;
    return 200 'wildcard_after_success';
    }

    server{
    listen 80;
    server_name *.baidu.com;
    default_type text/plain;
    return 200 'wildcard_before_success';
    }

    server{
    listen 80;
    server_name www.baidu.com;
    default_type text/plain;
    return 200 'exact_success';
    }

    server{
    listen 80 default_server;
    server_name _;
    default_type text/plain;
    return 444 'default_server not found server';
    }
    • 结论

      1
      2
      3
      4
      5
      exact_success
      wildcard_before_success
      wildcard_after_success
      regex_success
      default_server not found server!!
      1
      2
      3
      4
      5
      6
      7
      8
      9
      No1:准确匹配server_name

      No2:通配符在开始时匹配server_name成功

      No3:通配符在结束时匹配server_name成功

      No4:正则表达式匹配server_name成功

      No5:被默认的default_server处理,如果没有指定默认找第一个server
  • location 指令

    • 不带符号,要求必须以指定模式开始

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      server {
      listen 80;
      server_name 127.0.0.1;
      location /abc{
      default_type text/plain;
      return 200 "access success";
      }
      }
      以下访问都是正确的
      http://192.168.200.133/abc
      http://192.168.200.133/abc?p1=TOM
      http://192.168.200.133/abc/
      http://192.168.200.133/abcdef
    • = : 用于不包含正则表达式的uri 前,必须与指定的模式精确匹配

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      server {
      listen 80;
      server_name 127.0.0.1;
      location =/abc{
      default_type text/plain;
      return 200 "access success";
      }
      }
      可以匹配到
      http://192.168.200.133/abc
      http://192.168.200.133/abc?p1=TOM
      匹配不到
      http://192.168.200.133/abc/
      http://192.168.200.133/abcdef
    • ~ : 用于表示当前uri中包含了正则表达式,并且区分大小写
      ~*: 用于表示当前uri中包含了正则表达式,并且不区分大小写

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      server {
      listen 80;
      server_name 127.0.0.1;
      location ~^/abc\w${
      default_type text/plain;
      return 200 "access success";
      }
      }
      server {
      listen 80;
      server_name 127.0.0.1;
      location ~*^/abc\w${
      default_type text/plain;
      return 200 "access success";
      }
      }
      如果 uri 包含了正则表达式,需要用上述两个符号(~/~*)来标识

      • ^~:用于不包含正则表达式的uri前,功能和不加符号的一致,唯一不同的是,如果模式匹配,那么就停止搜索其他模式了

        1
        2
        3
        4
        5
        6
        7
        8
        server {
        listen 80;
        server_name 127.0.0.1;
        location ^~/abc{
        default_type text/plain;
        return 200 "access success";
        }
        }
  • 设置请求资源的目录 root/aslias

    1. /usr/local/nginx/html 目录下创建一个 images目录,并在目录下放入一张图片lyf.jpeg 图片

      1
      2
      3
      location /images {
      root /usr/local/nginx/html;
      }
      • 访问图片的路径为: http://192.168.22.5/images/lyf.jpeg
    2. 如果把root 改为alias

      1
      2
      3
      location /images {
      alias /usr/local/nginx/html;
      }

      再次访问上述地址,页面会出现404 的错误,查看错误日志会发现是因为地址不对,所以验证了

      1
      2
      3
      2022/10/19 00:20:23 [error] 1641#0: *3 open() "/usr/local/nginx/html/xr.jpg" failed (2: No such file or directory), client: 192.168.22.6, server: localhost, request: "GET /images/xr.jpg HTTP/1.1", host: "192.168.22.5"

      主要原因: open() "/usr/local/nginx/html/xr.jpg" failed 缺少目录导致无法访问
    • 如果需要alias 可以正确访问,则配置需要修改为

      1
      2
      3
      location /images {
      alias /usr/local/nginx/html/images;
      }
    • 如果location 路径是以/ 结尾,则alias 也必须是以/ 结尾,root 则没有要求

      location 以 / 结尾
    • 小结

      1
      2
      3
      4
      root 的处理结果是: root路径+location路径
      alias 的处理结果是: 使用alias路径替换location路径
      alias 是一个目录别名的定义,root则是最上层目录的含义。
      如果 location路径是以/结尾,alias也必须是以/结尾,root没有要求
  • Index 指令

    • index 后面可以跟多个设置,如果访问的时候没有指定具体访问的资源,则会依次进行查找,找到第一个为止

      1
      2
      3
      4
      5
      6
      7
      location / {
      root /usr/local/nginx/html;
      index index.html index.htm;
      }

      访问该location的时候,可以通过 http://ip:port/,地址后面如果不添加任何内容,则默认依次访问index.htmlindex.htm,找到第一个来进行返回

  • error_page 指令: 设置网站的错误页面

    • 可以指定具体跳转的地址

      1
      2
      3
      server {
      error_page 404 http://www.baidu.com;
      }
    • 可以指定重定向地址

      1
      2
      3
      4
      5
      6
      7
      server{
      error_page 404 /50x.html;
      error_page 500 502 503 504 /50x.html;
      location =/50x.html{
      root html;
      }
      }
    • 使用location @ 符合完成错误信息展示

      1
      2
      3
      4
      5
      6
      7
      server{
      error_page 404 @jump_to_error;
      location @jump_to_error {
      default_type text/plain;
      return 404 'Not Found Page...';
      }
      }
    • 可选项=[response] 的作用是用来将相应代码更改为另外一个

      1
      2
      3
      4
      5
      6
      7
      8
      9
      server{
      error_page 404 =200 /50x.html;
      location =/50x.html{
      root html;
      }
      }

      这样的话,当返回404找不到对应的资源的时候,在浏览器上可以看到,最终返回的状态码是200,这块需要注意下,编写error_page后面的内容,404后面需要加空格,200前面不能加空格

静态资源优化配置语法

  • 如下配置

    1
    2
    3
    sendfile on;
    tcp_nopush on;
    tcp_nodeplay on;
    • sendfile:用来开启高效的文件传输模式,默认值:off,位置:http、server、location,推荐http

      请求静态资源的过程: 客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务器端应用程序,服务器端应用程序会处理这些请求,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器传递回去

    • tcp_nopush: 该指令必须在sendfile 打开的状态下才会生效,主要是用来提升网络包的传输效率,默认值off,位置: http、server、location

    • tcp_nodelay: 该指令必须在keep-alive 连接开启后的情况下才生效,来提高网络包传输的实时性,默认值on,位置同上

静态资源压缩

  • 模块

    1
    2
    3
    ngx_http_gzip_module模块
    ngx_http_gzip_static_module模块
    ngx_http_gunzip_module模块
    • Gzip 模块配置指令: 该指令用于开启或者关闭gzip 功能,默认值off

      未开启压缩之前大小
    • gzip_types 指令: 该指令可以根据相应页的MIME 类型选择性地开启Gzip 压缩功能

      gzip_types是根据页面加载地Content-Type 设置的 文件的Content-Type
    • gzip_comp_level 指令: 该指令用于设置Gzip 压缩程度,级别从1-91 表示压缩程度最低,效率最高,9 刚好相反,压缩程度最高,但是效率最低最费时间

      最大级别下的压缩
    • gzip_vary 指令:该指令用于设置使用Gzip 进行压缩发送是否携带Vary:Accept-Encoding头域的响应头部。主要是告诉接收方,所发送的数据经过了Gzip 压缩处理

    • gzip_disable 指令:针对不同种类客户端发起的请求,可以选择性地开启和关闭Gzip 功能,

      • regex: 根据客户端的浏览器标志(user-agent)来设置,支持使用正则表达式。指定的浏览器标志不使用Gzip.该指令一般是用来排除一些明显不支持Gzip的浏览器

        1
        gzip_disable "MSIE [1-6]\.";
    • gzip_min_length 指令:该指令针对传输数据的大小,可以选择性地开启和关闭Gzip 功能

      Gzip 压缩功能对大数据的压缩效果明显,但是如果要压缩的数据比较小的化,可能出现越压缩数据量越大的情况,因此我们需要根据响应内容的大小来决定是否使用Gzip功能,响应页面的大小可以通过头信息中的Content-Length 来获取。但是如何使用了Chunk 编码动态压缩,该指令将被忽略。建议设置为1K 或以上。

  • Gzip 压缩功能的实例配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    gzip on;  			  # 开启gzip功能
    gzip_types *; # 压缩源文件类型,根据具体的访问资源类型设定
    gzip_comp_level 6; # gzip压缩级别
    gzip_min_length 1024; # 进行压缩响应页面的最小长度,content-length
    gzip_buffers 4 16K; # 缓存空间大小
    gzip_http_version 1.1; # 指定压缩响应所需要的最低HTTP请求版本(此处选择默认)
    gzip_vary on; # 往头信息中添加压缩标识
    gzip_disable "MSIE [1-6]\."; # 对IE6以下的版本都不进行压缩
    gzip_proxied off# nginx作为反向代理压缩服务端返回数据的条件
    • 这些配置在很多地方可能都会用到,所以我们可以将这些内容抽取到一个配置文件中,然后通过include 指令把配置文件再次加载到nginx.conf 配置文件中,方法使用

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # nginx_gzip.conf
      gzip on;
      gzip_types *;
      gzip_comp_level 6;
      gzip_min_length 1024;
      gzip_buffers 4 16K;
      gzip_http_version 1.1;
      gzip_vary on;
      gzip_disable "MSIE [1-6]\.";
      gzip_proxied off;
      1
      2
      # nginx.conf
      include nginx_gzip.conf;
      引入压缩相关配置

Gzip 和 SendFile 共存问题

  • 问题

    开启sendfile 以后,在读取磁盘上的静态资源文件的时候,可以减少拷贝的次数,可以不经过用户进程将静态文件通过网络设备发送出去,但是Gzip 要想对资源压缩,是需要经过用户进程进行操作的。所以如何解决两个设置的共存问题。

  • 解决方案

    可以使用ngx_http_gzip_static_module 模块的gzip_static 指令来解决。

  • gzip_static: 检查与访问资源同名的.gz 文件时,response 中以gzip 相关的header 返回.gz 文件的内容

  • 使用测试

    • 关闭nginx_gzip.conf 中的gzip off

    • 添加gzip_static on;

    • 对资源手动压缩(读取的是同名gz 文件)

      对比

添加模块到 Nginx 的实现步骤

  1. 查询当前Nginx 的配置参数

    1
    nginx -V
    1
    2
    3
    4
    5
    [root@localhost conf]# nginx -V
    nginx version: nginx/1.23.1
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
    configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/logs/nginx.lock

  2. nginx 安装目录下的sbin 目录中的nginx 二进制文件进行更名

    1
    2
    cd /usr/local/nginx/sbin
    mv nginx nginxold
  3. 进入nginx 的安装目录

    1
    cd /root/nginx/core/nginx-1.23.1
  4. 执行make clean 清空之前编译的内容

    1
    make clean
  5. 使用configure 来配置参数

    1
    2
    3
    4
    # 将 nginx -V 的内容附带
    ./configure (添加的新模块去)
    # 添加模块
    ./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/logs/nginx.lock --with-http_gzip_static_module
  6. 使用make 命令进行编译

    1
    make
  7. objs 目录下的nginx 二进制执行文件移动到nginx 安装目录下的sbin 目录中

    1
    mv objs/nginx /usr/local/nginx/sbin
  8. 执行更新命令

    1
    make upgrade
    安装目录下执行该命令
    1
    2
    3
    4
    5
    6
    [root@localhost nginx-1.23.1]# nginx -V
    nginx version: nginx/1.23.1
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
    configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --modules-path=/usr/local/nginx/modules --conf-path=/usr/local/nginx/conf/nginx.conf --error-log-path=/usr/local/nginx/logs/error.log --http-log-path=/usr/local/nginx/logs/access.log --pid-path=/usr/local/nginx/logs/nginx.pid --lock-path=/usr/local/nginx/logs/nginx.lock --with-http_gzip_static_module
    [root@localhost nginx-1.23.1]# 出现添加的模块

浏览器缓存

  • 浏览器缓存

    是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览

  • 浏览器缓存执行流程

    浏览器缓存执行流程
    • 用户首次通过浏览器发送请求到服务端获取数据,客户端是没有对应的缓存,所以需要发送request请求来获取数据;

    • 服务端接收到请求后,获取服务端的数据及服务端缓存的允许后,返回200的成功状态码并且在响应头上附上对应资源以及缓存信息;

    • 当用户再次访问相同资源的时候,客户端会在浏览器的缓存目录中查找是否存在响应的缓存文件

    • 如果没有找到对应的缓存文件,则走(2)

    • 如果有缓存文件,接下来对缓存文件是否过期进行判断,过期的判断标准是(Expires),

    • 如果没有过期,则直接从本地缓存中返回数据进行展示

    • 如果Expires过期,接下来需要判断缓存文件是否发生过变化

    • 判断的标准有两个,一个是ETag(Entity Tag),一个是Last-Modified

    • 判断结果是未发生变化,则服务端返回304,直接从缓存文件中获取数据

    • 如果判断是发生了变化,重新从服务端获取数据,并根据缓存协商(服务端所设置的是否需要进行缓存数据的设置)来进行数据缓存。

  • expires 指令: 该指令用来控制页面缓存的作用。可以通过该指令控制HTTP 应答中的Expires“和”Cache-Control

    • Cache-Control 作为响应头信息,可以设置如下值

      1
      2
      3
      4
      5
      6
      7
      8
      9
      Cache-control: must-revalidate
      Cache-control: no-cache
      Cache-control: no-store
      Cache-control: no-transform
      Cache-control: public
      Cache-control: private
      Cache-control: proxy-revalidate
      Cache-Control: max-age=<seconds>
      Cache-control: s-maxage=<seconds>
      指令 说明
      must-revalidate 可缓存但必须再向源服务器进行确认
      no-cache 缓存前必须确认其有效性
      no-store 不缓存请求或响应的任何内容
      no-transform 代理不可更改媒体类型
      public 可向任意方提供响应的缓存
      private 仅向特定用户返回响应
      proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
      max-age=<秒> 响应最大Age
      s-maxage=<秒> 公共缓存服务器响应的最大Age

跨域

  • 浏览器的同源策略:是一种约定,是浏览器最核心也是最基本的安全功能,如果浏览器少了同源策略,则浏览器的正常功能可能都会受到影响。

    • 同源: 协议、域名(IP)、端口相同即为同源
  • 跨域问题

    有两台服务器分别为A,B,如果从服务器A的页面发送异步请求到服务器B获取数据,如果服务器A和服务器B不满足同源策略,则就会出现跨域问题。

  • 跨域复现

    • 文件结构

      下载所需文件依赖
    • jquery

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      <html>
      <head>
      <meta charset="utf-8">
      <title>跨域问题演示</title>
      <script src="jquery.js"></script>
      <script>
      $(function(){
      $("#btn").click(function(){
      $.get('http://192.168.200.133:8080/getUser',function(data){
      alert(JSON.stringify(data));
      });
      });
      });
      </script>
      </head>
      <body>
      <input type="button" value="获取数据" id="btn"/>
      </body>
      </html>

    • axios

      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
      <!DOCTYPE html>
      <html lang="en">

      <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>跨域测试</title>
      <script src="axios.min.js"></script>
      </head>

      <body>
      <div class="container">
      <button class="get_data">获取数据</button>
      </div>
      <script>
      let btnEl = document.querySelector(".get_data");
      btnEl.onclick = function () {
      console.log("in click....");
      axios({
      url: "http://192.168.22.5:8080/getUser",
      method: "get"
      }).then(res => {
      console.log(res);
      });
      }
      </script>
      </body>

      </html>
    • nginx 配置

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      server {
      listen 8080;
      server_name localhost;
      location /getUser {
      default_type application/json;
      return 200 ' {
      "id":1001,"name":"coder-itl","age":18
      }'
      };
      }
      server {
      listen 80;
      server_name localhost;

      location / {
      root html;
      index index.html index.htm;
      }
      }
    • 访问:http://192.168.22.5/a.html/b.html

      by CORS policy: No 'Access-Control-Allow-Origin'
    • 解决方案

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      # 在需要跨域的服务内配置(数据方)
      server {
      listen 8080;
      server_name localhost;
      location /getUser {
      default_type application/json;
      # 配置跨域允许
      add_header Access-Control-Allow-Origin http://192.168.22.5; # 将具体 IP 改为 * 代表允许所有
      add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;
      return 200 ' {
      # 数据源
      "id":1001,"name":"coder-itl","age":18
      }'
      };
      }
      成功获取数据

Vim 快速注释

  • 注释

    • 按下ctrl + v

    • 上下键选择多块

    • 按下大写I

    • 输入#

    • 按下ESC

  • 取消注释

    • 按下ctrl + v
    • 上下选择带有#
    • 按下d

Master主进程原理

  • 原理

    1. 启动时检查nginx.conf 是否正确,语法错误

    2. 根据配置文件的参数创建,且监控woker 进程的数量和状态

    3. 监听socket,接受client 发起的请求,然后worker 竞争抢夺链接,获胜的可以处理且响应请求

    4. 接受运维发送的管理nginx 进程的信号,并且将信号通知到worker 进程

    5. 如果运维发送了reload 命令,则读取新配置文件,创建新的worker 进程,结束旧的worker 进程

      Master主进程原理

代理

  • 正向代理

    1
    在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问。
  • 反向代理

    Nginx 反向代理模块的指令是由ngx_http_proxy_module 模块进行解析,该模块在安装Nginx 的时候已经自己加装到Nginx 中了

    • proxy_pass: 位置location

      URL: 为要设置的被代理服务器地址,包含传输协议(http,https://)、主机名称或IP 地址加端口号、URI 等要素。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      server {
      listen 80;
      server_name localhost;
      location /{
      #proxy_pass http://192.168.200.146;
      proxy_pass http://192.168.200.146/;
      }
      }
      当客户端访问 http://localhost/index.html,效果是一样的
      server{
      listen 80;
      server_name localhost;
      location /server{
      #proxy_pass http://192.168.200.146;
      proxy_pass http://192.168.200.146/;
      }
      }
      当客户端访问 http://localhost/server/index.html
      这个时候,第一个proxy_pass就变成了http://localhost/server/index.html
      第二个proxy_pass就变成了http://localhost/index.html效果就不一样了。
  • proxy_set_header: 该指令可以更改Nginx 服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给代理的服务器

  • proxy_redirect

  • 实战

    模拟实现

    服务器1,2,3存在两种情况:

    第一种情况: 三台服务器的内容不一样。
    第二种情况: 三台服务器的内容是一样。

    • 如果服务器1、服务器2和服务器3的内容不一样,那我们可以根据用户请求来分发到不同的服务器

      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
      代理服务器
      server {
      listen 8082;
      server_name localhost;
      location /server1 {
      proxy_pass http://192.168.22.6:8081/;
      }
      location /server2 {
      proxy_pass http://192.168.22.6:8082/;
      }
      location /server3 {
      proxy_pass http://192.168.22.6:8083/;
      }
      }

      服务端
      server1
      server {
      listen 8081;
      server_name localhost;
      default_type text/html;
      return 200 '<h1>192.168.22.6:8081</h1>'
      }
      server2
      server {
      listen 8082;
      server_name localhost;
      default_type text/html;
      return 200 '<h1>192.168.22.6:8082</h1>'
      }
      server3
      server {
      listen 8083;
      server_name localhost;
      default_type text/html;
      return 200 '<h1>192.168.22.6:8083</h1>'
      }

负载均衡

  • 作用

    1. 解决服务器的高并发压力,提高应用程序的处理性能。

    2. 提供故障转移,实现高可用。

    3. 通过添加或减少服务器数量,增强网站的可扩展性。

    4. 在负载均衡器上进行过滤,可以提高系统的安全性。

  • /七层负载均衡

    • 七层负载均衡

      Nginx 要实现七层负载均衡需要用到proxy_pass 代理模块配置。Nginx 默认安装支持这个模块,我们不需要再做任何处理。Nginx 的负载均衡是在Nginx 的反向代理基础上把用户的请求根据指定的算法分发到一组【upstream 虚拟服务池】。

    • upstream 指令: 该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,并且也可以是同时监听TCP Unix socket 的服务器。服务器可以指定不同的权重,默认为1,位置:http

    • server 指令: 该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端口或者unix socket,位置: upstream

    • Nginx 七层负载均衡的实现流程

      Nginx七层负载均衡的实现流程
    • 服务端设置

      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
      # web 服务1/2/3
      server {
      listen 9001;
      server_name localhost;
      default_type text/html;
      location /{
      return 200 '<h1>192.168.200.146:9001</h1>';
      }
      }
      server {
      listen 9002;
      server_name localhost;
      default_type text/html;
      location /{
      return 200 '<h1>192.168.200.146:9002</h1>';
      }
      }
      server {
      listen 9003;
      server_name localhost;
      default_type text/html;
      location /{
      return 200 '<h1>192.168.200.146:9003</h1>';
      }
      }
      • 负载均衡器设置

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        upstream backend{
        server 192.168.200.146:9091;
        server 192.168.200.146:9092;
        server 192.168.200.146:9093;
        }
        # nginx 负载均衡
        server {
        listen 8003;
        server_name localhost;
        location /{
        proxy_pass http://backend;
        }
        }
  • 负载均衡状态

    状态 概述
    down 当前的server暂时不参与负载均衡
    backup 预留的备份服务器
    max_fails 允许请求失败的次数
    fail_timeout 经过max_fails失败后, 服务暂停时间
    max_conns 限制最大的接收连接数
    • down: 将该服务器标记为永久不可用,那么该代理服务器将不参与负载均衡

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      upstream backend{
      server 192.168.200.146:9001 down;
      server 192.168.200.146:9002
      server 192.168.200.146:9003;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
      # 该状态一般会对需要停机维护的服务器进行设置

    • backup: 将该服务器标记为备份服务器,当主服务器不可用时,将用来传递请求

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      upstream backend{
      server 192.168.200.146:9001 down;
      server 192.168.200.146:9002 backup;
      server 192.168.200.146:9003;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
    • max_conns

      max_conns=number: 用来设置代理服务器同时活动链接的最大数量,默认为0,表示不限制,使用该配置可以根据后端服务器处理请求的并发量来进行设置,防止后端服务器被压垮。

    • max_fails fail_timeout

      max_fails=number: 设置允许请求代理服务器失败的次数,默认为1

      fail_timeout=time: 设置经过max_fails 失败后,服务暂停的时间,默认是10 秒。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      upstream backend{
      server 192.168.200.133:9001 down;
      server 192.168.200.133:9002 backup;
      server 192.168.200.133:9003 max_fails=3 fail_timeout=15;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
  • 负载均衡策略

    算法名称 说明
    轮询 默认方式
    weight 权重方式
    ip_hash 依据ip分配方式
    least_conn 依据最少连接方式
    url_hash 依据URL分配方式
    fair 依据响应时间方式
    • 轮询:upstream 模块负载均衡默认的策略。每个请求会按时间顺序逐个分配到不同的后端服务器。轮询不需要额外的配置。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      upstream backend{
      server 192.168.200.146:9001 weight=1;
      server 192.168.200.146:9002;
      server 192.168.200.146:9003;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
    • weight 加权[加权轮询]

      1
      weight=number: 用来设置服务器的权重,默认为1,权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的,所有此策略比较适合服务器的硬件配置差别比较大的情况。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      upstream backend{
      server 192.168.200.146:9001 weight=10;
      server 192.168.200.146:9002 weight=5;
      server 192.168.200.146:9003 weight=3;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
    • ip_hash: 当对后端的多台动态应用服务器做负载均衡时,ip_hash 指令能够将某个客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来自某一个IP 的用户在后端Web 服务器A 上登录后,在访问该站点的其他URL,能保证其访问的还是后端web 服务器A

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      upstream backend{
      ip_hash;
      server 192.168.200.146:9001;
      server 192.168.200.146:9002;
      server 192.168.200.146:9003;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
    • least_conn: 最少连接,把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn 这种方式就可以达到更好的负载均衡效果

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      upstream backend{
      least_conn;
      server 192.168.200.146:9001;
      server 192.168.200.146:9002;
      server 192.168.200.146:9003;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }
      # 此负载均衡策略适合请求处理时间长短不一造成服务器过载的情况。
    • url_hash: 按访问url hash 结果来分配请求,使每个url 定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      upstream backend{
      hash &request_uri;
      server 192.168.200.146:9001;
      server 192.168.200.146:9002;
      server 192.168.200.146:9003;
      }
      server {
      listen 8083;
      server_name localhost;
      location /{
      proxy_pass http://backend;
      }
      }

Tomcat集群

  • 准备3 tomcat,使用端口进行区分[实际环境应该是三台服务器],修改server.xml,将端口修改分别修改为8080,8180,8280

  • 启动

  • Nginx对应的配置文件中添加如下内容

    1
    2
    3
    4
    5
    6
    upstream webservice{
    server 192.168.200.146:8080;
    server 192.168.200.146:8180;
    server 192.168.200.146:8280;
    }

Nginx 高可用解决方案

  • Keepalived: 使用Keepalived 来解决,Keepalived 软件由 C 编写的,最初是专为 LVS 负载均衡软件设计的,Keepalived 软件主要是通过 VRRP 协议实现高可用功能

    产生虚拟路由
  • VRRP 介绍

    VRRP(Virtual Route Redundancy Protocol)协议,翻译过来为虚拟路由冗余协议。VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP,而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,MASTER实现针对虚拟路由器IP的各种网络功能。其他设备不拥有该虚拟IP,状态为BACKUP,处了接收MASTERVRRP状态通告信息以外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。

    • 选择协议

      1
      VRRP可以把一个虚拟路由器的责任动态分配到局域网上的 VRRP 路由器中的一台。其中的虚拟路由即Virtual路由是由VRRP路由群组创建的一个不真实存在的路由,这个虚拟路由也是有对应的IP地址。而且VRRP路由1VRRP路由2之间会有竞争选择,通过选择会产生一个Master路由和一个Backup路由。
    • 路由容错协议

      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
          Master路由和Backup路由之间会有一个心跳检测,Master会定时告知Backup自己的状态,如果在指定的时间内,Backup没有接收到这个通知内容,Backup就会替代Master成为新的Master。Master路由有一个特权就是虚拟路由和后端服务器都是通过Master进行数据传递交互的,而备份节点则会直接丢弃这些请求和数据,不做处理,只是去监听Master的状态

      + 环境搭建

      + 环境准备

      | VIP(虚拟路由ip) | IP | 主机名 | 主/从 |
      | --------------- | --------------- | ----------- | ------ |
      | | 192.168.200.133 | keepalived1 | Master |
      | 192.168.200.222 | | | |
      | | 192.168.200.122 | keepalived2 | Backup |

      + `keepalived`的安装

      ```properties
      步骤1: 从官方网站下载 keepalived,官网地址https://keepalived.org/
      步骤2:将下载的资源上传到服务器
      keepalived-2.0.20.tar.gz
      步骤3:创建keepalived目录,方便管理资源
      mkdir keepalived
      步骤4:将压缩文件进行解压缩,解压缩到指定的目录
      tar -zxf keepalived-2.0.20.tar.gz -C keepalived/
      步骤5:keepalived进行配置,编译和安装
      cd keepalived/keepalived-2.0.20
      ./configure --sysconf=/etc --prefix=/usr/local
      make && make install


      安装完成后,有两个文件需要我们认识下,一个是 `/etc/keepalived/keepalived.conf`(keepalived的系统配置文件,我们主要操作的就是该文件),一个是/usr/local/sbin目录下的`keepalived`,是系统配置脚本,用来启动和关闭keepalived

firewall-cmd

  • 查询防火墙中指定的端口是否开放

    1
    firewall-cmd --query-port=9001/tcp
  • 如何开放一个指定的端口

    1
    firewall-cmd --permanent --add-port=9002/tcp
  • 批量添加开发端口

    1
    firewall-cmd --permanent --add-port=9001-9003/tcp
  • 如何移除一个指定的端口

    1
    firewall-cmd --permanent --remove-port=9003/tcp
  • 重新加载

    1
    firewall-cmd --reload
    1
    2
    3
     --permanent 表示设置为持久
    --add-port 表示添加指定端口
    --remove-port 表示移除指定端口

快速安装

  • 创建nginx-install.sh

    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
    vim  nginx-install.sh

    # 复制进该文件
    yum install -y gcc gcc-c++ autoconf automake make
    yum install -y gzip zlib zlib-devel openssl openssl-devel pcre pcre-devel wget httpd-tools vim
    cd /opt
    wget https://tengine.taobao.org/download/tengine-2.3.3.tar.gz
    tar -zxvf tengine-2.3.3.tar.gz
    cd tengine-2.3.3
    mkdir -p ~/.vim
    cp -r /opt/tengine-2.3.3/contrib/vim/* ~/.vim
    mkdir -p /opt/tbngx2.3.3
    cd tengine-2.3.3/
    ./configure --prefix=/opt/tbngx2.3.3 --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module --with-threads --with-file-aio

    make && make install

    yum -y install net-tools
    netstat -tunlp | grep 80

    cd /opt
    rm -rf tengine-2.3.3 tengine-2.3.3.tar.gz
    ls
    pwd
    echo -e "\033[31m Nginx安装文件路径为: /opt/tbngx2.3.3/ \033[0m"
    echo -e "\033[32m Nginx安装文件路径为: /opt/tbngx2.3.3/ \033[0m"
    echo -e "\033[33m Nginx安装文件路径为: /opt/tbngx2.3.3/ \033[0m"

    # 保存退出 赋予权限
    chmod 777 nginx-install.sh
    # 执行
    ./nginx-install.sh