Nginx设置负载均衡,及禁止访问个别目录地址

本次操作拓扑

TB

首先,在路由器上开启端口转发:

ZF

两台tomcat配置

web1

web2

注意,<Context path=”” docBase=”userdir” debug=”0″ reloadable=”true” /> 项添加于 <Host> … </Host> 之间:

[root@TEST2 tomcat]# vim conf/server.xml
...
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
        <Context path="" docBase="userdir" debug="0" reloadable="true" />
        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

访问查看:

webOK

OK!

Nginx配置

下载、安装:

[root@node1 ~]# wget http://nginx.org/download/nginx-1.9.13.tar.gz
[root@node1 ~]# tar zxf nginx-1.9.13.tar.gz -C /usr/local/src/
[root@node1 ~]# cd /usr/local/src/nginx-1.9.13/
[root@node1 nginx-1.9.13]# groupadd -g 222 www
[root@node1 nginx-1.9.13]# useradd -g www -u 222 -s /sbin/nologin -M www
[root@node1 nginx-1.9.13]# yum install -y gcc pcre-devel openssl-devel
[root@node1 nginx-1.9.13]# ./configure --prefix=/data/nginx --user=www --group=www --with-threads --with-http_ssl_module --with-stream --with-stream_ssl_module
[root@node1 nginx-1.9.13]# make -j `cat /proc/cpuinfo | grep processor | wc -l`;make install

编辑配置文件:

编辑主配置文件,开启gzip压缩访问功能:

[root@node1 nginx-1.9.13]# cd /data/nginx/
[root@node1 nginx]# vim conf/nginx.conf
# Nginx Main Configure.
user  www;
worker_processes  4;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    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;
    server_tokens  off;
    client_max_body_size 30m;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    gzip  on;
    gzip_min_length 1024;
    gzip_buffers 4 128k;
    gzip_http_version 1.0;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain  text/javascript application/x-javascript text/css  text/xml image/jpg  application/xml  image/jpeg image/gif im
age/png;
    gzip_vary on;
    gzip_disable        "Dalvik\.";

include vhosts/*.conf;

}

创建副配置文件,设置负载

[root@node1 nginx]# mkdir conf/vhosts
[root@node1 nginx]# vim conf/vhosts/userweb.conf
# Nginx Configure.
server {
        listen  80;
        access_log  logs/fmtxt_access.log;
        error_log   logs/fmtxt_error.log ;
    location / {
        proxy_pass http://userweb;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

upstream userweb {
        server 172.16.220.226:9090;
        server 172.16.220.227:9090;
}

upstream 负载均衡模块说明

upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。在上面的设定中,通过upstream指令指定了一个负载均衡器的名称userweb。这个名称可以任意指定,在需要用到的地方直接调用即可。

upstream 默认支持的负载均衡算法

  • 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。
  • ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。

upstream 支持的状态参数

在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:

  • down,表示当前的server暂时不参与负载均衡。
  • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
  • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
  • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

注,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

测试、启动服务

[root@node1 nginx]# ./sbin/nginx -t
nginx: the configuration file /data/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /data/nginx/conf/nginx.conf test is successful
[root@node1 nginx]# ./sbin/nginx 
[root@node1 nginx]# netstat -nlput | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      15478/nginx: master

进行外网访问:

access1

再次刷新:

access2

可以看到,由于是默认的轮循方式访问,所访问到的服务器是不一样的。

查看tomcat端日志:

accesslog1

accesslog2

可以看到显示的是负载服务器的IP地址,如何让它显示对端真实IP呢,很简单,上面我们已经设置了proxy_set_header X-Real-IP $remote_addr;条目,定义了个X-Real-IP变量,让tomcat记录日志时取这个变量记录的IP即可。

修改tomcat配置文件server.xml

[root@TEST2 tomcat]# vim conf/server.xml

更改org.apache.catalina.valves.AccessLogValve项,将样式中的%h换为%{X-Real-IP}i 即可

...
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%{X-Real-IP}i %l %u %t &quot;%r&quot; %s %b" />
...

两台都改过之后,重启服务即可:

[root@TEST2 tomcat]# ./bin/shutdown.sh 
Using CATALINA_BASE:   /home/tomcat
Using CATALINA_HOME:   /home/tomcat
Using CATALINA_TMPDIR: /home/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_67
Using CLASSPATH:       /home/tomcat/bin/bootstrap.jar:/home/tomcat/bin/tomcat-juli.jar
[root@TEST2 tomcat]# netstat -nlput | grep 9090
[root@TEST2 tomcat]# ./bin/startup.sh 
Using CATALINA_BASE:   /home/tomcat
Using CATALINA_HOME:   /home/tomcat
Using CATALINA_TMPDIR: /home/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_67
Using CLASSPATH:       /home/tomcat/bin/bootstrap.jar:/home/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@TEST2 tomcat]# netstat -nlput | grep 9090
tcp        0      0 :::9090                     :::*                        LISTEN      2164/java
[root@TEST3 tomcat]# ./bin/shutdown.sh 
Using CATALINA_BASE:   /home/tomcat
Using CATALINA_HOME:   /home/tomcat
Using CATALINA_TMPDIR: /home/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_67
Using CLASSPATH:       /home/tomcat/bin/bootstrap.jar:/home/tomcat/bin/tomcat-juli.jar
[root@TEST3 tomcat]# netstat -nlput | grep 9090
[root@TEST3 tomcat]# ./bin/startup.sh 
Using CATALINA_BASE:   /home/tomcat
Using CATALINA_HOME:   /home/tomcat
Using CATALINA_TMPDIR: /home/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_67
Using CLASSPATH:       /home/tomcat/bin/bootstrap.jar:/home/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@TEST3 tomcat]# netstat -nlput | grep 9090
tcp        0      0 :::9090                     :::*                        LISTEN      2563/java

然后重新刷新两篇访问,再看日志,已经记录为客户机真实IP。

logok1

logok2

我们还有个后端地址/admin,有时我们需要只允许个别地址访问,可以这样做,修改副配置文件,在server中加上location /admin/处理项,如下

[root@node1 nginx]# vim conf/vhosts/userweb.conf
# Nginx Configure.
server {
        listen  80;
        access_log  logs/fmtxt_access.log;
        error_log   logs/fmtxt_error.log ;
    location / {
        proxy_pass http://userweb;
        proxy_set_header X-Real-IP $remote_addr;
    }
    location /admin/ {
        allow 192.80.*.*;
        deny all;
        proxy_pass http://userweb;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

upstream userweb {
        server 172.16.220.226:9090;
        server 172.16.220.227:9090;
}

这样就只允许allow中的这个IP地址访问/admin/中的资源。注:*.*为隐藏的后两位。

修改好后重新加载配置:

[root@node1 nginx]# ./sbin/nginx -s reload

访问:

  • 使用授权IP地址访问正常

accessok1

  • 使用其它地址访问被拒

accessok2

分别查看3台机的日志:

Nginx:

endlog1

两台tomcat上日志:

endlog2

endlog3

均已OK,已经达到目的。

发表评论

error: Content is protected !!