本次应用的目的是拿nginx做服务器的负载均衡,而且提供的服务已用docker进行部署,该docker提供访问的端口有两个,分别对应不同的服务。因此首先需要查看docker映射的端口,然后通过修改upsteam,location,proxy三个模块达到目的。

1.查看docker服务映射的端口

netstat -ltunp #查看端口

centos7 docker 查看端口 docker查看服务端口_centos7 docker 查看端口


如上图所示,本机的docker服务端口是19090,18080,18081,10022。我们再使用==docker ps==命令查看已经启动的容器情况,得到下图。

centos7 docker 查看端口 docker查看服务端口_负载均衡_02


在port项中可以看到,本机的19090,18080,18081,10022端口分别被映射到docker容器中的9090,8080,8081,22端口。此时访问本机中的映射端口即可访问容器内 web 应用相应提供的界面。

2.定位到nginx的配置文件下

cd usr/local/nginx/conf/

其中的nginx.conf文件存放着nginx服务器的基础配置,默认的配置。如是新手,可以使用cat命令查看一下默认的配置,里面有一些配置的样例注释。而且,新手最好使用cp命令将原始配置文件进行备份。

3.负载均衡配置基本知识

upstream 定义负载节点池,location 模块 进行URL匹配,proxy模块 发送请求给upstream定义的节点池。

upstream模块
upstream块定义了一个上游服务器的集群,便于反向代理中的proxy_pass使用。
nginx默认支持四种调度算法,还有两种可以通过下载扩展包来使用:

  • 轮询(rr),每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器故障,故障系统自动清除,使用户访问不受影响。
  • 轮询权值(weight),weight值越大,分配到的访问几率越高,主要用于后端每个服务器性能不均的情况。
  • ip_hash,每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器,主要解决动态网站session共享的问题。
  • least_conn 最少链接数,那个机器连接数少就分发。
  • url_hash,按照访问的URL的hash结果来分配请求,是每个URL定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率,nginx本身不支持,如果想使用需要安装nginx的hash软件包。
  • fair,这个算法可以依据页面大小和加载时间长短智能的进行负载均衡,也就是根据后端服务器的响应时间来分配请求,相应时间短的优先分配,默认不支持,如果想使用需要安装upstream_fail模块。

server配置项指定后端服务器的名字,这个名字可以是域名、IP地址端口,UNIX句柄等,同时还可以设定每个后端服务器在负载均衡调度中的状态。
location模块
location作用:基于一个指令设置URI。
其基本语法是:
location [=|~|~*|^~|@] pattern { … }
[=|~|~*|^~|@] 被称作 location modifier ,这会定义 Nginx 如何去匹配其后的 pattern ,以及该 pattern 的最基本的属性(简单字符串或正则表达式)

  • 精确匹配,如果找到匹配=号的内容,立即停止搜索,并立即处理请求(优先级最高)
  • ~ 区分大小写
  • ~* 不区分大小写
  • *~ 只匹配字符串,不匹配正则表达式
  • @ 指定一个命名的location,一般用于内部重定义请求

proxy模块
- proxy_pass 指令,可以将请求转发到另一台服务器。
- proxy_set_header 指令,当后端Web服务器上也配置有多个虚拟主机时,需要用该Header来区分反向代理哪个主机名。
- proxy_set_header X-Forwarded-For 指令,如果后端Web服务器上的程序需要获取用户IP,从该Header头获取。

log配置
nginx日志主要分为两种,访问日志access.log和错误日志error.log
这两个日志所在的路径一般在usr/local/nginx中。
其基本语法为:
erro/access_log /path/file level
日志级别为:
debug < info < notice < warn < error < crit < alert < emerg < stderr

当传入的level级别小于或者等于log参数中的日志级别,就会输出日志内容,否则这条日志就会被忽略。
nginx日志配置一般使用下面三个参数:

  • error/access_log: 定义日志的路径及格式。
  • log_format: 定义日志的模板。
  • open_log_file_cache: 定义日志文件缓存。

4.根据应用要求修改conf文件

目前在两台服务器上分别布置了docker服务,每个docker提供了两个服务,一个是http://localhost:18080/, 访问这个页面可以进行A任务的处理,一个是http://localhost:19090/, 访问这个页面可以获得B任务的处理。于是我们可以用两个upstream块分别代表两个端口的服务,再进行相应的proxy_pass配置。

配置代码如下:

upstream taskB_servers{
        server XXX.XX.X.111:19090 weight=1; #1号服务器B任务端口
        server XXX.XX.X.222:19090 weight=1; #2号服务器B任务端口
    }

    upstream taskA_servers{
        server XXX.XX.X.111:18080 weight=1; #1号服务器A任务端口
        server XXX.XX.X.222:18080 weight=1; #2号服务器A任务端口
    }

    server {
        listen       8080;
        server_name  example;

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

        }

        #处理任务A请求
        location /taskA { 
            proxy_pass http://taskA_servers/;  #后面的'/'一定要有
        }
        #处理任务B请求
        location /taskB {
            proxy_pass http://taskB_servers;
        }

        # 将服务错误页面重定向到静态页面50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

配置好后,我们通过访问nginx所在的服务器ip对应的地址便可以访问所需的服务,如,目前nginx所在的服务器IP是120.32.1.123,那么访问A服务的地址如下:
http://120.32.1.123:8080/taskA

接下来进行日志配置,进行访问IP,上游服务器地址,响应时间等消息的记录,配置如下:

#定义返回日志格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
            '$status $body_bytes_sent "$http_referer" '
            '"$http_user_agent" "$http_x_forwarded_for"'
            '"request_time" "$request_time"'
            '"upstream_addr" "$upstream_addr"'
            '"upstream_response_time" "$upstream_response_time"';

    access_log  /usr/local/nginx/logs/access.log  main;
    error_log  /usr/local/nginx/logs/error.log;

参考资料

  1. http://nginx.org/en/docs/ngx_core_module.html