tomcat集群负载均衡配置

  • Tomcat与Apache或Nginx连接和集群配置
  • 系统环境设置

    Tomcat发布器的安装

    JDK安装

    (1)先选择Download下面的tomcat版本(如tomcat 7.0) (2)再点击“Core”下面的“tar.gz”进行下载,如apache-tomcat-7.0.12.tar.gz (3)下载完成后上传到web服务器上的“/tools”目录下(自己建的目录)

    Tomcat安装

    Apache Proxy负载均衡

    Nginx负载均衡

    nginx安装

    nginx负载配置

    Tomcat与Apache或Nginx连接和集群配置

    Tomcat的连接方式

    Tomcat7所支持的本地连接:

    1. JK 1.2 .x
    2. mod_proxy (Apache HTTP Server 2.2默认包含)

    其他AJP连接器可能可以工作,但不再维护。

    Tomcat 与 Apache HTTP Server2.4连接

    HTTP连接

    从上面的说明可以看出,如果你只需要一个Tomcat,那就直接用就好了,不用和Apache HTTP Server连接。如果需要多个Tomcat集群,就是AJP连接。所以用HTTP连接Apache和Tomcat这种情况应该不多,简单说明一下怎么连接: 取消两个module的注释:

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_http_module modules/mod_proxy_http.so
    

    在httpd.conf文件中添加以下两行:

    ProxyPass /webappname http://ip:8080/webappname
    ProxyPassReverse /webappname http://ip:8080/webappname
    

    ip、端口号和webappname根据实际情况修改

    说明:上述写法可能有安全隐患。不要使用ProxyRequests启用代理,除非对代理做了权限控制。否则对你的网络和互联网都是很大的危险。默认ProxyRequests为off。

    参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy.html#access

    AJP连接

    AJP连接官方支持两种方式JK 1.2.x和mod_proxy。

    JK是老牌连接器,被广泛使用和验证,值得信任,但是配置比较复杂。

    mod_proxy是Apache2.2以后的默认设置,配置简单,但是因为比较新,所以没有经过大范围的验证。

    网上JK的文档比较多,这里我们介绍一下mod_proxy的写法。其实跟HTTP的方式一样,只是把http://修改为ajp://就可以了。

    取消两个module的注释

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
    

    在httpd.conf文件中添加以下行:

    ProxyPass /webappname ajp://ip:8009/webappname
    

    ip、端口号和webappname根据实际情况修改

    AJP连接通常不需要设置ProxyPassReverse。

    参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy_ajp.html

    Apache HTTP Server2.4集群配置

    如文章开始所述,Apache Http Server和Tomcat集群要用AJP方式连接

    同样集群可以用JK和mod_proxy两种方式,这里介绍mod_proxy的方式:

    取消五个module的注释

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
    LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
    LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
    LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
    

    根据负载均衡调度策略的不同,取消如下module的注释

    LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
    LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
    LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
    

    当一个请求被代理到某个节点,接下来同一个用户的请求都将被代理到相同的节点。很多均衡器通过一张记录客户端ip和节点的关系表来实现这个特性。这种方式对客户端和节点都是透明的,但是存在一些问题:如果客户端藏在某些代理之后将导致负载分布不均,当客户端使用动态IP地址,并在请求间变更,将失去粘性,关系表溢出将导致错误等问题。

    mod_proxy_balancer通过两种方式实现粘性:cookies和URL encoding。cookie可以被Apache服务器和节点使用,URL encoding通常在节点中使用。

    下面的例子使用mod_headers提供负载均衡粘性,即使节点服务器没有设置合适的session cookie。

    Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
    <Proxy balancer://mycluster>
     ......
    </Proxy>
    ProxyPass /test balancer://mycluster
    

    env变量有6种,参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html#environment

    以下配置同时支持cookies和URL encoding

    ProxyPass /test balacer://mycluuster stickysession=JSESSIONID|jsessionid scolonpathdelim=On
    <Proxy balancer://mycluster>
        BlancerMember http://192.168.1.50:80 route=node1
        BlancerMember http://192.168.1.51:80 route=node2
    </Proxy>
    

    将集群的日志写到Apache服务器目录下的logs/balance_log文件中。

    参考:http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html#stickyness_troubleshooting

    需要mod_status。管理页面可以动态更新集群成员,修改平衡器的属性和特定成员或使之离线。

    <Location /balancer-manager>
        SetHandler balancer-manager
        Require ip 192.168
    </Location>
    

    你可以通过http://your.server.name/balancer-manager访问管理页面。

    注意,只有balancers在<Location ...>之外定义,才能使用管理页面。

    Tomcat 与 Nginx连接

    HTTP连接

    server {                     #添加一个站点
        listen       82;         #设置端口
        server_name  localhost;  #站点名称/域名
    
        location / {             #设置路径
            proxy_pass http://ip:8080;  #http代理,指向tomcat http地址
        }
    }
    

    在nginx.conf文件中添加一个server{},listen设置端口,server_name设置域名,location设置目录。

    proxy_pass是http代理,指向tomcat地址。

    修改后conf后,nginx -s reload就可以热更新了,很方便。

    AJP连接

    关于AJP连接,有一种说法是Nginx采用连接池,所以HTTP方式的连接不比AJP方式差。

    有人的测试结果是Nginx通过HTTP连接Tomcat 性能略强于Apache通过AJP连接Tomcat。

    参见:http://nginx.2469901.n2.nabble.com/AJP-td7582236.html

    Nginx本身并不支持AJP连接,但有人写了一个nginx_ajp_module来支持ajp。由于是第三方控件,所以请在充分测试后使用。

    先到nginx安装文件的目录下,打ajp补丁,重新配置configure,编辑,安装。

    其他配置详情参考:https://github.com/yaoweibin/nginx_ajp_module

    Nginx集群配置

    HTTP

    upstream tomcat_http {       #用upstream定义一组服务器
        #ip_hash通过记录客户端ip实现粘性session。有一个第三方的module可以用cookie实现粘性:https://code.google.com/p/nginx-sticky-module/
        ip_hash; 
        #通过server定义多个服务器
        #weight是权重,默认为1。
        #max_fails和fail_timeout配合使用,在fail_timeout时间内通信失败达到max_fails的次数后,此服务器在fail_timeout时间内被认为不可用。
        server 192.168.50.65:8090 weight=2;
        server 192.168.50.65:8091 max_fails=3 fail_timeout=30s;
    
        #keepalive为连接开启缓存,并设置缓存连接的最大数量。
        keepalive 10;
     }
    
     server {
        listen       82;
        server_name  localhost;
    
        location / {
            #将proxy_pass后的服务器地址,变为upstream的名字
            proxy_pass http://tomcat_http;
        }
    }
    

    更多参数说明参考:http://nginx.org/en/docs/http/ngx_http_upstream_module.html

    AJP

    upstream tomcat_ajp {    # upstream定义一组服务器
        #srun_id同Tomcat配置中Engine的jvmRoute。
        server 192.168.50.65:8019 srun_id=tomcat7_a weight=2;
        server 192.168.50.65:8029 srun_id=tomcat7_b;
    
        #用cookie方式实现粘性session
        jvm_route $cookie_JSESSIONID reverse;
        keepalive 10;
    }
    
    server {
        listen       82;
        server_name  localhost;
    
        location / {
            ajp_keep_conn on;
            ajp_pass tomcat_ajp;  #指定连接到哪个upstream上
        }
    }