本文来源于:https://blog.youkuaiyun.com/sunroyi666/article/details/52237667 ,如有不当之处,请告知删除。
一. 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
另外,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
设置没问题,直接打开该服务器上的测试页面也没问题,可是从Apache就是跳不到。
后来想了一下,可能是由于这个服务器的网关与本机不一样,也就是说不是在一个局域网里面。
本机:
192.168.3.100:
3. Apache的启动
3.1. httpd.conf中,修改Apache的路径:
- Define SRVROOT "D:\Apache24"
- ServerRoot "${SRVROOT}"
端口设置:
- 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 里面找
下面以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">
⑤ 在④的后面插入下面这段:
- <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