nginx1.18.0集群安装(docker版)

 

主机规划

192.168.31.101   cancer01   nginx loader balancer

192.168.31.102   cancer02   nginx web1

192.168.31.103   cancer03   nginx web2

环境准备

以下设置请根据实际情况自行配置,此处略

设置IP

       设置主机名

       关闭防火墙

       关闭selinux

       禁用透明大页

       设置虚拟内存

       设置文件句柄数和进程数

       主机时间同步

       配置免密

       安装jdk

       添加用户

       授权sodu

       设置防火墙端口(若防火墙开启则设置)

       ……

安装docker

在每台主机上安装docker环境。

 

安装yum-utils:

yum install -y yum-utils

 

安装依赖

yum install -y device-mapper-persistent-data lvm2

 

为yum源添加docker仓库位置:

yum repolist

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

 

安装docker:

yum install -y docker-ce

 

启动docker:

systemctl start docker

 

安装ngnix

在每台主机上安装ngnix。

 

下载nginx镜像:

docker pull nginx:1.18.0

 

列出镜像

docker images

 

先运行一次容器(为了拷贝配置文件):

(多行)

docker run --net="host" -p 80:80 --name nginx \

-v /usr/local/nginx/html:/usr/share/nginx/html \

-v /usr/local/nginx/logs:/var/log/nginx  \

-d nginx:1.18.0

(一行)

docker run --net="host" -p 80:80 --name nginx -v /usr/local/nginx/html:/usr/share/nginx/html -v /usr/local/nginx/logs:/var/log/nginx -d nginx:1.18.0

 

将容器内的配置文件拷贝到指定目录:

docker container cp nginx:/etc/nginx /usr/local/nginx/

 

修改文件名称:

cd /usr/local/nginx

mv nginx conf

 

终止并删除容器:

docker stop nginx

docker rm nginx

 

启动nginx服务:

(多行)

docker run --net="host" -p 80:80 --name nginx \

-v /usr/local/nginx/html:/usr/share/nginx/html \

-v /usr/local/nginx/logs:/var/log/nginx  \

-v /usr/local/nginx/conf:/etc/nginx \

-d nginx:1.18.0

(一行)

docker run --net="host" -p 80:80 --name nginx -v /usr/local/nginx/html:/usr/share/nginx/html -v /usr/local/nginx/logs:/var/log/nginx -v /usr/local/nginx/conf:/etc/nginx -d nginx:1.18.0

 

列出所有容器

docker ps -a

 

查看进程

ps -ef | grep nginx

 

查看端口

netstat -ntlp

 

查看80端口占用

lsof -i:80

可查看80端口被那个进程占用。

 

配置ngnix

在cancer01主机上如下配置:

cd /usr/local/nginx/conf/conf.d/

vim cancer.conf

 

upstream cancer{

   ip_hash;

       server 192.168.31.102:80;

       server 192.168.31.103:80;

    }

server {

        listen               80;

        server_name        cancer01;

        location / {

             proxy_set_header X-Real-IP $remote_addr;

             proxy_buffering off;

             proxy_connect_timeout 5;

             proxy_read_timeout 5;

             proxy_send_timeout 5;

             proxy_pass http://cancer;

        }

    }

 

在cancer01主机上如下配置:

cd /usr/local/nginx/html/

vim index.html

       hello cancer01

 

在cancer02主机上如下配置:

cd /usr/local/nginx/html/

vim index.html

       hello cancer02

 

在cancer03主机上如下配置:

cd /usr/local/nginx/html/

vim index.html

       hello cancer03

 

启动ngnix

在每台主机上重新启动nginx:

docker restart nginx

 

验证

http://192.168.31.101

http://cancer01

 

负载均衡说明

配置说明

upstream模板定义的后端服务器列表中选取一台服务器接收用户的请求。一个基本的upstream模块如下:

upstream [服务器组名称]{

  server [IP地址]:[端口号];

  server [IP地址]:[端口号];

  ....

}

