0%

Nginx入门

Nginx入门

基本概念

Nginx是什么,能做什么

Nginx是一个高性能的HTTP和反向代理web服务器,特点是占有内存少,并发能力强

反向代理

  1. 正向代理
    • 如果把局域网的Internet想象成一个巨大的资源库,则局域网中的客户端要访问Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。
    • 在客户端(浏览器)配置代理服务器,通过代理服务器进行互联网访问
  2. 反向代理
    • 反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

负载均衡

单个服务器解决不了高并发请求服务器满足不了的问题,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是负载均衡

动静分离

为了加快网络的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。

安装、命令和配置文件

安装

docker中

1
2
3
4
5
docker pull nginx
docker run --name mynginx -p 8888:80 -d nginx
docker start mynginx
# 进入容器
docker exec -it mynginx bash

常用命令

1
2
3
4
5
6
7
8
# 查看nginx的版本号
nginx -v
# 关闭nginx
nginx -s stop
# 启动nginx
nginx
# 重新加载
nginx -s reload

配置文件

docker中配置文件位置:/etc/nginx/nginx.conf

配置文件的三部分

  1. 全局块

    • 从配置文件到events块之间的内容,主要设置一些影响nginx服务器整体运行的配置指令,主要包括配置运行Nginx服务器的用户(组)、允许生成的worker process数、进程PID存放路径、日志存放路径和类型以及配置文件的引入
    • worker_processes 1;,其中worker_processes值越大,可以支持的并发处理量就越多,但会受到硬件、软件等设备的制约
  2. events块

    • events块涉及的指令主要影响Nginx服务器与用户的网络连接,常用的设置包括是否开启对多work process下的网络连接进行序列化、是否允许同时接收多个网络连接、选取哪种事件驱动模型来处理连接请求、每个word process可以同时支持的最大连接数等
    • worker_connections 1024;表示每个work process支持的最大连接数为1024
    • 这部分对Nginx的性能影响较大
  3. http块

    • Nginx服务器配置最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里

    • http块又包括http全局块、server块

    • http全局块

      • http全局块配置的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、单连接请求数上限等
    • server块(在较新版本中的存放位置:/etc/nginx/conf.d/default.conf)

      • 和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网硬件成本。每个http块可包括多个server块,而每个server块就相当于一个虚拟主机,而每个server块也分为全局server块,以及可同时包含多个location块

      • 全局server块

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

        listen:端口号

        server_name :主机名称

      • location块

        一个server块可以配置多个location块。主要作用是基于Nginx服务器接收到的请求字符串,对虚拟主机名称(也可以是IP别名)之外的字符串进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。

配置实例

配置反向代理

案例1

  1. 实现效果

    • 打开浏览器,在浏览器地址栏中输入地址www.123.com,跳转到tomcat页面
  2. 具体实现

    1. 在host文件中配置配置dns解析,将www.123.com解析到本地地址

    2. 在nginx进行请求转发配置(反向代理)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      server{
      listen 80;
      server_name 服务器地址;
      location / {
      root html;
      proxy_pass http://127.0.0.1:8080;
      index index.html
      }
      }

案例2

  1. 实现效果,监听端口8888,访问http://127.0.0.1:8888/a/ 直接跳转到127.0.0.1:8080;访问http://127.0.0.1:8888/b/直接跳转到127.0.0.1:8081

  2. 配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server{
    listen 8888;
    server_name 服务器地址;
    # ~表示正则表达式形式
    location ~ /a/ {
    proxy_pass http://127.0.0.1:8080;
    }
    location ~ /b/ {
    proxy_pass http://127.0.0.1:8081;
    }
    }

    配置文件中符号说明:

    ~:用于表示uri包含正则表达式,并且区分大小写

    =:用于不含正则表达式的uri前,要求请求字符串与uri严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求

    ~*:用于表示uri包含正则表达式,并且不区分大小写

    ^~:用于不含正则表达式的uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配

    注意:如果uri包含正则表达式,则必须要有*标识

配置负载均衡

  1. 实现效果,浏览器输入地址http://192.168.1.1/a.html,负载均衡效果,平均分配到8080和8081端口中

  2. 配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    server{
    listen 8888;
    server_name 服务器地址;
    upstream myserver{
    server 192.168.1.1:8080 weight=1;
    server 192.168.1.1:8081 weight=1;
    }
    location / {
    proxy_pass http://myserver;
    root hml;
    index index.html index.htm;
    }
    }
  3. Nginx提供了几种分配方式:

    1. 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down调,能自动剔除
    2. weight:weight代表权重,默认为1,权重越高,被分配的客户端越多,指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况
    3. ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题
    4. fair:按后端服务器的响应时间来分配请求,响应时间短的优先分配

