一、简介

  nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;nginx可以作为一个HTTP服务器进行网站的发布处理,另外nginx可以作为反向代理进行负载均衡的实现。

二、功能介绍

2.1、nginx负载均衡

负载均衡建立在现有网络结构之上,它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。负载均衡(Load Balance)其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。

  nginx提供的负载均衡能力主要包括Http负载均衡,和UDP和TCP负载均衡;

2.1.1、负载均衡算法

1、Round Robin:请求在服务器之间均匀分布,并考虑服务器权重(默认算法)

upstream backend {
   server backend1.example.com;
   server backend2.example.com;
}

2、Least Connections:在考虑服务器权重的同时,向活动连接数最少的服务器发送请求

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}

3、IP Hash:向其发送请求的服务器由客户端IP地址确定。在这种情况下,要么使用IPv4地址的前三个八位字节,要么使用整个IPv6地址来计算哈希值。该方法保证来自同一地址的请求可以到达同一服务器,除非该服务器不可用

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}

如果其中一个服务器需要从负载均衡组中暂时移除,可以用down参数标记它,以保持当前客户端IP地址的散列。将由此服务器处理的请求自动发送到组中的下一个服务器。

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}

4、Generic Hash:向其发送请求的服务器由用户定义的键确定,该键可以是文本字符串、变量或组合。例如,密钥可以是成对的源IP地址和端口,或者是URI。

upstream backend {
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

5、Least Time(NGINX Plus独有):对于每个请求,NGINX Plus选择平均延迟最低且活动连接数最少的服务器,其中最低平均延迟是根据包含到最短时间指令的以下哪些参数计算:
header :从服务器接收第一个字节的时间
last_byte:从服务器接收完整响应的时间
last_byte inflight:从服务器接收完整响应的时间,考虑到不完整的请求

upstream backend {
    least_time header;
    server backend1.example.com;
    server backend2.example.com;
}

6、Random:每个请求都将被传递到随机选择的服务器。如果指定了两个参数,NGINX首先考虑服务器权重随机选择两个服务器,然后使用指定的方法选择其中一个服务器
least_conn:活动连接数最少
least_time=header(NGINX Plus):从服务器接收响应头的最小平均时间($upstream_header_time)

least_time=last_byte(NGINX Plus):从服务器接收完整响应的最小平均时间($upstream_response_time)

upstream backend {
    random two least_time=last_byte;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    server backend4.example.com;
}

注意:在配置Round Robin以外的任何方法时,将相应的指令(hash、ip_hash、least_conn、least_time或random)放在upstream {}块中服务器指令列表的上方

其他设置:
Server Weights:默认情况下,NGINX使用Round-Robin方法根据请求的权重在组中的服务器之间分发请求。server指令的weight参数设置服务器的权重;默认值为1:

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

2.1.2、第三方算法

第三方的负载均衡策略的实现需要安装第三方插件

1、fair:按照服务器端的响应时间来分配请求,响应时间短的优先分配

#动态服务器组
upstream dynamic_zuoyu {
    server localhost:8080; 
    server localhost:8081; 
    server localhost:8082; 
    fair;    #实现响应时间短的优先分配
}

2、url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。

#动态服务器组
upstream dynamic_zuoyu {
    hash $request_uri;    #实现每个url定向到同一个后端服务器
    server localhost:8080; 
    server localhost:8081; 
    server localhost:8082;
}

2.2、缓存

缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。--百度百科

一般一个请求有:客户端缓存,代理端缓存(nginx),服务器缓存(redis、Memcache等)

nginx基本功能介绍和基本安装教程  第1张

  1. 客户端第一次向Nginx请求数据a;

  2. 当Nginx发现缓存中没有数据a时,会向服务端请求数据a;

  3. 服务端接收到Nginx发来的请求,则返回数据a到Nginx,并且缓存在Nginx;

  4. Nginx返回数据a给客户端应用;

  5. 客户端第二次向Nginx请求数据a;

  6. 当Nginx发现缓存中存在数据a时,则不会请求服务端;

  7. Nginx把缓存中的数据a返回给客户端应用

2.3、网络服务器

2.3.1、web服务器

nginx作为web服务器的优点:

  1. 轻量级,同样起web 服务,比apache占用更少的内存及资源 ,支持更多的并发连接,体现更高的效率,这点使 Nginx 尤其受到虚拟主机提供商的欢迎。在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 这归功于Nginx为我们选择了 epoll and kqueue 作为开发模型.

  2. 抗并发,nginx 处理请求是异步非阻塞的,而apache 则是阻塞型的,在高并发下nginx 能保持低资源低消耗高性能

  3. 高度模块化的设计,编写模块相对简单

  4. 社区活跃,各种高性能模块出品迅速啊

  5. Nginx本身就是一个反向代理服务器

  6. 负载均衡能力突出,Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务. Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多 apache是同步多进程模型,一个连接对应一个进程;nginx是异步的,多个连接(万级别)可以对应一个进程,一般来说,需要性能的web 服务,用nginx 。如果不需要性能只求稳定,那就apache 吧。当使用nginx作为web服务器时,其必须通过fastcgi协议结合php-fpm使用,而不能像apache那样直接将php作为自身的一个模块来处理请求。

nginx基本功能介绍和基本安装教程  第2张

当请求交给php-fpm处理之后,当前这个连接是不能断开的,nginx怎么处理这个连接?连接始终是存在,nginx要维持一段内存空间,保存连接的相关信息(客户端信息,请求报文等),称为接收缓冲区,而当nginx准备好数据之后,是通过发送缓存区响应请求给客户端,所以维持一个请求或者说是一段会话是需要空间的。

如果客户端能理解fastcgi报文,nginx直接将php-fpm数据处理好的通过fastcgi协议传送过来的响应报文给到客户端,拿到一位数据就放到发送缓冲区中,客户端直接拿到,这个过程就是同步的,nginx就是做了透明转发。但是上述的过程是不行的,客户端是无法理解的,php-fpm处理之后的fastcgi协议报文完全送给nginx之后,nginx需要处理成客户端能识别的http报文才行,所以存储fastcgi协议报文也是需要空间的,所以这种方式下是异步的

nginx基本功能介绍和基本安装教程  第3张

多个请求可能是相同的资源,所以我们可以再nginx中加缓存,当请求过来时,先查看缓存是否存在且没有过期,有的话,nginx取出缓存数据封装响应报文给到客户端,没有缓存再向动态服务器php-fpm请求数据,php-fpm返回数据后,nginx先缓存起来,再响应给客户端,这样就大大减少了动态服务器的压力。


2.3.2、反向代理

正向代理:如果把局域网外的 Internet 想象成一个巨大的资源库,则局域网中的客户端要访问 Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。

反向代理:其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址。

2.3.3、动静分离

动静分离:为了提高网站的响应速度,减轻程序服务器(Tomcat,Jboss等)的负载,对于静态资源比如图片,js,css等文件,我们可以在反向代理服务器中进行缓存,这样浏览器在请求一个静态资源时,代理服务器就可以直接处理,而不用将请求转发给后端服务器。用户请求的动态文件比如servlet,jsp则转发给Tomcat,Jboss服务器处理,这就是动静分离。这也是反向代理服务器的一个重要的作用。

  动静分离主要是通过nginx+tomcat来实现,其中nginx处理图片、html、JS、CSS等静态文件,tomcat处理jsp、servlet等动态请求。所以可以利用nginx作为文件服务器,在公司的内网搭建文件服务器,提供下载功能,挺方便。

  动静分离从目前实现角度来讲大致分为两种:一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开。

2.3.4、压缩和解压缩

压缩响应通常显著的减少传输数据的大小。然而,压缩发生在运行时,它也会增加相当大的处理开销对性能有负面的影响。Nginx在发送响应到客户端时执行压缩,但不对已经压缩的响应“二次压缩”。

  默认情况下,NGINX仅压缩MIME类型的响应text/html。要压缩其他MIME类型的响应,请包含gzip_types指令并列出其他类型。

2.4、高可用性

高可用HA(High Availability)是分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计减少系统不能提供服务的时间。如果一个系统能够一直提供服务,那么这个可用性则是百分之百,但是天有不测风云。所以我们只能尽可能的去减少服务的故障

  Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP (Virtual Router Redundancy Protocol ,虚拟路由器冗余协议)功能。因此,Keepalived除了能够管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、MySQL等)的高可用解决方案软件
