Rumah  >  Artikel  >  pembangunan bahagian belakang  >  nginx负载均衡策略和配置

nginx负载均衡策略和配置

不言
不言asal
2018-06-05 10:11:181783semak imbas

这篇文章主要介绍了关于nginx负载均衡策略和配置 ,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

前言

先来简单了解一下什么是负载均衡,单从字面上的意思来理解就可以解释N台服务器平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。那么负载均衡的前提就是要有多台服务器才能实现,也就是两台以上即可。负载均衡是高并发、大流量网站必须要实现的技术。

环境

采用两机负载均衡部署

  测试域名  a.com

  A服务器IP: 10.1.108.31 (主服务器)

  B服务器IP: 192.168.112.128

部署思路

  A服务器做为主服务器,域名直接解析到A服务器(10.1.108.31 )上,由A服务器负载均衡到自身(10.1.108.31 )与B服务器(192.168.112.128)上。

需要负载均衡的项目

nodejs web项目,项目名称social,端口6602

分别在A服务器与B服务器上启动social项目(如何启动nodejs 项目在此不做介绍),在A服务器上安装nginx(如何安装在此不做介绍,B服务器不需要安装)。

部署

域名解析

由于不是真实环境,域名就随便使用一个a.com用作测试,所以a.com的解析只能在hosts文件设置。

打开:C:\Windows\System32\drivers\etc\hosts

在末尾添加

10.1.108.31  a.com

保存退出,然后启动命令模式ping下看看是否已设置成功

从截图上看已成功将a.com解析到10.1.108.31

配置nginx.conf

nginx安装目录的conf目录下,打开nginx.conf文件

http段加入以下代码


upstream a.com {
            server 127.0.0.1:6602;
            server 192.168.112.128:6602;
        }