配置动静分离

目录实现角度大致分两种:

  1. 纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案
  2. 动态根静态文件混合一直发布,通过nginx来分开

案例:

  1. 配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    server{
    listen 8888;
    server_name 服务器地址;

    location /www/ {
    root /data/;
    index index.html index.htm;
    }
    location /image/ {
    root /data/;
    autoindex on;
    }
    }

配置高可用集群

  1. 什么是Nginx的高可用

    • 两台Nginx服务器
    • keepalived
    • 虚拟ip
    • 完成当一个Nginx宕机后,仍然可用的功能
  2. 配置高可用的准备工作

    1. 需要两台服务器 192.168.1.1 和192.168.1.2
    2. 在两台服务器上安装nginx
    3. 在两台服务器上安装keepalived:yum install keepalived -y
  3. 分别在两台服务器上配置/etc/keepalived/keepalived.conf

    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
    global_defs {					#全局配置
    notification_email { #指定keepalived在发生切换时需要发送email到的对象,一行一个
    acassen@firewall.loc #指定收件人邮箱
    failover@firewall.loc
    sysadmin@firewall.loc
    }
    notification_email_from Alexandre.Cassen@firewall.loc #指定发件人
    smtp_server 192.168.1.129 #指定smtp服务器地址
    smtp_connect_timeout 30 #指定smtp连接超时时间
    router_id LVS_DEVEL #此处注意router_id为负载均衡标识,在局域网内应该是唯一的。
    }

    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 eth3s0f1 # 网卡
    virtual_router_id 51 #主、备机的virtual_router_id必须相同
    priority 100 # 主、备机取不同的优先级,主机值较大,备份机值较小
    advert_int 1 # 时间间隔,每隔1s发送心跳检测主机是否存活
    authentication {
    auth_type PASS
    auth_pass 1111 #此密码最多只支持八位数,建议密码不要设置太复杂,要尽可能简单,最好不要有特殊字符、汉字。
    }
    virtual_ipaddress {
    192.168.1.50 # 虚拟地址
    }
    }
  4. 编写nginx_check.sh脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # ! /bin/bash
    A=`ps -C nginx -no-header | wc -l`
    if [ $A -eq 0 ] ;then
    nginx # Nginx启动
    sleep 2
    if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
    killall keepalived
    fi
    fi
  5. 启动Nginx和keepalived

    1
    2
    nginx
    systemctl start keepalived.service

基本原理

  1. master&worker

    使用一个master进程和多个worker进程,一个master进程发送信号给多个worker进程

  2. worker如何进行工作

    当一个client给master时,多个worker争抢client

  3. 一个master和多个worker的好处

    1. 对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多,其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。
    2. 可以使用nginx -s reload热部署,利用nginx进程热部署操作
  4. 设置多少个worker

    Nginx同redis类似,都采用了io多路复用机制,每个worker都是一个独立的进程,但每个进程里只有一个主线程,通过异步非阻塞的方式来处理请求,即时是成千上万个请求也不在话下。每个worker的线程可以把一个cpu的性能发挥到极致。所以worker数和服务器的cpu数相等是最为适宜的。设少了会浪费CPU,设多了会造成CPU频繁切换上下文带来损耗。

  5. 设置worker数量

    1
    2
    3
    4
    5
    worker_processes 4
    # work绑定cpu(4work绑定4cpu)
    worker_cpu_affinity 0001 0010 0100 1000
    # work绑定cpu (4work绑定8CPU中的4个)
    worker_cpu_affinity 00000001 00000010 00000100 00001000
  6. 连接数worker_connection

    这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connectionsworker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections worker_processes,如果支持http1.1的浏览器,每次访问要占用两个连接,所以普通的静态访问最大并发数是:worker_connections * worker_processes/2,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/4。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接

    问题:

    1. 发送请求,占用worker的几个连接数?

      答案:2个或4个

    2. Nginx有一个master,四个worker,每个worker支持最大的连接数据1024,支持的最大并发数是多少?

      • 普通静态访问最大并发数:worker_connections * worker_processes / 2
      • 而如果是HTTP作为反向代理,最大并发数量是: worker_connections * worker_processes/4