upstream模块配置完成后,要让指定的访问反向代理到服务器列表,格式如下:

location ~ .*$ {

  index index.jsp index.html;

  proxy_pass http://[服务器组名称];

}

 

1,编辑配置文件:用upstream定义一个集群

#upstream :                        定义一个上游服务器集群

#webcluster :                      集群的名称,用来区分

#server 172.18.1.2:80       指定集群的机器ip的端口

   upstream webcluster{

       server 172.18.1.2:80;

       server 172.18.1.3:80;

    }

 

2,在server配置访问中使用上面定义的webcluster集群

   server {

        listen               80;

        server_name        localhost;

        location / {

             proxy_set_header X-Real-IP $remote_addr;

             proxy_buffering off;

             proxy_connect_timeout 5;

             proxy_read_timeout 5;

             proxy_send_timeout 5;

             proxy_pass http://webcluster;

        }

    }

 

3,配置中各个指令的说明:

proxy_pass,将代理转发给上方 upstream 中配置的集群中的两台服务器去处理

X-Real-IP,用来得到真实ip,否则在后端看到的都是loader的ip。proxy_set_header X-Real-IP $remote_addr;

proxy_buffering,默认值是on,这里我们把它关闭,off。它负责开启从后端被代理服务器的响应body缓冲,我们需要从后端服务器按收实时的数据,所以关闭

proxy_connect_timeout,该指令设置与upstream server的连接超时时间,默认值60s,最高不能超过75秒。注意这个不是等待后端返回页面的时间(那个时长是由proxy_read_timeout变量来定义)。如果upstream服务器正在运行中,但是没有响应,则这个指令不会起作用,因为与upstream服务器的连接已经建立

proxy_read_timeout,该指令设置与代理服务器的读超时时间。它决定了nginx会等待多长时间来获得请求的响应。如果两次读操作之间经过指定的时间还收不到upstream响应的数据,视为超时,默认值:60s

proxy_send_timeout,这个指定设置了发送请求给upstream服务器的超时时间,如果两次写操作之间经过指定的时间不能发送到upstream,视为超时。默认值:60s

 

调度算法

目前Nginx的upstream模块支持6种方式的负载均衡策略(算法):

rr (轮询)

wrr (就是rr的基础上加上权重weight)

ip_hash (根据ip分发)

url_pash (根据url分发)

least_conn (分发给连接数少的机器)

fair (按响应时间分发,是第三方的算法,如使用需要安装时添加相应的模块)

 

1)轮询

  最基本的配置方法,是upstream模块默认的负载均衡策略。每个请求会按时间顺序平均分配到不同的后端服务器。有如下参数:

fail_timeout    与max_fails结合使用

max_fails        在fail_timeout参数设置的时间内最大失败次数。如果在这个时间内,所有该服务器的请求都失败了,那么认为该服务器停机

fail_time         服务器被认为停机的时长,默认10s(被认为停机的服务器尝试间隔?)

backup          标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里

down             标记服务器永久停机

  注意:1.down标记的服务器会自动剔除;2.缺省就是轮询;3.此策略适合服务器配置无状态且短平块的服务使用

 

max_fails /fail_timeout

    例子:

     upstream webcluster{

       server 172.18.1.2:80 max_fails=3 fail_timeout=60s;

       server 172.18.1.3:80 max_fails=3 fail_timeout=60s;

    }

在fail_timeout参数定义的时间段内,如果失败的次数达到max_fails的值,Nginx就认为服务器不可用,标记此机器为fail,

当前的fail_timeout时长内不再尝试连接,到下一个再去尝试请求,如果连接成功,则恢复之前的分发,如果仍然不可用,则继续等到下一个周期再尝试

默认值:  fail_timeout为10s,max_fails为1次

建议值:  机器出故障一般没那么容易恢复,建议设置为: 3/60

说明:后端服务器连接失败时,会记录到error_log日志中:

2020/05/12 05:44:32 [error] 483#0: *7 connect() failed (111: Connection refused) while connecting to upstream,

client: 172.18.0.1, server: localhost, request: "GET / HTTP/1.1", upstream: "http://172.18.1.3:80/", host: "192.168.3.59"

 

down

表示此服务器已被手动停用

例子:

     upstream webcluster{

       server 172.18.1.2:80 max_fails=3 fail_timeout=60s down;

       server 172.18.1.3:80 max_fails=3 fail_timeout=60s;

    }

 

backup

表示此服务器是备用服务器,只有其它后端服务器都宕机或者很忙才会访问到,所以在集群中压力最小

例:

    upstream webcluster{

       server 172.18.1.2:80 max_fails=3 fail_timeout=60s;

       server 172.18.1.3:80 max_fails=3 fail_timeout=60s backup;

    }

 

2)weight

权重方式,在轮询策略的基础上指定轮询的几率。也可以认为是在轮询的基础上新增了一个weight的参数,此参数指定轮询的几率,值为number。

    如果后端服务器的性能或带宽有差异时,可以用这个值来调整压力的分配

upstream模块配置模板如下:

upstream [服务器组名称]{

  server [IP地址]:[端口号] weight=2;

  server [IP地址]:[端口号];

  ....

}

  在该例子中,没有weight参数的服务器默认为1,weight的数值与访问比例成正比,所有weight值的总和为一个循环单位,服务器自身的weight值为循环单位内的轮询次数。

  注意:1.权重越高分配到的请求越多;2.此策略可以和least_conn策略、iphash策略结合使用;3.此策略比较适合服务器硬件配置差距较大的情况。

 

3)ip_hash

  依据ip分配方式,指定负载均衡器按照基于客户端IP的分配方式,这个方法确保了相同的客户端请求一致发送到相同的服务器,以保证session会话。这样每个访客都固定访问一个后端服务器,可以解决session不能跨服务器的问题。upstream模块配置模板如下:

upstream [服务器组名称]{

  ip_hash;

  server [IP地址]:[端口号] weight=2;

  server [IP地址]:[端口号];

  ....

}

注意:1.nginx1.3.1之前的版本不能在ip_hash中使用权重(weight);2..ip_hash不能与backup同时使用;3.此策略适合有状态服务的程序,比如session;4.当有服务器需要剔除,必须手动down掉。

如果同一个ip发出的请求能分发到相同的后端机器,则一定程度上可以提高访问效率,因为可以避免多次建立http连接

注意:如果用户使用带有服务端缓存功能的浏览器(比如微信的内置浏览器),则用户的ip地址会发生变化,所以如果做session共享时不能寄希望于ip_hash

 

4)least_conn

  最少连接方式,把请求发给链接数最少的后端服务器。轮询是把请求平均分配给各个后端,使它们的负载大致相同。但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。upstream模块配置模板如下:

upstream [服务器组名称]{

  least_conn;

  server [IP地址]:[端口号] weight=2;

  server [IP地址]:[端口号];

  ....

}

  注意:此策略适合请求处理时间长短不一造成的服务器过载情况。

 

5)fair

  响应时间方式,按照服务器端的响应时间来分配请求,响应时间短的优先分配。upstream模块配置模板如下:

upstream [服务器组名称]{

  server [IP地址]:[端口号] weight=2;

  server [IP地址]:[端口号];

  ....

  fair;

}

  注意:需要安装第三方插件。

 

6)url_hash

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

upstream [服务器组名称]{

  hash $request_uri;

  server [IP地址]:[端口号] weight=2;

  server [IP地址]:[端口号];

  ....

}

  注意:1.需要安装第三方插件;2.uri,是i,不是小写的L。

如果后端的web服务机器上有本地缓存,且缓存内容不同,可以使用这种方式,因为可以提高缓存命中率,缩短访问时间

比如:供下载用的文件缓存到web服务器,如果缓存内容相同,例如 redis缓存页面内容,则使用url_hash带来的益外不大

 

参考案例(模板)

参考模板:

upstream apachephp  {

    server ip:8080;

}

server {

    listen 80;

    server_name        www.nowamagic.net;

    access_log           logs/quancha.access.log  main;

    error_log             logs/quancha.error.log;

    root                    html;

    index                   index.html index.htm index.php;

    location / {

        proxy_pass                 http://apachephp;

        proxy_redirect          off;

        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_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

        proxy_max_temp_file_size          0;

        proxy_connect_timeout          90;

        proxy_send_timeout            90;

        proxy_read_timeout             90;

        proxy_buffer_size                4k;

        proxy_buffers                  4 32k;

        proxy_busy_buffers_size          64k;

        proxy_temp_file_write_size         64k;

   }

}

说明:新建一个cancer.conf,加入以上内容(记得修改ip和域名为你的ip和域名)。修改nginx.conf,添加include cancer.conf 到http{}段, reload nginx就可以了。

 

参考案例(完整)

负载均衡,完整如下:

user www www;

worker_processes 8;

pid /usr/local/nginx/nginx.pid;

worker_rlimit_nofile 102400;

events{

use epoll;

worker_connections 102400;

}  

http{

  include       mime.types;  

  default_type  application/octet-stream;  

  fastcgi_intercept_errors on;  

  charset  utf-8;  

  server_names_hash_bucket_size 128;  

  client_header_buffer_size 4k;  

  large_client_header_buffers 4 32k;  

  client_max_body_size 300m;  

  sendfile on;  

  tcp_nopush     on;  

  keepalive_timeout 60;  

  tcp_nodelay on;  

  client_body_buffer_size  512k;  

  proxy_connect_timeout    5;  

  proxy_read_timeout       60;  

  proxy_send_timeout       5;  

  proxy_buffer_size        16k;  

  proxy_buffers            4 64k;  

  proxy_busy_buffers_size 128k;  

  proxy_temp_file_write_size 128k;  

  gzip on;  

  gzip_min_length  1k;  

  gzip_buffers     4 16k;  

  gzip_http_version 1.1;  

  gzip_comp_level 2;  

  gzip_types       text/plain application/x-javascript text/css application/xml;  

  gzip_vary on;  

 

###2012-12-19 change nginx logs  

log_format  main  '$http_x_forwarded_for - $remote_user [$time_local] "$request" ' 

              '$status $body_bytes_sent "$http_referer" ' 

              '"$http_user_agent"  $request_time $remote_addr';  

 

upstream web_app {  

server 127.0.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;  

server 127.0.0.1:8081 weight=1 max_fails=2 fail_timeout=30s;  

}  

 

###chinaapp.sinaapp.com  

server {  

    listen 80;  

    server_name  chinaapp.sinaapp.com;  

    index index.jsp index.html index.htm;  

    #发布目录/data/www  

    root  /data/www;  

    location / {  

           proxy_next_upstream http_502 http_504 error timeout invalid_header;  

           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_pass http://web_app;  

           expires      3d;  

    }

  }

}

 

参考案例(多集群)

user  nginx;  

location / {  

  root html;

  index index.html index.htm;

  if ($request_uri ~* \.html$){

    proxy_pass http://htmlservers;

  }

  if ($request_uri ~* \.php$){

    proxy_pass http://phpservers;

  }

  proxy_pass http://picservers;

}

upstream htmlservers {  //在http模块下,server模块平级处添加

  server 192.168.5.102:80;

  server 192.168.5.103:80;

}

upstream phpservers{

  server 192.168.5.102:80;

  server 192.168.5.103:80;

}

upstream picservers {

  server 192.168.5.102:80;

  server 192.168.5.103:80;

}

 

上一篇:Nginx基于TCP/UDP端口的四层负载均衡(stream模块)配置梳理


下一篇:poj 1273 Drainage Ditches (网络流 最大流)