server {
        listen       80;
        location / {
            proxy_pass http://a.com;      #设置反向代理的地址
            proxy_connect_timeout 2;      #代理服务器超时时间,秒
        }

注:

2个节点,其中一个宕机了,nginx还是会分发请求给它,直到超时,没有响应,然后发给另一个节点。默认1分钟内不会再发请求,一分钟后重复上述动作。这样的结果是网站时快时慢,设置proxy_connect_timeout 2秒,缩短超时时间,使其不至于太慢。

保存配置,启动nginx,访问a.com

                           图1

                          图2

如上图所示,访问了两次a.com,分别返回了A服务器和B服务器中是数据。表明nginx负载均衡配置成功。

nginx配置详解


user    www-data;                        #运行用户worker_processes  4;                   #启动进程,通常设置成和cpu的核数相等
worker_cpu_affinity 0001 0010 0100 1000;   #为每个进程绑定cpu内核,参考下面注解1
error_log  /var/log/nginx/error.log;   #全局错误日志pid        /var/run/nginx.pid;          #PID文件
#events模块中包含nginx中所有处理连接的设置
events {                            
   use   epoll;  #连接处理方式,参考注解2
  worker_connections  1024;    #单个后台worker process进程的最大并发链接数,不能超过最大文件打开数,最大文件打开数可以通过worker_rlimit_nofile修改。  multi_accept on;   #on:worker process一次接受所有新连接, off: 一次接受一个新的连接
}
#设定http服务器,利用它的反向代理功能提供负载均衡支持
http {
     
    include       /etc/nginx/mime.types;       #设定mime类型,类型由mime.type文件定义
   include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
    default_type  application/octet-stream;  #默认文件类型
   #charset utf-8; #默认编码
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  logs/access.log  main;       #设定日志格式
    
    sendfile        on;   #开启高效文件传输模式,sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的负载.注意:如果图片显示不正常把这个改成off。
   #防止网络阻塞,两者区别参考注解3    tcp_nopush     on;
   tcp_nodelay        on;
autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。    keepalive_timeout  30;                 #连接超时时间,单位秒
  #gzip模块设置  gzip on; #开启gzip压缩输出  gzip_min_length 1k; #最小压缩文件大小,大于1K才压缩  gzip_buffers 4 16k; #压缩缓冲区  gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)  gzip_comp_level 2; #压缩等级,1-10,数字越大压缩也越大  gzip_types text/plain application/x-javascript text/css application/xml;
  #压缩类型,默认就已经包含text/html,所以上面就不用再写了,写上去也不会有问题,但是会有一个warn。
  gzip_vary on;  # 和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩
  gzip_disable "MSIE [1-6]\.";  #禁用IE6的gzip压缩,IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死
    client_header_buffer_size    1k;    #设定请求头缓存大小    large_client_header_buffers  4 10k;  #设置用于读取大客户机请求头文件的最大数量和大小,超过则返回给客户端414或400错误。请求处理结束后缓存释放。
   #使用Nginx最大的好处就是负载均衡
   #upstream用于设置一组可以在proxy_pass指令中使用的代理服务器,默认的代理方式为轮询。    upstream mysvr {
      #设定负载均衡的服务器列表
      #server指令用于指定后端服务器的名称和参数。       server 192.168.8.1x:80  weight=5;
       server 192.168.8.2x:80  weight=1;   
       server 192.168.8.3x:80  weight=6; 
    }
   #在server内可通过proxy_pass指令设置关于反向代理的upstream服务器集群。             
   server {                
        listen       80;  #侦听192.168.8.x的80端口        server_name  192.168.8.x;
      
       location ~ .*\.aspx$ {     #对aspx后缀的进行负载均衡请求
            root   /root;             #定义服务器的默认网站根目录位置             index index.php index.html index.htm;   #定义首页索引文件的名称
             proxy_pass  http://mysvr ;                 #请求转向mysvr 定义的服务器列表
             #以下是一些反向代理的配置可删除.
             proxy_redirect off;
             #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
             proxy_set_header Host $host;
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_connect_timeout 90;     #nginx跟后端服务器连接超时时间(代理连接超时)
             proxy_send_timeout 90;        #后端服务器数据回传时间(代理发送超时)
             proxy_read_timeout 90;         #连接成功后,后端服务器响应时间(代理接收超时)
             proxy_buffer_size 4k;          #设置代理服务器(nginx)保存用户头信息的缓冲区大小             proxy_buffers 4 32k;     #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置             proxy_busy_buffers_size 64k;    #高负荷下缓冲大小(proxy_buffers*2)             proxy_temp_file_write_size 64k;  #设定缓存文件夹大小,大于这个值,将从upstream服务器传
         }
   }
}

nginx配置注解

1.worker_cpu_affinity注解

Nginx默认没有开启利用多核CPU,我们可以通过增加worker_cpu_affinity配置参数来充分利用多核CPU。CPU是任务处理,计算最关键的资源,CPU核越多,性能就越好。
配置Nginx多核CPU,worker_cpu_affinity使用方法和范例

2CPU,开启2个进程
worker_processes     2;
worker_cpu_affinity 01 10;

01表示启用第一个CPU内核,10表示启用第二个CPU内核
worker_cpu_affinity 01 10;表示开启两个进程,第一个进程对应着第一个CPU内核,第二个进程对应着第二个CPU内核。

2核CPU,开启4个进程
worker_processes     4;
worker_cpu_affinity 01 10 01 10;

开启了四个进程,它们分别对应着开启2个CPU内核

4核CPU,开户4个进程
worker_processes     4;
worker_cpu_affinity 0001 0010 0100 1000;

0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推

4核CPU,开启2个进程
worker_processes     2;
worker_cpu_affinity 0101 1010;

0101表示开启第一个和第三个内核,1010表示开启第二个和第四个内核
2个进程对应着四个内核
worker_cpu_affinity配置是写在/etc/nginx/nginx.conf里面的。
2核是 01,四核是0001,8核是00000001,有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。

8核CPU,开户8个进程
worker_processes     8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 0010000001000000 10000000;

