Nginx 详细教程

Nginx 1. 基本概念 概述

  • Nginx 是一个高性能的 HTTP 和反向代理服务器
  • 特点是占有内存少,并发能力强
  • 专为性能优化而开发,性能是其最最要的考量
反向代理
  • 谈反向代理之前我们先来了解一下正向代理,比如现在我们要访问 www.google.com,谷歌大陆目前是不能直接访问的,那么我们就可以通过在浏览器配置代理服务器进行访问(如下图)
    Nginx 详细教程
    文章图片
  • 接下来我们介绍反向代理,客户端对代理无感知,客户端不需要任何配置,我们只需要将请求发送到反向代理服务器,然后由反向代理服务器去选择目标服务器获取数据后,再返回给客户端。此时反向代理服务器和目标服务器对外就是一个服务器。显然,反向代理对外暴露的是反向代理服务器,隐藏了真实服务器
  • 比如下图中,我们想目标服务器发出请求时,由反向代理服务器选择 tomcat 服务器 8001 端口,获取数据后,再将数据返回给客户端
    Nginx 详细教程
    文章图片
负载均衡
  • 客户端发送多个请求到服务器,服务器与数据库交互处理请求,处理完毕后,再将结果返回给客户端
    Nginx 详细教程
    文章图片
  • 这种架构模式适用于早期系统单一简单,并发较少的情况。随着信息数量的不断增长,访问量和请求量的飞速增长,服务器性能就会达到瓶颈,此时我们应该如何解决?
  • 首先想到的是提升服务器的配置,但是随着摩尔定律的日益失效,硬件的性能提升已经不能满足日益提升的性能需求。另外一个方法是我们可以增加服务器的数量,将请求分发到各个服务器上,这就是我们说的 负载均衡
  • 如下图,将 15 个请求分发到三台服务器上,理想状态是每台服务器 3 个请求
    Nginx 详细教程
    文章图片
动静分离
  • 为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度,降低原来单个服务器的压力
    Nginx 详细教程
    文章图片
2. Nginx 安装、命令和配置文件 Linux 中安装 Nginx
  • 安装 PCRE
    PCRE 作用是让 Nginx 支持 Rewrite 功能。
    cd /usr/src/ wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz

    Nginx 详细教程
    文章图片

    tar zxvf pcre-8.37.tar.gz

    Nginx 详细教程
    文章图片

    cd pcre-8.37/ ./configure make && make install

    Nginx 详细教程
    文章图片

    pcre-config --version

    Nginx 详细教程
    文章图片

  • 安装编译工具及库文件
    yum -y install make zlib zlib-devel gcc-c++ libtoolopenssl openssl-devel

    Nginx 详细教程
    文章图片

  • 安装 Nginx
    cd /usr/src/ wget http://nginx.org/download/nginx-1.12.2.tar.gz

    Nginx 详细教程
    文章图片

    tar zxvf nginx-1.12.2.tar.gz

    Nginx 详细教程
    文章图片

    cd nginx-1.12.2/ ./configure make && make install

    Nginx 详细教程
    文章图片

    /usr/local/nginx/sbin/nginx -v

    Nginx 详细教程
    文章图片

  • 安装成功后,在 usr 多出来一个文件夹 local/nginx,启动脚本为 /nginx/sbin/nginx
  • 测试
    cd /usr/local/nginx/sbin ./nginx ps -ef | grep nginx

    Nginx 详细教程
    文章图片

    直接访问 IP 地址可以看到如下界面
    Nginx 详细教程
    文章图片

    防火墙相关操作
    • 查看开放的端口号:firewall-cmd --list-all
    • 设置开放的端口号:firewall-cmd --add-service=http --permanent
      eg:sudo firewall-cmd --add-port=80/tcp --permanent
    • 重启防火墙:firewall-cmd --reload
    • 关闭防火墙:systemctl stop firewalld
    • 永久关闭防火墙:systemctl disable firewalld
Nginx 常用命令
使用 nginx 命令前要进入 nginx 目录:cd /usr/local/nginx/sbin
  • 查看 nginx 版本号:./nginx -v
    Nginx 详细教程
    文章图片
  • 启动 nginx:./nginx
    Nginx 详细教程
    文章图片
  • 关闭 nginx:./nginx -s stop
    Nginx 详细教程
    文章图片
  • 重载 nginx:./nginx -s reload
    Nginx 详细教程
    文章图片
  • 配置 systemctl
    配置 systemctl 后的启动方式
    • 状态:ssytemctl status nginx
    • 启动:systemctl start nginx
    • 关闭:systemctl stop nginx
    • 重启:systemctl restart nginx
    配置方法
    • nginx.service
      cd /usr/lib/systemd/system vim nginx.service

    • 【Nginx 详细教程】将以下内容复制进去(注释的内容不要放进去!!!)
      [Unit]//对服务的说明 Description=nginx - high performance web server//描述服务 After=network.target remote-fs.target nss-lookup.target//描述服务类型[Service]//服务的一些具体运行参数的设置 Type=forking//后台运行的形式 PIDFile=/usr/local/nginx/logs/nginx.pid//PID文件的路径 ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf//启动 准备 ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf//启动命令 ExecReload=/usr/local/nginx/sbin/nginx -s reload//重启命令 ExecStop=/usr/local/nginx/sbin/nginx -s stop//停止命令 ExecQuit=/usr/local/nginx/sbin/nginx -s quit//快速停止 PrivateTmp=true//给服务分配临时空间[Install] WantedBy=multi-user.target//服务用户的模式

    • 赋予权限:chmod +x /usr/lib/systemd/system/nginx.service
    • 启动服务
      // 启动服务之前,需要先重载 systemctl 命令 systemctl daemon-reload systemctl start nginx.service

      报错直接 kill -9 杀死重新拉起即可
Nginx 配置文件
Nginx 配置文件位置:/usr/local/nginx/conf/nginx.conf
配置文件由三部分组成
  • 第一部分:全局块(从配置文件开始到 events 块之间的内容)
    • 主要设置一些影响 Nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数、进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等
    • worker_processes 1:Nginx 服务器并发处理的值,worker_processes 值越大,可以支持的并发处理数量越多
  • 第二部分:events 块
    events { worker_connections1024; }

    • events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,比如 worker_connections 1024; 表示 Nginx 支持的最大连接数为 1024
  • 第三部分:http 块(http 块也可以包括 http 全局块、server 块)
    • http 全局块:http 全局块配置的指令包括文件引入、MIME-TYPE 类型、日志自定义、连接超时时间、单链接请求数上限等
    • server 块:这块和虚拟主机有密切联系,每个 http 块可以包括多个 server 块,每个 server 块就相当于一个虚拟主机,每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块
      • 全局 server 块:最常见的配置是本虚拟主机的监听配置和本虚拟主机的名称或 IP 配置
      • location 块:主要作用的是基于 Nginx 服务器接收到的请求字符串(eg:server_name/uri-string),对虚拟主机名称(也可以是 IP 别名)之外的字符串(eg:/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行
3. Nginx 配置实例 <0> 准备工作
  • 安装 tomcat,使用默认端口号 8080
    cd /usr/src wget https://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.5.73/bin/apache-tomcat-8.5.73.tar.gz tar zxvf apache-tomcat-8.5.73.tar.gz

    Nginx 详细教程
    文章图片

  • 安装 jdk:可参考此教程 Linux 安装和配置 JDK13
  • 启动 tomcat
    cd /usr/src/apache-tomcat-8.5.73/bin/ ./startup.sh

    Nginx 详细教程
    文章图片

  • 访问 tomcat(服务器要开放 8080 端口)
    Nginx 详细教程
    文章图片

    <1> 反向代理 ? 实例一
  • 实现效果:打开浏览器,在浏览器地址输入地址 www.123.com,跳转到 Linux 系统 tomcat 主页面中
  • 过程分析:Windows 浏览器不能直接访问t omcat,要通过 nginx 反向代理到 tomcat
    Nginx 详细教程
    文章图片
  • 具体配置
    • 在 Windows 系统的 host 文件进行域名和 ip 对应关系的配置 C:\Windows\System32\drivers\etc\hosts
      Nginx 详细教程
      文章图片

      Nginx 详细教程
      文章图片
    • 在 nginx 进行请求转发的配置(反向代理)
      cd /usr/local/nginx/conf/ vim nginx.conf

      Nginx 详细教程
      文章图片

    • 测试
      //启动 nginx cd /usr/local/nginx/sbin ./nginx

      Nginx 详细教程
      文章图片

<2> 反向代理 ? 实例二
  • 实现效果:使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中,nginx 监听端口为 9001
    • 访问 http://118.195.179.192:9001/edu/ 直接跳转到 127.0.0.1:8080
    • 访问 http://118.195.179.192/vod/ 直接跳转到 127.0.0.1:8081
  • 准备工作
    • 准备两个 tomcat 服务器,一个 8080 端口,一个 8081 端口
      cd /usr/src mkdir tomcat8008 mkdir tomcat8081 cp apache-tomcat-8.5.73.tar.gz tomcat8080 cp apache-tomcat-8.5.73.tar.gz tomcat8081 ps -ef | grep tomcat kill -9 端口号 cd tomcat8080 tar zxvf apache-tomcat-8.5.73.tar.gz cd .. cd tomcat8081 tar zxvf apache-tomcat-8.5.73.tar.gz cd .. cd tomcat8080 cd apache-tomcat-8.5.73/ cd bin/ ./startup.sh cd .. cd .. cd .. cd tomcat8081 cd apache-tomcat-8.5.73/ cd conf vim server.xml

      shutdown 端口随便改一下,我这里改成 8015
      Nginx 详细教程
      文章图片

    • 端口改成 8081
      Nginx 详细教程
      文章图片

      启动 tomcat8081
      ./startup.sh

      可以看到我们启动了两个 tomcat,一个是 8080,一个是 8081
      Nginx 详细教程
      文章图片

      我们可以访问看一下
      Nginx 详细教程
      文章图片

    Nginx 详细教程
    文章图片

  • 创建文件夹和测试页面
    • /usr/src/tomcat8080/apache-tomcat-8.5.73/webapps 下创建 edu 文件夹,并在文件夹下创建 a.html 文件,内容为 8080!!!
      Nginx 详细教程
      文章图片
    • 同样的,在 /usr/src/tomcat8081/apache-tomcat-8.5.73/webapps 下创建 vod 文件夹,并在文件夹下创建 a.html 文件,内容为 8081!!!
      Nginx 详细教程
      文章图片
  • 具体配置
    • 找到 nginx 配置文件进行反向代理配置
      cd /usr/local/nginx/conf vim nginx.conf

      添加一个 server
      server { listen9001; server_name118.195.179.192; location ~ /edu/ { proxy_pass http://127.0.0.1:8080; }location ~ /vod/ { proxy_pass http://127.0.0.1:8081; } }

      Nginx 详细教程
      文章图片

      开放端口号 9001、8080、8081
      重新加载 nginx
      cd /usr/local/nginx/sbin ./nginx --s stop ./nginx

  • 最终测试
    Nginx 详细教程
    文章图片

    Nginx 详细教程
    文章图片
  • location 指令说明
    • 该指令用于匹配 URL ,语法如下:
      location [ = | ~ | ~* | ^~] uri {}

    • =:用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求
    • ~:用于表示 url 包含正则表达式,并且区分大小写
    • ~*:用于表示 uri 包含正则表达式,并且不区分大小写
    • ^~:用于不含正则表达式的 uri 前,要求 nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配
<3> 负载均衡
  • 实现效果:通过浏览器地址栏输入地址 http://118.195.179.192/edu/a.html,负载均衡效果,平均 8080 和 8081 端口
  • 准备工作
    • 准备两台 tomcat 服务器,一台 8080,一台 8081(上一个实例已经准备过)
    • 在两台 tomcat 的 webapps 目录下,创建名称为 edu 文件夹,在 edu 文件夹创建 a.html 页面,用于测试
  • 在 nginx 的配置文件中进行负载均衡的配置
    cd /usr/local/nginx/conf vim nginx.conf

    Nginx 详细教程
    文章图片

  • 测试
    Nginx 详细教程
    文章图片
    Nginx 详细教程
    文章图片
  • 负载均衡分配策略
    • 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除
    • weight
      • weight 代表权重,默认为1,权重越高被分配的客户端越多
      • 指定轮询几率,weight 和访问比率成正比,用于后端服务器性能不均的情况
        upstream myserver { server 118.195.179.192:8080 weight=5; server 118.195.179.192:8081 weight=10; }

    • ip_hash :每个请求按访问 ip 的 hash 结果分配,这样每个访问固定访问一个后端服务器,可以解决 session 问题,eg
      upstream myserver { ip_hash; server 118.195.179.192:8080; server 118.195.179.192:8081; }

    • fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配
      upstream myserver { server 118.195.179.192:8080; server 118.195.179.192:8081; fair; }

<4> 动静分离
动静分离从目前实现角度来讲大致分为两种
  • 一种是纯粹把静态文件独立成到单独的域名,放在独立的服务器上
  • 另一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开
通过 location 指定不同的后缀名实现不同的请求转发。通过 expires 参数设置,可以使浏览器缓存过期期间,减少与服务器之前的请求和流量。具体 expires 定义:是给一个资源设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可,所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件,不建议使用 Expires 来缓存)。比如:设置 3d,表示在 3 天之内访问这个 URL,发送一个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码 304,如果有修改,则直接从服务器重新下载,返回状态码 200
  • 准备工作
    • 在 Linux 系统中准备静态资源,用于进行访问
      cd / mkdir static cd static mkdir www mkdir image

      www 文件夹中创建文件 a.html ,内容为 test html
      image 文件夹中随便放一张图片,我这里放的是 01.jpg
  • 实现效果:浏览器访问 www 下 a.html 和 image 下 01.jpg(不是通过 tomcat,而是通过 nginx 静态资源配置访问)
  • 具体配置
    cd /usr/local/nginx/conf vim nginx.conf

    Nginx 详细教程
    文章图片

    启动/重启 nginx
    cd /usr/local/nginx/sbin ./nginx

  • 测试
    • 浏览器输入地址 http://118.195.179.192/image/01.jpg
      Nginx 详细教程
      文章图片

      Nginx 详细教程
      文章图片
    • 浏览器输入地址 http://118.195.179.192/www/a.html
      Nginx 详细教程
      文章图片
<5> 高可用集群
  • 什么是高可用?
    • 有一台主服务器和一台备份服务器,一般请求时都是根据主服务器发送请求,当主服务器的 Nginx 挂掉时,会自动切换到备份服务器,通过备份服务器进行访问,此时备份服务器作为主服务器的位置来处理请求,这就是高可用
    Nginx 详细教程
    文章图片

  • 准备工作
    • 需要两台 Nginx 服务器
    • 在两台服务器安装 nginx (前面有教程)
    • 在两台服务器安装 keepalived
      yum install keepalived -y
      安装目录为:/etc/keepalived
      查看是否被安装:rpm -q -a keepalived
      Nginx 详细教程
      文章图片
  • 完成高可用配置(主备配置)
    cd /etc/keepalived vim keepalived.conf

    主服务器
    global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL }vrrp_script chk_http_port { script "/usr/local/src/nginx_check.sh" interval 2# 检测脚本执行的间隔 weight 2 }vrrp_instance VI_1 { state MASTER# 备份服务器上将 MASTER 改为 BACKUP interface eth0# 网卡 virtual_router_id 51# 主、备机的 virtual_router_id 必须相同 priority 100# 主、备机取不同的优先级,主机值较大,备机值较小 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16# VRRP H 虚拟地址 } }

    备份服务器
    global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL }vrrp_script chk_http_port { script "/usr/local/src/nginx_check.sh" interval 2# 检测脚本执行的间隔 weight 2 }vrrp_instance VI_1 { state BACKUP# 备份服务器上将 MASTER 改为 BACKUP interface eth0# 网卡 virtual_router_id 51# 主、备机的 virtual_router_id 必须相同 priority 90# 主、备机取不同的优先级,主机值较大,备机值较小 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16# VRRP H 虚拟地址 } }

    在主服务器和备份服务器 /usr/local/src 下编写文件 nginx_check.sh
    #!/bin/bash A=`ps -C nginx -no-header |wc -1` if [ $A -eq 0 ]; then /usr/local/nginx/sbin/nginx# Nginx 启动脚本位置 sleep 2 if [ `ps -C nginx --no-header |wc -1` -eq 0 ]; then killall keepalived fi fi

    启动两台服务器的 nginx 和 keepalived
    cd /usr/local/nginx/sbin ./nginx systemctl start keepalived

  • 测试:两台服务器要在同一局域网,我这里只是为了演示流程
  • keepalived 配置文件详解
    • global_defs:全局配置(主要是 router_id 服务器名字/etc/host 添加主机名称)
    • vrrp_script:脚本配置
      • script "xxx.sh"
      • interval 2:检测脚本执行的间隔(2s)
      • weight -20:权重(当脚本中的条件成立,当前主机的权重降低20)
    • vrrp_instance:虚拟 IP 配置
      • state BACKUP:表示服务器是主服务器(MASTER)还是备份服务器(BACKUP)
      • interface eth0:绑定的网卡(通过 ifconfig 查看)
      • virtual_router_id 51:主备机的id值,相当于唯一标识
      • priority 90:优先级,值越大,优先级越高(一般主服务器设置为 100,从服务器小于 100,比如 90)
      • advert_int 1:每隔多长时间发送一个心跳,检测服务器是否或者,默认每隔 1 s 发送一个心跳
      • authentication {auth_type PASS auth_pass 1111}:权限校验方式(密码:1111)
      • vritual_ipaddress:绑定虚拟 IP(可以绑定多个)
4. Nginx 原理
  • nginx 启动后有两个进程:master 和 worker
    Nginx 详细教程
    文章图片
  • master 就相当于一个领导,不做具体工作,分配任务给 worker,worker 做具体的任务
  • worker 如何进行工作?
    • 当 client(客户端)发送一个请求到 nginx,首先到 master,master 得到请求后,将请求分担给 worker,一个 master 下面有很多个 worker,worker 获取任务不是平均分配,也不是轮询,而是 争抢 的机制
client 发送请求 -> master ->worker(争抢机制) -> 具体操作
  • 一个 master 和多个 worker 有什么好处?
    • 可以使用 nginx -s reload 热部署,利于 nginx 进行热部署操作
    • 每个 worker 都是独立的进程,不需要加锁,一个进程退出后,其他进程可正常工作,降低风险
  • 设置多少个 worker 合适?
    • Nginx 同 redis 类似都采用了 IO 多路复用机制,每个 worker 都是一个独立的进程,每个进程里只有一个主线程,通过异步非阻塞方式来处理请求。每个 worker 的线程可以把一个 CPU 的性能发挥到极致。因此,worker 数和服务器的 CPU 数相等是最为适宜的。设少了会浪费 CPU,设多了会造成 CPU 频繁切换上下文带来的损耗
  • 连接数 worker_connection(每个 worker 进程所能建立连接的最大值)
    • 发送一个请求,占用了 worker 的几个连接数?答案:2(client 访问静态资源,worker 收到请求后返回) 或者 4 个(worker 本身不支持 Java,worker 要把请求转发给 tomcat,tomcat 再返回)
    • nginx 有一个 master,有 4 个 worker,每个 worker 支持的最大连接数为 1024, 支持的最大的并发数为多少?
      worker 最大支持的连接数 4*1024 worker 支持的最大并发 4*1024/2=2048 或 4*1024/4=1024

    普通的静态访问最大并发数是:worker_connections * worker_processes / 2
    作为反向代理来说,最大的并发数量是:worker_connections * worker_processes / 4
    【注】worker_connections:每个 worker 支持的最大连接数(即上面所说的 1024)
    worker_processes:worker 的数量

    推荐阅读