Keepalived高可用服务之间的故障切换转移,是通过VRRP 来实现的。

  在 Keepalived服务正常工作时,主 Master节点会不断地向备节点发送(多播的方式)心跳消息,用以告诉备Backup节点自己还活着,当主 Master节点发生故障时,就无法发送心跳消息,备节点也就因此无法继续检测到来自主 Master节点的心跳了,于是调用自身的接管程序,接管主Master节点的 IP资源及服务。而当主 Master节点恢复时,备Backup节点又会释放主节点故障时自身接管的IP资源及服务,恢复到原来的备用角色

2.5、邮件代理

NGINX可以将IMAP,POP3和SMTP协议代理到承载邮件帐户的上游邮件服务器之一,因此可以用作电子邮件客户端的单个端点。这可能带来许多好处,例如:

  1. 轻松扩展邮件服务器的数量

  2. 根据不同的规则选择邮件服务器,例如,根据客户的IP地址选择最近的服务器

  3. 在邮件服务器之间分配负载

  使用--with-mail用于电子邮件代理功能的--with-mail_ssl_module参数和用于SSL / TLS支持的参数编译了Mail模块

三、编译安装

3.1、安装依赖

yum -y install gcc automake autoconf libtool make gcc-c++
 
#安装pcre
cd /usr/local/src
wget https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
tar -zxvf pcre-8.44.tar.gz
cd pcre-8.44
./configure
make
make install
 
#安装zlib
cd /usr/local/src
wget http://zlib.net/zlib-1.2.11.tar.gz
tar -zxvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
./configure
make
make install
 
#安装openssl
cd /usr/local/src
wget http://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar -zxf openssl-1.1.1d.tar.gz
cd openssl-1.1.1d
./Configure darwin64-x86_64-cc --prefix=/usr
make
make install

3.2、安装nginx

官网:https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/#sources

cd /usr/local/src
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar -zxvf nginx-1.18.0.tar.gz
cd nginx-1.18.0
 
./configure \
--sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-file-aio \
--with-http_realip_module \
--with-http_ssl_module \
--with-stream \
--with-mail=dynamic \
--with-pcre=/usr/local/src/pcre-8.44 \
--with-zlib=/usr/local/src/zlib-1.2.11 \
--with-openssl=/usr/local/src/openssl-1.1.1d
 
make
make install

