Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现

时间:2021-04-12 16:56:40

  Apache作为前端的Web服务器,将客户端的请求分流到后端的多个Tomcat应用服务器。

  1、准备环境

    1)确保已安装好不低于1.5版本的JDK,并配置好相应的环境变量

    2)下载Apache HTTP Server

      2.1)windows版本下载地址:http://archive.apache.org/dist/httpd/binaries/win32/  我下载的是:httpd-2.2.22-win32-x86-openssl-0.9.8t.msi

      2.2)安装Apache HTTP Server,选择典型安装就行了。在安装界面出现Server Information界面时,需要填写Network Domain、Server Name和Administrator's Email Address,我只是在自己的机器上配置,所以我就按如下填写了。

                                                    Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现

        填写好之后,一路Next。

      2.3)检查Apache HTTP Server是否安装成功,在浏览器输入 http://localhost/ 如果出现下面的页面即可。

                       Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现

    3)准备两个Tomcat应用服务器

      我这里使用的是apache-tomcat-7.0.33.zip

      解压后分别取名tomcat-7-1和tomcat-7-2

                Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现

  2、配置Apache HTTP Server负载均衡

    1)修改Apache HTTP Server安装路径conf目录下的httpd.conf文件,找到以下内容,去掉前面的#注释,启用mod_proxy模块

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_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so

    mod_proxy  提供HTTP/1.1的代理/网关功能支持

    mod_proxy_ajp  mod_proxy的扩展,提供Apache JServ Protocol支持

    mod_proxy_balancer  mod_proxy的扩展,提供负载均衡支持

    mod_proxy_connect  mod_proxy的扩展,提供对处理HTTP CONNECT方法的支持

    mod_proxy_ftp  mod_proxy的FTP支持模块

    mod_proxy_http  mod_proxy的HTTP支持模块

    2)在httpd.conf文件的最后面添加以下内容

ProxyRequests Off  
<proxy balancer://cluster>
BalancerMember ajp://localhost:8009 loadfactor=1 route=jvm1
BalancerMember ajp://localhost:9009 loadfactor=1 route=jvm2
</proxy>

    ProxyRequests Off  使用反向代理

    BalancerMember  把服务器添加到负载均衡组

    loadfactor  负载比例分配,上面的设置是按1:1的比例给两台服务器分配请求,loadfactor的值是1-100之间

    因为是在同一台机器上,所以我把其中一个应用服务器tomcat-7-2的AJP协议端口改为9009,怎么改在后面tomcat的配置中会说,在不同的机器上无需修改。route也要和各自的应用服务器配置的引擎一致

    3)找到httpd.conf文件中的Include conf/extra/httpd-vhosts.conf,去掉前面的#注释,导入虚拟主机配置文件。修改后如下

# Virtual hosts
Include conf/extra/httpd-vhosts.conf

    4)修改conf目录下extra目录中的httpd-vhosts.conf文件,在文件最后添加以下内容,将80端口的请求转发给负载均衡代理处理器

<VirtualHost *:80> 
ServerName localhost
ProxyPass / balancer://cluster/ stickysession=jsessionid nofailover=On
ProxyPassReverse / balancer://cluster/
</VirtualHost>

  

  3、配置Tomcat的server.xml文件

    1)因为是在同一台机器上,所以将其中一个应用服务器tomcat-7-2的端口做如下修改

    1.1)找到:

<Server port="8005" shutdown="SHUTDOWN">

      修改成:

<Server port="9005" shutdown="SHUTDOWN">

    1.2)找到:

  <Connector port="8080" protocol="HTTP/1.1"
connectionTimeout
="20000"
redirectPort
="8443" />

      修改成:

  <Connector port="9080" protocol="HTTP/1.1"
connectionTimeout
="20000"
redirectPort
="9443" />

    1.3)找到:

 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

      修改成:

<Connector port="9009" protocol="AJP/1.3" redirectPort="9443" />

    2)配置引擎Engine

    2.1)找到:

<Engine name="Catalina" defaultHost="localhost">

      tomcat-7-1修改成如下内容,将tomcat-7-1配置成集群成员

<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm1">

      tomcat-7-2修改成如下内容,将tomcat-7-2配置成集群成员

<Engine name="Standalone" defaultHost="localhost" jvmRoute="jvm2">

    3)配置一个集群环境中的session复制

    3.1)找到:

<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->

    去掉注释,在tomcat-7-1中修改为:

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6"> 

<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"/>
<!--因为tomcat都在同一台机器上,这里的端口设置成5001-->

<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;"/>

<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>

      在tomcat-7-2中修改为:

  <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="6"> 

<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
="5002"
selectorTimeout
="100"
maxThreads
="6"/>
<!--因为tomcat都在同一台机器上,这里的端口设置成5002-->

<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;"/>

<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>

 

  4、在应用程序的web.xml中加入<distributable/>元素使应用程序支持集群

  5、放入session中的对象需要实现序列化接口

  6、测试,建立一个web项目叫webapp。

    1)在index.jsp中,把一个值存到session中

<%@ page language="java"  pageEncoding="UTF-8"%>
<%

request.getSession().setAttribute(
"myName", "Luxh");
System.out.println(
"set value success!");
%>

<!DOCTYPE html>
<html>
<head>

<title>My JSP 'index.jsp' starting page</title>

<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
hello,apache and tomcat! this is index.jsp file.
<br>
</body>
</html>

    2)写一个Servlet,把存在session中的值取出

package cn.luxh.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {



System.out.println(
"Hello,Apache and Tomcat!!!!!!!!====="+request.getSession().getAttribute("myName"));

response.setContentType(
"text/html");
PrintWriter out
= response.getWriter();
out.println(
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println(
"<HTML>");
out.println(
" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(
" <BODY>");
out.print(
" This is ");
out.print(
this.getClass());
out.println(
", using the GET method");
out.println(
" </BODY>");
out.println(
"</HTML>");
out.flush();
out.close();
}

}

    3)配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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_2_5.xsd"
>
<display-name></display-name>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>cn.luxh.servlet.MyServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/servlet/MyServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<distributable/>

</web-app>

    4)将项目打成war包,分别放到tomcat的webapps目录下

    5)启动Apache HTTP Server,启动tomcat-7-1,启动tomcat-7-2

    访问:http://localhost/webapp/ ,可以看到请求被分发到tomcat-7-1中,并且把值存到session中

Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现

 

      接下来,我们不断访问servlet,可以看到,请求被平均分发到两个应用服务器,并且能从session中取到值。

Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现

 

      接下来,停掉tomcat-7-1,继续不断访问servlet,在剩下的那个tomcat中依然可以取到session中的值

Windows下Apache+Tomcat做简单负载均衡--使用mod_proxy实现