0001表示启用第一个CPU内核,0010表示启用第二个CPU内核,依此类推
worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。

2.连接处理方式

nginx 支持多种连接处理方法,使用哪种方法取决于所使用的系统。系统支持多种方法时,nginx会自动选择最高效的方法。如果需要,可以通过use指令指定使用的方法。

select:

1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认32*32=1024. 
2.
操作限制:通过遍历FD_SETSIZE(1024)Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍

poll:

1.Socket数量几乎无限制:该模式下的Socket对应的fd列表由一个数组来保存,大小不限(默认4k). 
2.
操作限制:Select. 

epoll:

Linux 2.6以上版本

1.Socket数量无限制:Poll 
2.
操作无限制:基于内核提供的反射模式,有活跃Socket,内核访问该Socketcallback,不需要遍历轮询.

kqueue 

epoll相差不大,原理相同,用于操作系统:FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0, and MacOS X

select模式低效的原因
select
模式低效是由select的定义所决定的,与操作系统实现无关,任何内核在实现select时必须做轮循,才能知道这些socket的情况,这是会消耗 cpu的。此外,当你拥有一个很大socket集的时候,尽管任一时间只有小部分的socket"活跃"的,但每次你都不得不将所有的socket填入到一个FD_SET中,这也会消耗一些cpu,并且当select返回后,处理业务时你可能还需要做上下文映射,同样也会有一些性能影响,因此 selectepoll相对低效。
epoll
的适用情景就是大量的socket,但是活跃多不是很高的情况。

3.tcp_nodelay和tcp_nopush区别

tcp_nodelay

Nginx TCP_NODELAY 选项使得在打开一个新的 socket时增加了TCP_NODELAY选项。

但这时会造成一种情况:

终端应用程序每产生一次操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据以及40个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞。

为了避免这种情况,TCP堆栈实现了等待数据 0.2秒钟,因此操作后它不会发送一个数据包,而是将这段时间内的数据打成一个大的包。

这一机制是由Nagle算法保证。

Nagle化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为默认配置了,但有些场合下把这一选项关掉也是合乎需要的。

现在假设某个应用程序发出了一个请求,希望发送小块数据。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。

如果我们马上发送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。如果请求立即发出那么响应时间也会快一些。

以上操作可以通过设置套接字的 TCP_NODELAY = on 选项来完成,这样就禁用了Nagle 算法。    

另外一种情况则需要我们等到数据量达到最大时才通过网络一次发送全部数据,这种数据传输方式有益于大量数据的通信性能,典型的应用就是文件服务器。

Nginx keepalive 的连接中使用 TCP_NODELAY keepalive 连接会在数据发送后还保持连接状态,并还允许通过它发送更多数据。

这样就可以少实例化许多 socked 连接以及每次连接的三次握手过程。

tcp_nopush

nginx 中,tcp_nopush 配置和 tcp_nodelay 互斥。它可以配置一次发送数据的包大小。

也就是说,它不是按时间累计  0.2 秒后发送包,而是当包累计到一定大小后就发送。

nginx 中,tcp_nopush 必须和 sendfile 搭配使用。

4.负载均衡

nginx支持下面几种负载均衡机制:

1round-robin:轮询。以轮询方式将请求分配到不同服务器上,默认采用轮询方式。

2least-connected:最少连接数。将下一个请求分配到连接数最少的那台服务器上。

3ip-hash :基于客户端的IP地址。散列函数被用于确定下一个请求分配到哪台服务器上。

在一些要求需要更长的时间才能完成的应用情况下,最少连接可以更公平地控制应用程序实例的负载。使用最少连接负载均衡,nginx不会向负载繁忙的服务器上分发请求,而是将请求分发到负载低的服务器上。配置如下:


upstream mysvr {
   least-connected
  server 192.168.8.1:3128
  server 192.168.8.2:80
  server 192.168.8.3:80
}

Atas ialah kandungan terperinci nginx负载均衡策略和配置. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn