天天看点

Apache反向代理Tomcat集群,以及session复制

一、Apache反向代理介绍

Apache可以通过mod_jk和mod_proxy模块跟Tomcat整合,mod_proxy只能在apache 2.2.x系列的版本才能直接提供,它可以提供更丰富的功能和安全性;而对于apache1.3.x和2.0.x来说mod_jk才更合适,这俩种方式都可以使用tomcat内置的ajp和http类型的连接器来实现apache代理tomcat集群。

二、实验的环境:

192.168.30.116 OS:Centos6.4 x86_64  apache.luojianlong.com

192.168.30.117 OS:Centos6.4 x86_64  TomcatA.luojianlong.com

192.168.30.119 OS:Centos6.4 x86_64  TomcatB.luojianlong.com

Apache versrion: httpd-2.4.6

Tomcat version: apache-tomcat-7.0.53

拓扑图如下:

<a href="http://s3.51cto.com/wyfs02/M01/23/AF/wKiom1M-ZE2Qtr1lAAD2vuIjNuQ819.jpg" target="_blank"></a>

三、使用apache的mod_jk来实现反向代理

首先在apache.luojianlong.com上编译安装apache

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

<code># 安装apr和apr-util</code>

<code>[root@apache ~]</code><code># tar xvf apr-1.4.6.tar.bz2</code>

<code>[root@apache ~]</code><code># cd apr-1.4.6</code>

<code>[root@apache apr-1.4.6]</code><code># ./configure --prefix=/usr/local/apr --disable-ipv6</code>

<code># 如果报错rm: cannot remove `libtoolT': No such file or directory</code>

<code># 直接打开 configure,把 $RM “$cfgfile” 那行删除掉,重新再运行</code>

<code># ./configure 就可以了</code>

<code>[root@apache apr-1.4.6]</code><code># make &amp;&amp; make install</code>

<code>[root@apache ~]</code><code># tar xvf apr-util-1.5.2.tar.bz2</code>

<code>[root@apache ~]</code><code># cd apr-util-1.5.2</code>

<code>[root@apache apr-util-1.5.2]</code><code># ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr</code>

<code>[root@apache apr-util-1.5.2]</code><code># make &amp;&amp; make install</code>

<code># 安装apache</code>

<code>[root@apache ~]</code><code># tar xvf httpd-2.4.6.tar.bz2</code>

<code>[root@apache ~]</code><code># cd httpd-2.4.6</code>

<code>[root@apache httpd-2.4.6]</code><code># ./configure --prefix=/usr/local/apache \</code>

<code>&gt; --sysconfdir=</code><code>/etc/httpd</code> <code>\</code>

<code>&gt; --</code><code>enable</code><code>-so \</code>

<code>&gt; --</code><code>enable</code><code>-ssl \</code>

<code>&gt; --</code><code>enable</code><code>-cgi \</code>

<code>&gt; --</code><code>enable</code><code>-rewrite \</code>

<code>&gt; --with-zlib \</code>

<code>&gt; --with-pcre \</code>

<code>&gt; --with-apr=</code><code>/usr/local/apr</code> <code>\</code>

<code>&gt; --with-apr-util=</code><code>/usr/local/apr-util</code> <code>\</code>

<code>&gt; --</code><code>enable</code><code>-mpms-shared=all \</code>

<code>&gt; --with-mpm=event \</code>

<code>&gt; --</code><code>enable</code><code>-proxy \</code>

<code>&gt; --</code><code>enable</code><code>-proxy-http \</code>

<code>&gt; --</code><code>enable</code><code>-proxy-ajp \</code>

<code>&gt; --</code><code>enable</code><code>-proxy-balancer \</code>

<code>&gt; --</code><code>enable</code><code>-lbmethod-heartbeat \</code>

<code>&gt; --</code><code>enable</code><code>-heartbeat \</code>

<code>&gt; --</code><code>enable</code><code>-slotmem-shm \</code>

<code>&gt; --</code><code>enable</code><code>-slotmem-plain \</code>

<code>&gt; --</code><code>enable</code><code>-watchdog</code>

<code>[root@apache httpd-2.4.6]</code><code># make &amp;&amp; make install</code>

<code>[root@apache ~]</code><code># vi /etc/httpd/httpd.conf</code>

<code># 编辑配置文件取消下面的这一行的注释</code>

<code>LoadModule slotmem_shm_module modules</code><code>/mod_slotmem_shm</code><code>.so</code>

<code>[root@apache ~]</code><code># /usr/local/apache/bin/apachectl start</code>

<code>[root@apache ~]</code><code># ps aux | grep apache</code>

<code>root     18345  0.0  0.0 105796  2336 ?        Ss   16:59   0:00 </code><code>/usr/local/apache/bin/httpd</code> <code>-k start</code>

<code>daemon   18346  0.2  0.1 450056  4384 ?        Sl   16:59   0:00 </code><code>/usr/local/apache/bin/httpd</code> <code>-k start</code>

<code>daemon   18347  0.0  0.1 450056  4384 ?        Sl   16:59   0:00 </code><code>/usr/local/apache/bin/httpd</code> <code>-k start</code>

<code>daemon   18348  0.2  0.1 450056  4392 ?        Sl   16:59   0:00 </code><code>/usr/local/apache/bin/httpd</code> <code>-k start</code>

在2台tomcat上面安装tomcat

<code># 首先安装配置jdk环境</code>

<code>[root@TomcatA ~]</code><code># tar zxvf jdk-7u25-linux-x64.gz -C /usr/local/</code>

<code>[root@TomcatA </code><code>local</code><code>]</code><code># ln -s jdk1.7.0_25 jdk</code>

<code>[root@TomcatA ~]</code><code># vi /etc/profile.d/jdk.sh</code>

<code>export</code> <code>JAVA_HOME=</code><code>/usr/local/jdk</code>

<code>export</code> <code>CLASSPATH=$CLASSPATH:$JAVA_HOME</code><code>/lib</code><code>:$JAVA_HOME</code><code>/jre/lib</code>

<code>export</code> <code>PATH=</code><code>/usr/local/jdk/bin</code><code>:$PATH</code>

<code>[root@TomcatA ~]</code><code># . /etc/profile.d/jdk.sh</code>

<code>[root@TomcatA ~]</code><code># java -version</code>

<code>java version </code><code>"1.7.0_25"</code>

<code>Java(TM) SE Runtime Environment (build 1.7.0_25-b15)</code>

<code>Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)</code>

<code># 安装配置tomcat</code>

<code>[root@TomcatA ~]</code><code># tar zxvf apache-tomcat-7.0.53.tar.gz -C /usr/local/</code>

<code>[root@TomcatA ~]</code><code># cd /usr/local/</code>

<code>[root@TomcatA </code><code>local</code><code>]</code><code># ln -s apache-tomcat-7.0.53 tomcat</code>

<code>[root@TomcatA ~]</code><code># vi /etc/profile.d/tomcat.sh</code>

<code>export</code> <code>CATALINA_HOME=</code><code>/usr/local/tomcat</code>

<code>export</code> <code>PATH=</code><code>/usr/local/tomcat/bin</code><code>:$PATH</code>

<code>[root@TomcatA ~]</code><code># . /etc/profile.d/tomcat.sh</code>

<code>[root@TomcatA ~]</code><code># catalina.sh start</code>

<code>Using CATALINA_BASE:   </code><code>/usr/local/tomcat</code>

<code>Using CATALINA_HOME:   </code><code>/usr/local/tomcat</code>

<code>Using CATALINA_TMPDIR: </code><code>/usr/local/tomcat/temp</code>

<code>Using JRE_HOME:        </code><code>/usr/local/jdk</code>

<code>Using CLASSPATH:       </code><code>/usr/local/tomcat/bin/bootstrap</code><code>.jar:</code><code>/usr/local/tomcat/bin/tomcat-juli</code><code>.jar</code>

<code>Tomcat started.</code>

<code>[root@TomcatA ~]</code><code># jps</code>

<code>18724 Bootstrap</code>

<code>18744 Jps</code>

<code>[root@TomcatA ~]</code><code># ss -antpl | grep :8080</code>

<code>LISTEN     0      100                      :::8080                    :::*      </code><code>users</code><code>:((</code><code>"java"</code><code>,18724,42))</code>

<code>[root@TomcatA ~]</code><code># scp -pr jdk-7u25-linux-x64.gz apache-tomcat-7.0.53.tar.gz [email protected]:/root/</code>

<code># TomcatB上同样上面的步骤安装jdk和tomcat</code>

访问都正常

<code>[root@TomcatA ~]</code><code># curl -I http://192.168.30.117:8080</code>

<code>HTTP</code><code>/1</code><code>.1 200 OK</code>

<code>Server: Apache-Coyote</code><code>/1</code><code>.1</code>

<code>Content-Type: text</code><code>/html</code><code>;charset=ISO-8859-1</code>

<code>Transfer-Encoding: chunked</code>

<code>Date: Fri, 04 Apr 2014 09:35:50 GMT</code>

<code>[root@TomcatA ~]</code><code># curl -I http://192.168.30.119:8080</code>

<code>Date: Fri, 04 Apr 2014 09:36:45 GMT</code>

配置基于mod_jk的负载均衡

修改Tomcat配置文件,添加Host标签,创建项目加载的类库文件夹,并为每一个Tomcat实例的引擎添加jvmRoute参数,并通过其为当前引擎设置全局惟一标识符,需要注意的是,每一个实例的jvmRoute的值均不能相同。

<code># 为每一个Tomcat实例的引擎添加jvmRoute参数,并通过其为当前引擎设置全局惟一标识符,需要注意的是,每一个实例的jvmRoute的值均不能相同。</code>

<code>[root@TomcatA ~]</code><code># vi /usr/local/tomcat/conf/server.xml</code>

<code># 添加以下内容</code>

<code>  </code><code>&lt;Engine name=</code><code>"Catalina"</code> <code>defaultHost=</code><code>"192.168.30.117"</code> <code>jvmRoute=</code><code>"TomcatA"</code><code>&gt;</code>

<code>  </code><code>&lt;Host name=</code><code>"192.168.30.117"</code>  <code>appBase=</code><code>"/tomcat/web"</code>

<code>            </code><code>unpackWARs=</code><code>"true"</code> <code>autoDeploy=</code><code>"true"</code><code>&gt;</code>

<code>  </code><code>&lt;Context path=</code><code>""</code> <code>docBase=</code><code>"/tomcat/web"</code><code>/&gt;</code>

<code>       </code><code>&lt;Valve className=</code><code>"org.apache.catalina.valves.AccessLogValve"</code> <code>directory=</code><code>"logs"</code>

<code>               </code><code>prefix=</code><code>"www_access_log."</code> <code>suffix=</code><code>".txt"</code>

<code>               </code><code>pattern=</code><code>"%h %l %u %t &amp;quot;%r&amp;quot; %s %b"</code> <code>/&gt;</code>

<code>      </code><code>&lt;</code><code>/Host</code><code>&gt;</code>

<code>[root@TomcatA ~]</code><code># mkdir /tomcat/web/WEB-INF/classes -p</code>

<code>[root@TomcatA ~]</code><code># mkdir /tomcat/web/WEB-INF/lib -p</code>

为了方便后面的测试,为2台服务器分别建立index.jsp测试页

47

48

49

50

51

<code>[root@TomcatA ~]</code><code># cd /tomcat/web/</code>

<code>[root@TomcatA web]</code><code># vi index.jsp</code>

<code>&lt;%@ page language=</code><code>"java"</code> <code>%&gt;</code>

<code>&lt;html&gt;</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;&lt;title&gt;TomcatA&lt;</code><code>/title</code><code>&gt;&lt;</code><code>/head</code><code>&gt;</code>

<code>  </code><code>&lt;body&gt;</code>

<code>    </code><code>&lt;h1&gt;&lt;font color=</code><code>"red"</code><code>&gt;TomcatA &lt;</code><code>/font</code><code>&gt;&lt;</code><code>/h1</code><code>&gt;</code>

<code>    </code><code>&lt;table align=</code><code>"centre"</code> <code>border=</code><code>"1"</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>tr</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;Session ID&lt;</code><code>/td</code><code>&gt;</code>

<code>    </code><code>&lt;% session.setAttribute(</code><code>"abc"</code><code>,</code><code>"abc"</code><code>); %&gt;</code>

<code>        </code><code>&lt;td&gt;&lt;%= session.getId() %&gt;&lt;</code><code>/td</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>/tr</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;Created on&lt;</code><code>/td</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;&lt;%= session.getCreationTime() %&gt;&lt;</code><code>/td</code><code>&gt;</code>

<code>     </code><code>&lt;</code><code>/tr</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>/table</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>/body</code><code>&gt;</code>

<code>&lt;</code><code>/html</code><code>&gt;</code>

<code>[root@TomcatA ~]</code><code># catalina.sh stop</code>

<code>[root@TomcatA ~]</code><code># curl http://192.168.30.117:8080/index.jsp</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    </code> 

<code>        </code><code>&lt;td&gt;AB5025287773B482327CF6F5D982389F.TomcatA&lt;</code><code>/td</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;1396605416275&lt;</code><code>/td</code><code>&gt;</code>

将配置文件和项目目录发送到TomcatB服务器,然后修改

<code>[root@TomcatA ~]</code><code># scp -pr /usr/local/tomcat/conf/server.xml [email protected]:/usr/local/tomcat/conf/</code>

<code>[root@TomcatA ~]</code><code># scp -pr /tomcat/ [email protected]:/</code>

<code>[root@TomcatB ~]</code><code># cd /usr/local/tomcat/conf/</code>

<code>[root@TomcatB conf]</code><code># vi server.xml</code>

<code># 将Engine标签中的defaulthost的值改为192.168.30.119,jvmRoute的值改为TomcatB,Host标签中的name的值改为192.168.30.119,jvmRoute的值改为TomcatB</code>

为TomcatB建立测试页面

<code>[root@TomcatB ~]</code><code># cd /tomcat/web/</code>

<code>[root@TomcatB web]</code><code># vi index.jsp</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;&lt;title&gt;TomcatB&lt;</code><code>/title</code><code>&gt;&lt;</code><code>/head</code><code>&gt;</code>

<code>    </code><code>&lt;h1&gt;&lt;font color=</code><code>"blue"</code><code>&gt;TomcatB &lt;</code><code>/font</code><code>&gt;&lt;</code><code>/h1</code><code>&gt;</code>

<code>[root@TomcatB ~]</code><code># catalina.sh stop</code>

<code>[root@TomcatB ~]</code><code># catalina.sh start</code>

<code>[root@TomcatB ~]</code><code># curl http://192.168.30.119:8080/index.jsp</code>

<code>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              </code> 

<code>        </code><code>&lt;td&gt;9F9DAF404E0EDDE92AD63400A4ED8283.TomcatA&lt;</code><code>/td</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;1396605796342&lt;</code><code>/td</code><code>&gt;</code>

配置apache通过mod_jk模块与Tomcat连接,mod_jk是ASF的一个项目,是一个工作于apache端基于AJP协议与Tomcat通信的连接器,它是apache的一个模块,是AJP协议的客户端(服务端是Tomcat的AJP连接器)。

<code>[root@apache ~]</code><code># tar zxvf tomcat-connectors-1.2.37-src.tar.gz</code>

<code>[root@apache ~]</code><code># cd tomcat-connectors-1.2.37-src/native</code>

<code>[root@apache native]</code><code># ./configure --with-apxs=/usr/local/apache/bin/apxs</code>

<code>[root@apache native]</code><code># make &amp;&amp; make install</code>

apache要使用mod_jk连接器,需要在启动时加载此连接器模块,为了便于管理与mod_jk模块相关的配置,这里使用一个专门的配置文件/etc/httpd/extra/httpd-jk.conf来保存相关指令及其设置。其内容如下:

<code>[root@apache ~]</code><code># vi /etc/httpd/extra/httpd-jk.conf</code>

<code>LoadModule  jk_module  modules</code><code>/mod_jk</code><code>.so</code>

<code>JkWorkersFile  </code><code>/etc/httpd/extra/workers</code><code>.properties</code>

<code>JkLogFile  logs</code><code>/mod_jk</code><code>.log</code>

<code>JkLogLevel  debug</code>