3.3、编译参数

  • make是用来编译的,它从Makefile中读取指令,然后编译。

  • make install是用来安装的,它也从Makefile中读取指令,安装到指定的位置。

  • configure命令是用来检测你的安装平台的目标特征的。它定义了系统的各个方面,包括nginx的被允许使用的连接处理的方法,比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,它是个shell脚本,执行结束时,它会创建一个Makefile文件。nginx的configure命令支持以下参数: 

  • --prefix=path #定义一个目录,存放服务器上的文件 ,也就是nginx的安装目录。默认使用 /usr/local/nginx。

  • --sbin-path=path #设置nginx的可执行文件的路径,默认为 prefix/sbin/nginx.

  • --conf-path=path #设置在nginx.conf配置文件的路径。nginx允许使用不同的配置文件启动,通过命令行中的-c选项。默认为prefix/conf/nginx.conf.

  • --pid-path=path #设置nginx.pid文件,将存储的主进程的进程号。安装完成后,可以随时改变的文件名 , 在nginx.conf配置文件中使用 PID指令。默认情况下,文件名 为prefix/logs/nginx.pid.

  • --error-log-path=path #设置主错误,警告,和诊断文件的名称。安装完成后,可以随时改变的文件名 ,在nginx.conf配置文件中 使用 的error_log指令。默认情况下,文件名 为prefix/logs/error.log.

  • --http-log-path=path #设置主请求的HTTP服务器的日志文件的名称。安装完成后,可以随时改变的文件名 ,在nginx.conf配置文件中 使用 的access_log指令。默认情况下,文件名 为prefix/logs/access.log.

  • --user=name #设置nginx工作进程的用户。安装完成后,可以随时更改的名称在nginx.conf配置文件中 使用的 user指令。默认的用户名是nobody。

  • --group=name #设置nginx工作进程的用户组。安装完成后,可以随时更改的名称在nginx.conf配置文件中 使用的 user指令。默认的为非特权用户。

  • --with-select_module --without-select_module #启用或禁用构建一个模块来允许服务器使用select()方法。该模块将自动建立,如果平台不支持的kqueue,epoll,rtsig或/dev/poll。

  • --with-poll_module --without-poll_module #启用或禁用构建一个模块来允许服务器使用poll()方法。该模块将自动建立,如果平台不支持的kqueue,epoll,rtsig或/dev/poll。

  • --without-http_gzip_module #不编译压缩的HTTP服务器的响应模块。编译并运行此模块需要zlib库。

  • --without-http_rewrite_module #不编译重写模块。编译并运行此模块需要PCRE库支持。

  • --without-http_proxy_module #不编译http_proxy模块。

  • --with-http_ssl_module #使用https协议模块。默认情况下,该模块没有被构建。建立并运行此模块的OpenSSL库是必需的。

  • --with-pcre=path #设置PCRE库的源码路径。PCRE库的源码(版本4.4 - 8.30)需要从PCRE网站下载并解压。其余的工作是Nginx的./ configure和make来完成。正则表达式使用在location指令和 ngx_http_rewrite_module 模块中。

  • --with-pcre-jit #编译PCRE包含“just-in-time compilation”(1.1.12中, pcre_jit指令)。

  • --with-zlib=path #设置的zlib库的源码路径。要下载从 zlib(版本1.1.3 - 1.2.5)的并解压。其余的工作是Nginx的./ configure和make完成。ngx_http_gzip_module模块需要使用zlib 。

  • --with-cc-opt=parameters #设置额外的参数将被添加到CFLAGS变量。例如,当你在FreeBSD上使用PCRE库时需要使用:--with-cc-opt="-I /usr/local/include。.如需要需要增加 select()支持的文件数量:--with-cc-opt="-D FD_SETSIZE=2048".

  • --with-ld-opt=parameters #设置附加的参数,将用于在链接期间。例如,当在FreeBSD下使用该系统的PCRE库,应指定:--with-ld-opt="-L /usr/local/lib".

  • --add-module=<PATH> #静态加载第三方模块

  • --add-dynamic-module=<PATH> #动态加载第三方模块

四、nginx常用命令

[root@lgh1 nginx]# ./nginx -h
nginx version: nginx/1.18.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
 
Options:
  -?,-h         : this help 
  -v            : show version and exit #显示 nginx 的版本
  -V            : show version and configure options then exit #显示 nginx 的版本,编译器版本和配置参数
  -t            : test configuration and exit #测试配置参数并退出
  -T            : test configuration, dump it and exit# 测试配置参数,dump出并退出
  -q            : suppress non-error messages during configuration testing #在配置测试期间禁止显示非错误消息
  -s signal     : send signal to a master process: stop, quit, reopen, reload #发送信号给主进程;包括stop(停止), quit(退出), <br>          reopen(重新打开日志文件), reload(重新加载配置文件)
  -p prefix     : set prefix path (default: /usr/local/nginx/) #设置nginx的路径
  -c filename   : set configuration file (default: /usr/local/nginx/nginx.conf) # 为Nginx指定一个配置文件
  -g directives : set global directives out of configuration file #从配置文件中设置全局指令

 ./nginx   #启动nginx

五、配置文件格式说明

...              #全局块
events {         #events块
   ...
}
http      #http块
{
    ...   #http全局块
    server        #server块
    {
        ...       #server全局块
        location [PATTERN]   #location块
        {
            ...
        }
        location [PATTERN]
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     #http全局块
}

1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
2、events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
3、http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
4、server块:配置虚拟主机的相关参数,一个http中可以有多个server。
5、location块:配置请求的路由,以及各种页面的处理情况