Apache+Tomcat集群实现反向代理负载均衡

一. Apache+Tomcat集群实现反向代理的负载均衡的原理:
Apache作为调度器,转发HTTP请求。然后等待实际服务器的HTTP响应,并转发给用户。
Tomcat集群作为实际的服务器,处理HTTP请求。

二. 需要安装的程序:
1. Apache2.2.4
2. 4个Tomcat7(注意修改server.xml)

三. 修改配置文件:
我这里的端口设置如下,请先确保这些端口没有被使用,也可以自己修改:

Apache:8090
Tomcat1:服务器端口:8004
	 HTTP端口:8080
	 AJP端口:8009
Tomcat2:服务器端口:8005
	 HTTP端口:8081
	 AJP端口:8010

1. Apache24\conf\httpd.conf
① Apache2以后已经集成了很多Module,因此只要把注释去掉就可以了。
我这里主要放开了下面这些Module:
#LoadModule access_compat_module modules/mod_access_compat.so
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule allowmethods_module modules/mod_allowmethods.so
LoadModule asis_module modules/mod_asis.so
LoadModule auth_basic_module modules/mod_auth_basic.so
#LoadModule auth_digest_module modules/mod_auth_digest.so
#LoadModule auth_form_module modules/mod_auth_form.so
#LoadModule authn_anon_module modules/mod_authn_anon.so
LoadModule authn_core_module modules/mod_authn_core.so
#LoadModule authn_dbd_module modules/mod_authn_dbd.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_file_module modules/mod_authn_file.so
#LoadModule authn_socache_module modules/mod_authn_socache.so
#LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule authz_core_module modules/mod_authz_core.so
#LoadModule authz_dbd_module modules/mod_authz_dbd.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
#LoadModule authz_owner_module modules/mod_authz_owner.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule buffer_module modules/mod_buffer.so
#LoadModule cache_module modules/mod_cache.so
#LoadModule cache_disk_module modules/mod_cache_disk.so
#LoadModule cache_socache_module modules/mod_cache_socache.so
#LoadModule cern_meta_module modules/mod_cern_meta.so
LoadModule cgi_module modules/mod_cgi.so
#LoadModule charset_lite_module modules/mod_charset_lite.so
#LoadModule data_module modules/mod_data.so
#LoadModule dav_module modules/mod_dav.so
#LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule dav_lock_module modules/mod_dav_lock.so
#LoadModule dbd_module modules/mod_dbd.so
#LoadModule deflate_module modules/mod_deflate.so
LoadModule dir_module modules/mod_dir.so
#LoadModule dumpio_module modules/mod_dumpio.so
LoadModule env_module modules/mod_env.so
#LoadModule expires_module modules/mod_expires.so
#LoadModule ext_filter_module modules/mod_ext_filter.so
#LoadModule file_cache_module modules/mod_file_cache.so
#LoadModule filter_module modules/mod_filter.so
#LoadModule headers_module modules/mod_headers.so
#LoadModule heartbeat_module modules/mod_heartbeat.so
#LoadModule heartmonitor_module modules/mod_heartmonitor.so
#LoadModule http2_module modules/mod_http2.so
#LoadModule ident_module modules/mod_ident.so
#LoadModule imagemap_module modules/mod_imagemap.so
LoadModule include_module modules/mod_include.so
LoadModule info_module modules/mod_info.so
LoadModule isapi_module modules/mod_isapi.so
#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so
#LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so
#LoadModule ldap_module modules/mod_ldap.so
#LoadModule logio_module modules/mod_logio.so
LoadModule log_config_module modules/mod_log_config.so
#LoadModule log_debug_module modules/mod_log_debug.so
#LoadModule log_forensic_module modules/mod_log_forensic.so
#LoadModule lua_module modules/mod_lua.so
#LoadModule macro_module modules/mod_macro.so
LoadModule mime_module modules/mod_mime.so
#LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule negotiation_module modules/mod_negotiation.so
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 proxy_connect_module modules/mod_proxy_connect.so
#LoadModule proxy_express_module modules/mod_proxy_express.so
#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_html_module modules/mod_proxy_html.so
LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_http2_module modules/mod_proxy_http2.so
#LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
#LoadModule ratelimit_module modules/mod_ratelimit.so
#LoadModule reflector_module modules/mod_reflector.so
#LoadModule remoteip_module modules/mod_remoteip.so
#LoadModule request_module modules/mod_request.so
#LoadModule reqtimeout_module modules/mod_reqtimeout.so
#LoadModule rewrite_module modules/mod_rewrite.so
#LoadModule sed_module modules/mod_sed.so
#LoadModule session_module modules/mod_session.so
#LoadModule session_cookie_module modules/mod_session_cookie.so
#LoadModule session_crypto_module modules/mod_session_crypto.so
#LoadModule session_dbd_module modules/mod_session_dbd.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule slotmem_plain_module modules/mod_slotmem_plain.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
#LoadModule socache_dbm_module modules/mod_socache_dbm.so
#LoadModule socache_memcache_module modules/mod_socache_memcache.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
#LoadModule speling_module modules/mod_speling.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule status_module modules/mod_status.so
#LoadModule substitute_module modules/mod_substitute.so
#LoadModule unique_id_module modules/mod_unique_id.so
#LoadModule userdir_module modules/mod_userdir.so
#LoadModule usertrack_module modules/mod_usertrack.so
#LoadModule version_module modules/mod_version.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
#LoadModule watchdog_module modules/mod_watchdog.so
#LoadModule xml2enc_module modules/mod_xml2enc.so

② 要进行虚拟主机的设置,需要放开下面的注释:
# Virtual hosts
Include conf/extra/httpd-vhosts.conf

2. Apache24\conf\extra\httpd-vhosts.conf
在最下面加入虚拟机配置(我Apache的端口设为8090):
#虚拟机配置,负载均衡配置
<VirtualHost *:8090>
    ServerAdmin sun@locahost
    ServerName localhost
    ServerAlias localhost
    ProxyPass / balancer://cluster/ stickysession=JSESSIONID|jsessionid nofailover=On
    ProxyPassReverse / balancer://cluster/
</VirtualHost> 

在最下面加入代理服务器的配置:
#The ProxyRequests directive should usually be set off when using ProxyPass.
ProxyRequests Off
<proxy balancer://cluster>
    BalancerMember ajp://localhost:8009 loadfactor=1 route=jvm1  smax=5 max=20 ttl=120 retry=300 timeout=15
    BalancerMember ajp://localhost:8010 loadfactor=1 route=jvm2  smax=5 max=20 ttl=120 retry=300 timeout=15
    BalancerMember ajp://192.168.3.100:9009 loadfactor=1 route=jvm3  smax=5 max=20 ttl=120 retry=300 timeout=15
    ProxySet lbmethod=byrequests
#lbmethod=byrequests 按照请求次数均衡(默认) 
#lbmethod=bytraffic 按照流量均衡 
#lbmethod=bybusyness 按照繁忙程度均衡(总是分配给活跃请求数最少的服务器)
</proxy>

这里有几点需要注意:
① 代理服务器分发请求给各服务器的方法设置lbmethod有3种,需要去掉httpd.conf中对应Module的注释:
#LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
#LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so

② 下面这两个就是对应的Tomcat服务器

    BalancerMember ajp://localhost:8009 loadfactor=1 route=jvm1  smax=5 max=20 ttl=120 retry=300 timeout=15
    BalancerMember ajp://localhost:8010 loadfactor=1 route=jvm2  smax=5 max=20 ttl=120 retry=300 timeout=15
可以看出,他们Apache用了AJP协议与Tomcat进行通信,因此localhost后面8009和8010也必须是Tomcat中AJP协议的端口号,而不是HTTP协议的端口号8080和8081。
另外,route=jvm1和route=jvm2在Tomcat中也有设置对应,后面会说明。

③ 下面这个就有点特殊了
BalancerMember ajp://192.168.3.100:9009 loadfactor=1 route=jvm3  smax=5 max=20 ttl=120 retry=300 timeout=15
我这里试了一下非本机的服务器192.168.3.100
设置没问题,直接打开该服务器上的测试页面也没问题,可是从Apache就是跳不到。
后来想了一下,可能是由于这个服务器的网关与本机不一样,也就是说不是在一个局域网里面。
本机:


192.168.3.100:


3. Apache的启动

3.1. httpd.conf中,修改Apache的路径:

Define SRVROOT "D:\Apache24"
ServerRoot "${SRVROOT}"
我的Apache的安装路径为:D:\Apache24

端口设置:
Listen 8090

服务器名设置:
ServerName localhost:8090

3.2. 在cmd里面,启动Apache服务:
① 移动到D:\Apache24\bin目录下,执行 httpd -k install

Apache2.4服务被添加到windows服务里面了。

② 执行 net start Apache2.4  ,启动Apache2.4服务


③ 删除服务用 sc delete Apache2.4
 

④ 如果有其他错误,可以去 Apache/logs/error.log 里面找

4. TomcatX\conf\server.xml
下面以Tomcat1为例:
① 服务器端口设置为8004:
<Server port="8004" shutdown="SHUTDOWN">

② HTTP端口设置为8080:

<Connector port="8080" protocol="HTTP/1.1"

③ AJP端口设置为8009:
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

④ AJP协议的jvmRoute设置:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
这里的jvm1与Apache的jvmRoute对应。

⑤ 在④的后面插入下面这段:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"  channelSendOptions="6"> 
<Manager className="org.apache.catalina.ha.session.BackupManager" 
expireSessionsOnShutdown="false" 
notifyListenersOnReplication="true" 
mapSendOptions="6"/> 
<!-- 
<Manager className="org.apache.catalina.ha.session.DeltaManager" 
expireSessionsOnShutdown="false" 
notifyListenersOnReplication="true"/> 
--> 

                  <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>

<Channel className="org.apache.catalina.tribes.group.GroupChannel"> 
<Membership className="org.apache.catalina.tribes.membership.McastService" 
address="228.0.0.4" 
port="45564" 
frequency="500" 
dropTime="3000"/> 
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" 
address="auto" 
port="5001" 
selectorTimeout="100" 
maxThreads="6"/> 
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> 
<Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> 
</Sender> 
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> 
<Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> 
<Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/> 
</Channel> 
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve" 
filter=".*\.gif;.*\.js;.*\.jpg;.*\.png;.*\.htm;.*\.html;.*\.css;.*\.txt;"/> 
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>
<Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" 
tempDir="/tmp/war-temp/" 
deployDir="/tmp/war-deploy/" 
watchDir="/tmp/war-listen/" 
watchEnabled="false"/> 
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> 
</Cluster>

另外,有人说AJP协议端口的redirectPort和Receiver的port也要设为各Tomcat唯一,但是我没有设成唯一也没问题。

四. 测试用JSP和配置:
1. 测试用JSP

建两个同名的testCluster.jsp,分别放在Tomcat1和Tomcat2的Tomcat/webapps/ROOT下,内容稍有不同。
第一个:

<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster Test</title></head>
<body>
<%
  //HttpSession session = request.getSession(true);
  System.out.println(session.getId());
  out.println("<br> SESSION ID:" + session.getId()+"<br>");  
  // 如果有新的请求,则添加session属性
  String name = request.getParameter("name");
  if (name != null && name.length() > 0) {
     String value = request.getParameter("value");
     session.setAttribute(name, value);
  }  
    out.print("<b>Session List:</b>");  
    Enumeration<String> names = session.getAttributeNames();
    while (names.hasMoreElements()) {
        String sname = names.nextElement(); 
        String value = session.getAttribute(sname).toString();
        out.println( sname + " = " + value+"<br>");
        System.out.println( sname + " = " + value);
   }
%>
  <form action="testCluster.jsp" method="post">
    名称:<input type=text size=20 name="name">
     <br>
    值:<input type=text size=20 name="value">
     <br>
    <input type=submit value="提交">
   </form>

   <b>负载均衡测试:此为:Tomcat1上的文件,<font color=red>111111</font><b>
</body>
</html>

第二个:
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster Test</title></head>
<body>
<%
  //HttpSession session = request.getSession(true);
  System.out.println(session.getId());
  out.println("<br> SESSION ID:" + session.getId()+"<br>");  
  // 如果有新的请求,则添加session属性
  String name = request.getParameter("name");
  if (name != null && name.length() > 0) {
     String value = request.getParameter("value");
     session.setAttribute(name, value);
  }  
    out.print("<b>Session List:</b>");  
    Enumeration<String> names = session.getAttributeNames();
    while (names.hasMoreElements()) {
        String sname = names.nextElement(); 
        String value = session.getAttribute(sname).toString();
        out.println( sname + " = " + value+"<br>");
        System.out.println( sname + " = " + value);
   }
%>
  <form action="testCluster.jsp" method="post">
    名称:<input type=text size=20 name="name">
     <br>
    值:<input type=text size=20 name="value">
     <br>
    <input type=submit value="提交">
   </form>

   <b>负载均衡测试:此为:Tomcat2上的文件,<font color=red>222222</font><b>
</body>
</html>

接下来就可以测试了:
用第一个浏览器打开http://localhost:8090/testCluster.jsp
(8090是Apache,它下面没有testCluster.jsp)
显示结果:

说明Apache把请求转给了Tomcat1。

用第二个浏览器打开http://localhost:8090/testCluster.jsp
显示结果:

说明Apache把请求转给了Tomcat2。

2. 实现Session共享,需要修改的配置文件:

在1里面按提交以后,Session会改变,jvm也会变,说明跳转到其他Tomcat以后,Session并没有保存下来。
要实现Session共享,需要在每个Tomcat/webapps/ROOT/WEB-INF/web.xml的最后插入<distributable /> :

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  version="3.0"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
<distributable /> 
</web-app>

测试:
在上面第二个浏览器中输入值后继续提交,可以看到jvm1和jvm2虽然在切换,但是SessionID一直是 8AC1E2DAA730CB20384FB337D1762244


------------------------------------------------------------------------------

所有修改完的配置文件和测试页面在这里下载:
http://download.youkuaiyun.com/detail/sunroyi666/9605862

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值