1. Nginx介绍

准确地说,Nginx是一个HTTP服务器和反向代理服务器,可代理通用的TCP/UDP、HTTP以及Mail等服务,最初由俄罗斯人Igor Sysoev编写,也是一款开源软件。Nginx凭借着自身强大的产品功能,已被业界广泛采用。淘宝的Tengine都是基于Nginx的。

Nginx产品有着众多特征,负载均衡便是其中之一。Nginx服务器实现的负载均衡大多是七层负载均衡,但同时也具有四层负载均衡的能力。,

Nginx还有一个付费版Nginx Plus,相比Nginx有一些高级的功能。

2. Nginx 简单使用

2.1 安装

如果系统是CentOS的话,可直接使用epel源进行安装:

安装epel源

sudo yum install epel-release

安装Nginx

sudo yum install nginx

如果系统是Ubuntu,可用如下命令安装:

sudo apt install nginx

如果想使用源码编译安装的话,可到Nginx官网 http://nginx.org/ 下载源码后安装。

源码安装需要解决一些软件依赖的问题。比如http重写功能(http_rewrite_module)要用到的pcre库,http压缩功能(http_gzip_module)用到的zlib库,https协议用的openssl等,这些也需要单独下载源码后编译安装,然后在nginx configure时指定这些库所在的路径。

2.2 配置文件

Nginx的配置文件主要是nginx.conf,可配置的指令非常的多。另外需要注释的行可在行首使用符号’#’。 从架构上看,配置可分为三大块,如下:

全局配置块

Events配置块 {
}

http配置块 {
  server {
    location {
    }
  }
}

其中http配置块又包括server和location两个小块,server块用来指定开放的端口和域名等一些配置,location是用来匹配特定的URI后所采取的动作。同一指令放在不同的块中,其作用域也不相同

3 简单使用

3.1 静态网站

在http块中添加如下配置,可以使服务器做为静态网站。

server {
    listen       80;
    server_name  www.example.com;    

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

server_name 指令表示http匹配的域名,一旦匹配,便执行location块中的内容。

location 指令表示匹配到的URI,‘/’表示匹配所有地址,匹配成功则执行location块。

root 指令用来设置根目录,就是静态文件所在的路径,如果使用yum或者apt方式安装,根目录路径一般为 /usr/share/nginx/html/ ,此处只有一个html,为相对路径。

Index 指令用来指定网站首页文件,即用户访问www.example.com,实际等于访问www.example.com/index.html ,如果index.html不存在,则为www.example.com/index.htm。

3.2 代理服务器

在http块中添加如下配置,可以使服务器成为http代理服务器。

server {
    listen       80;
    server_name  www.example.com;    

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

这是代理服务器的最简单配置,proxy_pass指令指明了真正提供服务的服务器地址。如此处的127.0.0.1:8080表示为本机的tomcat服务。

理解了上面的两种用法,下面就可以说说Nginx的负载均衡功能了。

3.4 HTTP负载均衡

上面的http代理服务器功能,只代理了一台服务器(127.0.0.1:8080),其实如果换成代理多台服务器,那么可以说它就是负载均衡了。

那配置块里应该怎么写入多台服务器呢?答案是需要使用upstream指令把他们放到一起,该指令位于http块中。如下便是定义了一组服务器,并命名为backend。

http {
    upstream backend {
        server 192.168.1.100:8080;
        server 192.168.1.101:8080;
        server 192.168.1.102:8080;
    }
}

要将请求传递给服务器组,需要在proxy_pass指令中引用该组的名称backend,即用backend名字代替原来单台配置里的127.0.0.1:8080,参考如下配置:

server {
    location / {
        proxy_pass http://backend;
    }
}

这样Nginx就会将请求默认以轮询(round-robin)的方式发送给upstream backend里的服务器了。

分发请求方式当然也支持加权轮询,如下就是给服务器设置不同的权值:

http {
    upstream backend {
        server 192.168.1.100 weight=3;
        server 192.168.1.101;
        server 192.168.1.102;
    }
}

在这种配置下,每5个新的请求,其中3个请求会被分配到192.168.1.100,1个请求会被分配到192.168.1.101,1个请求会被分配到192.168.1.102。

Nginx还支持另外两种负载均衡方式,分别是最小连接(Least connected load balancing)和ip-hash。

在一些请求需要较长时间才能完成的情况下,最小连接可以更加公平地控制应用实例的负载,尽量避免过多的请求让繁忙的应用服务器超载,使新的请求被分配到一个不太繁忙的服务器上。

nginx中的最小连接负载均衡是在服务器组配置中使用least_conn指令时激活的。

最小连接的用法实例:

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

在轮询或最小连接负载均衡的情况下,每个后续客户端的请求都有可能被分配到不同的服务器上。

但如果需要将客户端绑定到特定的应用服务器上,换句话说,使客户端的会话 “粘性 “或 “持久性”,即总是试图选择一个特定的服务器,那么可以使用ip-hash负载均衡机制。

ip-hash用法实例:

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

Nginx中的反向代理能够对服务器进行健康检查。如果某台服务器的响应出现错误,nginx会将这台服务器标记为失败,并会在一段时间内避免选择这台服务器进行后续的入站请求。

max_fails指令设置了在失败超时(fail_timeout)期间与服务器通信的连续失败次数。默认情况下,max_fails设置为1。当它被设置为0时,该服务器的健康检查将被禁用。fail_timeout参数还定义了服务器被标记为失败的时间。在fail_timeout时间间隔后,nginx将开始探测服务器的实时客户端请求。如果探测成功,服务器将被标记为可用服务器。

upstream backend {
    ip_hash;
    server backend1.example.com max_fails=3 weight=2 fail_timeout=2s;;
    server backend2.example.com;
}

3.5 TCP/UDP负载均衡

知道了HTTP负载均衡的使用,我们下面说说Nginx的TCP和UDP负载均衡。

Nginx 1.9版本后开始支持TCP、UDP的负载均衡,但是需要在编译的时候指定stream模块(–with-stream)。

TCP、UDP负载均衡使用最高层级的stream块(HTTP是http块),比如下面的配置,和HTTP负载均衡配置是差不多的:

stream {
    upstream tcp_backend {
        server backend1.example.com:8080;
}
    upstream udp_backend {
        server backend1.example.com:53;
    }

    # tcp协议
    server {
       listen     80;
       proxy_pass tcp_backend;
}

# udp协议
    server {
       listen     53 udp;
       proxy_pass udp_backend;
    }
}

listen指令默认是指tcp协议,除非写明udp协议。