<code>JkMount  /*  lbcluster1</code>

<code>JkMount  </code><code>/jkstatus/</code>  <code>stat1</code>

编辑/etc/httpd/extra/workers.properties,添加如下内容:

<code>[root@apache ~]</code><code># vi /etc/httpd/extra/workers.properties</code>

<code>worker.list = lbcluster1,stat1</code>

<code>worker.TomcatA.</code><code>type</code> <code>= ajp13</code>

<code>worker.TomcatA.host = 192.168.30.117</code>

<code>worker.TomcatA.port = 8009</code>

<code>worker.TomcatA.lbfactor = 5</code>

<code>worker.TomcatB.</code><code>type</code> <code>= ajp13</code>

<code>worker.TomcatB.host = 192.168.30.119</code>

<code>worker.TomcatB.port = 8009</code>

<code>worker.TomcatB.lbfactor = 5</code>

<code>worker.lbcluster1.</code><code>type</code> <code>= lb</code>

<code>worker.lbcluster1.sticky_session = 1</code>

<code>worker.lbcluster1.balance_workers = TomcatA, TomcatB</code>

<code>worker.stat1.</code><code>type</code> <code>= status</code>

对于apache代理来说,每一个后端的Tomcat实例中的engine都可以视作一个worker,而每一个worker的地址、连接器的端口等信息都需要在apache端指定以便apache可以识别并使用这些worker。约定俗成,配置这些信息的文件通常为workers.properties,其具体路径则是使用前面介绍过的JkWorkersFile指定的,在apache启动时,mod_jk会扫描此文件获取每一个worker的配置信息。比如,我们这里使用/etc/httpd/extra/workers.properties。

workers.properties文件一般由两类指令组成:一是mod_jk可以连接的各worker名称列表,二是每一个worker的属性配置信息。它们分别遵循如下使用语法。

worker.list = &lt; a comma separated list of worker names &gt;

worker. &lt;worker name&gt; .&lt;property&gt; = &lt;property value&gt;

其中worker.list指令可以重复指定多次,而worker name则是Tomcat中engine组件jvmRoute参数的值。如:

worker.TomcatA.host=172.16.100.1

根据其工作机制的不同,worker有多种不同的类型,这是需要为每个worker定义的一项属性woker.&lt;work name&gt;.type。常见的类型如下:

ajp13:此类型表示当前worker为一个运行着的Tomcat实例。

lb:lb即load balancing,专用于负载均衡场景中的woker;此worker并不真正负责处理用户请求,而是将用户请求调度给其它类型为ajp13的worker。

status:用户显示分布式环境中各实际worker工作状态的特殊worker,它不处理任何请求,也不关联到任何实际工作的worker实例。具体示例如请参见后文中的配置。

worker其它常见的属性说明:

host:Tomcat 7的worker实例所在的主机;

port:Tomcat 7实例上AJP1.3连接器的端口;

connection_pool_minsize:最少要保存在连接池中的连接的个数;默认为pool_size/2;

connection_pool_timeout:连接池中连接的超时时长;

mount:由当前worker提供的context路径,如果有多个则使用空格格开;此属性可以由JkMount指令替代;

retries:错误发生时的重试次数;

socket_timeout:mod_jk等待worker响应的时长,默认为0,即无限等待;

socket_keepalive:是否启用keep alive的功能,1表示启用,0表示禁用;

lbfactor:worker的权重,可以在负载均衡的应用场景中为worker定义此属性;

另外,在负载均衡模式中,专用的属性还有:

balance_workers:用于负载均衡模式中的各worker的名称列表,需要注意的是,出现在此处的worker名称一定不能在任何worker.list属性列表中定义过,并且worker.list属性中定义的worker名字必须包含负载均衡worker。具体示例请参见后文中的定义。

method:可以设定为R、T或B;默认为R,即根据请求的个数进行调度;T表示根据已经发送给worker的实际流量大小进行调度;B表示根据实际负载情况进行调度。

sticky_session:在将某请求调度至某worker后,源于此址的所有后续请求都将直接调度至此worker,实现将用户session与某worker绑定。默认为值为1,即启用此功能。如果后端的各worker之间支持session复制,则可以将此属性值设为0

除了需要使用LoadModule指令在apache中装载模块外,mod_jk还需要在apache的主配置文件中设置其它一些指令来配置其工作属性。如JkWorkersFile则用于指定保存了worker相关工作属性定义的配置文件,JkLogFile则用于指定mod_jk模块的日志文件,JkLogLevel则可用于指定日志的级别(info, error, debug),此外还可以使用JkRequestLogFormat自定义日志信息格式。而JkMount(格式: JkMount  &lt;URL to match&gt;  &lt;Tomcat worker name&gt;)指定则用于控制URL与Tomcat workers的对应关系。

为了让apache能使用/etc/httpd/extra/httpd-jk.conf配置文件中的配置信息,需要编辑/etc/httpd/httpd.conf,添加如下一行:

<code># 添加</code>

<code>Include  </code><code>/etc/httpd/extra/httpd-jk</code><code>.conf</code>

<code>[root@apache ~]</code><code># /usr/local/apache/bin/apachectl -t</code>

<code>Syntax OK</code>

<code>[root@apache ~]</code><code># /usr/local/apache/bin/apachectl restart</code>

测试效果

<a href="http://s3.51cto.com/wyfs02/M02/23/B1/wKiom1M-ijXjmUL6AAEAlyeGCjA954.jpg" target="_blank"></a>

测试发现,当worker.lbcluster1.sticky_session = 1时,同一个客户端访问始终都是TomcatA的页面

下面修改worker.lbcluster1.sticky_session = 0

<code>worker.lbcluster1.sticky_session = 0</code>

测试发现,访问请求被平均发送到Tomcat A 和 B

<a href="http://s3.51cto.com/wyfs02/M02/23/B1/wKiom1M-iz3BRXAMAADtvrT3NIs620.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M01/23/B2/wKioL1M-iyHxedKYAAEAlyeGCjA009.jpg" target="_blank"></a>

这样就体现出Sticky sessions的意义了。

四、配置apache通过mod_proxy模块与Tomcat连接

要使用mod_proxy与Tomcat实例连接,需要apache已经装载mod_proxy、mod_proxy_http、mod_proxy_ajp和proxy_balancer_module(实现Tomcat集群时用到)等模块:

<code>[root@apache ~]</code><code># /usr/local/apache/bin/httpd -D DUMP_MODULES | grep proxy</code>

<code> </code><code>proxy_module (shared)</code>

<code> </code><code>proxy_connect_module (shared)</code>

<code> </code><code>proxy_ftp_module (shared)</code>

<code> </code><code>proxy_http_module (shared)</code>

<code> </code><code>proxy_fcgi_module (shared)</code>

<code> </code><code>proxy_scgi_module (shared)</code>

<code> </code><code>proxy_wstunnel_module (shared)</code>

<code> </code><code>proxy_ajp_module (shared)</code>

<code> </code><code>proxy_balancer_module (shared)</code>

<code> </code><code>proxy_express_module (shared)</code>

编辑/etc/httpd/extra/mod_proxy.conf

<code>[root@apache ~]</code><code># vi /etc/httpd/extra/mod_proxy.conf</code>

<code>ProxyVia On</code>

<code>ProxyRequests Off</code>

<code>ProxyPreserveHost Off</code>

<code>&lt;proxy balancer:</code><code>//lbcluster1</code><code>&gt;</code>

<code>        </code><code>BalancerMember ajp:</code><code>//192</code><code>.168.30.119:8009 loadfactor=10 route=TomcatA</code>

<code>        </code><code>BalancerMember ajp:</code><code>//192</code><code>.168.30.117:8009 loadfactor=10 route=TomcatB</code>

<code>        </code><code>ProxySet lbmethod=byrequests</code>

<code>&lt;</code><code>/proxy</code><code>&gt;</code>

<code>&lt;Location </code><code>/balancer-manager</code><code>&gt;</code>

<code>   </code><code>SetHandler balancer-manager</code>

<code>   </code><code>Proxypass !</code>

<code>   </code><code>Require all granted</code>

<code>&lt;</code><code>/Location</code><code>&gt;</code>

<code>ProxyPass / balancer:</code><code>//lbcluster1/</code>

<code>ProxyPassReverse / balancer:</code><code>//lbcluster1/</code>

<code>&lt;Proxy *&gt;</code>

<code>  </code><code>Require all granted</code>

<code>&lt;</code><code>/Proxy</code><code>&gt;</code>

<code># 为了防止前面使用mod_jk模块带来的影响,要注释掉httpd.conf中的</code>

<code>注释 Include  </code><code>/etc/httpd/extra/httpd-jk</code><code>.conf</code>

<code>添加 Include  </code><code>/etc/httpd/extra/mod_proxy</code><code>.conf</code>

关于如上apache指令的说明:

ProxyPreserveHost {On|Off}:如果启用此功能,代理会将用户请求报文中的Host:行发送给后端的服务器,而不再使用ProxyPass指定的服务器地址。如果想在反向代理中支持虚拟主机,则需要开启此项,否则就无需打开此功能。

ProxyVia  {On|Off|Full|Block}:用于控制在http首部是否使用Via:,主要用于在多级代理中控制代理请求的流向。默认为Off,即不启用此功能;On表示每个请求和响应报文均添加Via:;Full表示每个Via:行都会添加当前apache服务器的版本号信息;Block表示每个代理请求报文中的Via:都会被移除。

ProxyRequests {On|Off}:是否开启apache正向代理的功能;启用此项时为了代理http协议必须启用mod_proxy_http模块。同时,如果为apache设置了ProxyPass,则必须将ProxyRequests设置为Off。

ProxyPass  [path]  !|url  [key=value key=value ...]]:将后端服务器某URL与当前服务器的某虚拟路径关联起来作为提供服务的路径,path为当前服务器上的某虚拟路径,url为后端服务器上某URL路径。使用此指令时必须将ProxyRequests的值设置为Off。需要注意的是,如果path以“/”结尾,则对应的url也必须以“/”结尾,反之亦然。

ProxyPassReverse:它一般和ProxyPass指令配合使用,此指令使Apache调整HTTP重定向应答中Location, Content-Location, URI头里的URL,这样可以避免在Apache作为反向代理使用时,后端服务器的HTTP重定向造成的绕过反向代理的问题,在没有加这样的反向代理设置的情况下,访问http://www.test.com/example/a,如果www.example.com对请求进行了redirect至http://www.example.com/b,那么,客户端就会绕过反向代理,进而访问http://www.test.com/example/b。如果设置了反向代理,则会在转交HTTP重定向应答到客户端之前调整它为http://www.test.com/example/a/b,即是在原请求之后追加上了redirect的路径。

另外,mod_proxy模块在httpd 2.1的版本之后支持与后端服务器的连接池功能,连接在按需创建在可以保存至连接池中以备进一步使用。连接池大小或其它设定可以通过在ProxyPass中使用key=value的方式定义。常用的key如下所示:

min:连接池的最小容量,此值与实际连接个数无关,仅表示连接池最小要初始化的空间大小。

max:连接池的最大容量,每个MPM都有自己独立的容量;都值与MPM本身有关,如Prefork的总是为1,而其它的则取决于ThreadsPerChild指令的值。

loadfactor:用于负载均衡集群配置中,定义对应后端服务器的权重,取值范围为1-100。

retry:当apache将请求发送至后端服务器得到错误响应时等待多长时间以后再重试。单位是秒钟。

如果Proxy指定是以balancer://开头,即用于负载均衡集群时,其还可以接受一些特殊的参数,如下所示:

lbmethod:apache实现负载均衡的调度方法,默认是byrequests,即基于权重将统计请求个数进行调度,bytraffic则执行基于权重的流量计数调度,bybusyness通过考量每个后端服务器的当前负载进行调度。

maxattempts:放弃请求之前实现故障转移的次数,默认为1,其最大值不应该大于总的节点数。

nofailover:取值为On或Off,设置为On时表示后端服务器故障时,用户的session将损坏;因此,在后端服务器不支持session复制时可将其设置为On。

stickysession:调度器的sticky session的名字,根据web程序语言的不同,其值为JSESSIONID或PHPSESSIONID。

上述指令除了能在banlancer://或ProxyPass中设定之外,也可使用ProxySet指令直接进行设置。

打开浏览器测试

<a href="http://s3.51cto.com/wyfs02/M00/23/B2/wKioL1M-ltOzOaVaAAEAlyeGCjA516.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M02/23/B1/wKiom1M-lwWA7gLUAADtvrT3NIs027.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M01/23/B2/wKioL1M-l5vTcz3PAAUXcxcSUTo673.jpg" target="_blank"></a>

可以看到俩个后端节点,工作正常。

配置,Tomcat的session集群复制,

52

53

54

55

56

57

58

59

60

<code># 删除之前新添加的Host,修改Engine中defaultHost的值为localhost</code>

<code>[root@TomcatA ~]</code><code># nano /usr/local/tomcat/conf/server.xml</code>

<code># 在Engine在中添加,address地址改为了本机地址</code>

<code>&lt;Cluster className=</code><code>"org.apache.catalina.ha.tcp.SimpleTcpCluster"</code>

<code>                 </code><code>channelSendOptions=</code><code>"8"</code><code>&gt;</code>

<code>          </code><code>&lt;Manager className=</code><code>"org.apache.catalina.ha.session.DeltaManager"</code>

<code>                   </code><code>expireSessionsOnShutdown=</code><code>"false"</code>

<code>                   </code><code>notifyListenersOnReplication=</code><code>"true"</code><code>/&gt;</code>

<code>          </code><code>&lt;Channel className=</code><code>"org.apache.catalina.tribes.group.GroupChannel"</code><code>&gt;</code>

<code>            </code><code>&lt;Membership className=</code><code>"org.apache.catalina.tribes.membership.McastService"</code>

<code>                        </code><code>address=</code><code>"192.168.30.117"</code>

<code>                        </code><code>port=</code><code>"45564"</code>

<code>                        </code><code>frequency=</code><code>"500"</code>

<code>                        </code><code>dropTime=</code><code>"3000"</code><code>/&gt;</code>

<code>            </code><code>&lt;Receiver className=</code><code>"org.apache.catalina.tribes.transport.nio.NioReceiver"</code>

<code>                      </code><code>address=</code><code>"auto"</code>

<code>                      </code><code>port=</code><code>"4000"</code>

<code>                      </code><code>autoBind=</code><code>"100"</code>

<code>                      </code><code>selectorTimeout=</code><code>"5000"</code>

<code>                      </code><code>maxThreads=</code><code>"6"</code><code>/&gt;</code>

<code>            </code><code>&lt;Sender className=</code><code>"org.apache.catalina.tribes.transport.ReplicationTransmitter"</code><code>&gt;</code>

<code>              </code><code>&lt;Transport className=</code><code>"org.apache.catalina.tribes.transport.nio.PooledParallelSender"</code><code>/&gt;</code>

<code>            </code><code>&lt;</code><code>/Sender</code><code>&gt;</code>

<code>            </code><code>&lt;Interceptor className=</code><code>"org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"</code><code>/&gt;</code>

<code>            </code><code>&lt;Interceptor className=</code><code>"org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"</code><code>/&gt;</code>

<code>          </code><code>&lt;</code><code>/Channel</code><code>&gt;</code>

<code>          </code><code>&lt;Valve className=</code><code>"org.apache.catalina.ha.tcp.ReplicationValve"</code>

<code>                 </code><code>filter=</code><code>""</code><code>/&gt;</code>

<code>          </code><code>&lt;Valve className=</code><code>"org.apache.catalina.ha.session.JvmRouteBinderValve"</code><code>/&gt;</code>

<code>          </code><code>&lt;Deployer className=</code><code>"org.apache.catalina.ha.deploy.FarmWarDeployer"</code>

<code>                    </code><code>tempDir=</code><code>"/tmp/war-temp/"</code>

<code>                    </code><code>deployDir=</code><code>"/tmp/war-deploy/"</code>

<code>                    </code><code>watchDir=</code><code>"/tmp/war-listen/"</code>

<code>                    </code><code>watchEnabled=</code><code>"false"</code><code>/&gt;</code>

<code>          </code><code>&lt;ClusterListener className=</code><code>"org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"</code><code>/&gt;</code>

<code>          </code><code>&lt;ClusterListener className=</code><code>"org.apache.catalina.ha.session.ClusterSessionListener"</code><code>/&gt;</code>

<code>        </code><code>&lt;</code><code>/Cluster</code><code>&gt;</code>

<code>[root@TomcatA ~]</code><code># cp /tomcat/web/index.jsp /usr/local/tomcat/webapps/ROOT/test.jsp</code>

<code>[root@TomcatA ~]</code><code># vi /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml</code>

<code># 在web-app中添加&lt;distributable/&gt;</code>

<code># 在TomcatB上做相同的操作</code>

<code># 观察TomcatA的catalina.out日志</code>

<code>[root@TomcatA ~]</code><code># tail -f /usr/local/tomcat/logs/catalina.out</code>

<code>INFO: Starting clustering manager at localhost</code><code>#</code>

<code>Apr 08, 2014 9:57:02 AM org.apache.catalina.ha.session.DeltaManager getAllClusterSessions</code>

<code>INFO: Manager [localhost</code><code>#], requesting session state from org.apache.catalina.tribes.membership.MemberImpl[tcp://{192, 168, 30, 119}:4000,{192, 168, 30, 119},4000, alive=28035, securePort=-1, UDP Port=-1, id={106 18 -38 -75 59 79 79 -35 -86 -72 -23 -20 -3 -80 -105 80 }, payload={}, command={}, domain={}, ]. This operation will timeout if no session state has been received within 60 seconds.</code>

日志显示集群session启动成功

打开浏览器访问,看下session是否同步

<a href="http://s3.51cto.com/wyfs02/M02/23/C4/wKiom1NDWVizx8vLAADV_2Fjaec678.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M00/23/C4/wKiom1NDWXLCrxblAADiPdbFUjQ748.jpg" target="_blank"></a>

发现session是相同的

到此,Apache使用俩种方式代理tomcat集群以及session复制已经配置完成。

     本文转自ljl_19880709 51CTO博客,原文链接:http://blog.51cto.com/luojianlong/1390767,如需转载请自行联系原作者