Apache 整合 Tomcat 、集群
目录
1.1 使用 mod_proxy整合
1.2 使用 mod_jk整合
1.3 集群
1.3.1 Tomcat集群配置
1.3.2 mod_proxy进行负载均衡
1.3.3 mod_jk进行负载均衡
Apache整合 Tomcat主要有两种方式,通过 mod_proxy整合和通过 mod_jk整合。
1.1 使用 mod_proxy整合
使用 mod_proxy整合 Tomcat需要我们开启 Apache的代理功能,代理功能的开启可以通过在 Apache的 conf/httpd.conf文件中将如下内容前的“ #”号去除,这样 Apache就能在运行的时候加载 mod_proxy模块了,从而开启了 Apache的代理功能。
#LoadModule proxy_module modules/mod_proxy.so
开启了 mod_proxy之后我们还需要选择一个协议来作为 Apache代理 Tomcat的协议,可以是 AJP协议、 Http协议等。如果需要使用 Http协议,那么请将 Apache的 conf/httpd.conf文件中如下内容前的“ #”号去除(需要使用其它的协议时使用类似的方式)。 Tomcat 的官方文档说在进行 Tomcat 集群时使用 AJP 协议比使用 Http 协议的性能要更好 ( It should be noted that the performance of HTTP proxying is usually lower than the performance of AJP, so AJP clustering is often preferable. )。
#LoadModule proxy_http_module modules/mod_proxy_http.so
Apache的代理有两种方式, Reverse方式和 Forward方式。 Forward 方式需要在客户端进行配置以利用代理服务器获取目标内容, Forward方式的一种常见场景就是我们的内网机器都无法连接外网,但是其中有一台可以连接,然后我们在可以连接外网的机器上搭建一个代理,让其它内网机器都通过该代理来访问外部网络。 Reverse 方式就无需在客户端进行配置了,客户端请求的目标地址是直接对应 Reverse代理的,然后由 Reverse代理在内部决定请求哪个真实的地址。本文将主要讲解 Reverse代理方式。
首先去掉 httpd.conf文件中如下内容前的“ #”号,以将 Virtual Host的配置包含在 Apache服务器的配置文件中,然后我们就可以在 httpd-vhosts.conf文件中进行 Virtual Host的配置了。
#Include conf/extra/httpd-vhosts.conf
然后,我们在 conf/extra/httpd-vhosts.conf文件中添加如下内容,其表示我们定义了一个虚拟主机,该虚拟主机将接收任何请求。
<VirtualHost *:80>
ProxyPass "/" "http://localhost:8080/" max=300
ProxyPassReverse "/" "http://localhost:8080/"
</VirtualHost>
上述的指令 ProxyPass是用来映射代理的路径的,其语法是:
ProxyPass path !|url [key=value[key=value…]]
其中 path表示 Apache请求的相对路径,而“ !”则表示不对该路径进行代理, url则表示需要代理的路径,后面的 key=value表示需要指定的参数。在我们的示例中就是使用根路径“ /”代理本地 8080端口的根路径“ /”,然后参数 max表示同时最多允许 300个对后台代理服务的并发请求。关于 ProxyPass的更多信息请参考 http://httpd.apache.org/docs/2.4/zh-cn/mod/mod_proxy.html#proxypass。
指令 ProxyPassReverse是用来对后台代理应用返回过来的 Response Header中的 URL进行转换的,使其能够以 Apache的形式正确的展示。比如请求后台服务后需要重定向到 http://localhost:8080/examples则通过 ProxyPassReverse指令进行转换后将会把重定向地址改为 http://localhost/examples。
这个时候我们在 8080端口启动 Tomcat,然后在 80端口启动 Apache,之后我们所有对 80端口的请求都将由 Apache代理请求到 8080端口的 Tomcat应用。
如下这样的配置就表示不对“ /examples”路径进行代理,此时访问“ /examples”时将去 Apache自己的路径下寻找对应的资源。
<VirtualHost *:80>
ProxyPass "/examples" "!"
ProxyPass "/" "http://localhost:8080/" max=300
ProxyPassReverse "/" "http://localhost:8080/"
</VirtualHost>
此时如果你在浏览器里面访问 http://localhost/examples时会得到一个 403页面,原因是 Apache默认会禁止对根目录以外的路径的访问。此时,我们需要找到 httpd.conf文件中的如下内容:
<Directory />
AllowOverride none
Require all denied
</Directory>
并将其修改为如下内容:
<Directory />
AllowOverride none
Order Deny,ALlow
Allow from All
</Directory>
更多内容请参考 http://httpd.apache.org/docs/2.4/mod/mod_proxy.html。
1.2 使用 mod_jk整合
首先我们需要下载 mod_jk.so,其由 Tomcat提供,可以从网址 http://tomcat.apache.org/connectors-doc/寻找对应 Apache版本的 mod_jk.so进行下载。下载后将 mod_jk.so放到 Apache服务器的 modules目录下。
然后在 httpd.conf文件的末尾加上如下内容以加载 mod_jk。
# 加载 mod_jk模块
LoadModule jk_module modules/mod_jk.so
# 指定 workers.properties文件的路径
JkWorkersFile conf/workers.properties
# 指定 Jk的日志输出路径
JkLogFile logs/mod_jk.log
# 指定 Jk日志文件的输出级别, [debug/info/error]
JkLogLevel info
# 指定日志输出时间的格式
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
之后可以在 extra/httpd-vhosts.conf文件中加上如下内容(注意需要在 httpd.conf文件中 include extra/httpd-vhosts.conf文件)。
<VirtualHost *:80>
# 指定交给 worker1进行处理的路径
JkMount /* worker1
# 指定不交给 worker1进行处理的路径
JkUnMount /examples/* worker1</VirtualHost>
上述指令所代表的含义已经在注释中给出,关于针对 Jk Module的更多配置信息官方文档 http://tomcat.apache.org/connectors-doc/reference/apache.html的配置说明。
接下来需要在我们指定的 workers.properties文件中定义对应的 worker。这里我们指定如下。
#指定需要定义的 worker列表,多个 worker之间使用逗号分隔
worker.list=worker1
#指定 worker1的 type
worker.worker1.type=ajp13
#指定 worker1连接的 Tomcat的 IP
worker.worker1.host=localhost
#指定 worker1连接 tomcat的端口,因为我们 worker1使用的 type为 ajp13,这里需要是 ajp13协议的端口
worker.worker1.port=8009
#指定 worker1对应的连接池的大小
worker.worker1.connection_pool_size=300
使用 ajp13协议时,对应的连接端口对应于我们的 Tomcat的 server.xml文件中配置的 ajp13协议的端口,如:
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
更多关于 workers.properties文件可以配置的信息请参考 Tomcat的官方文档。 http://tomcat.apache.org/connectors-doc/reference/workers.html。
通过如上配置后除了 /examples下的内容以外,我们就完全把 Tomcat交给了 Apache代理。
1.3 集群
Apache整合 Tomcat进行集群是将多个 Tomcat进行集群,集群的各个节点之间可以进行 Session的同步等,然后通过上述介绍的两种方式使用 Apache代理以实现对各个节点之间的负载均衡。其实除了 Apache服务器对 Tomcat集群进行负载均衡外,常用的进行负载均衡代理的还有 Nginx,本文的主题是 Apache整合 Tomcat,所以不会对 Nginx代理 Tomcat集群进行讲解,有兴趣的朋友可以自己查阅相关的文档进行了解。
1.3.1Tomcat集群配置
Tomcat的集群配置最简单的方式是将 Tomcat的 conf目录下的 server.xml文件中的 <cluster>标签的注释打开。
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
注意如果是在同一台电脑上同时启动多个 Tomcat进行集群时需要保证各个 Tomcat使用的 Server端口、 Http端口和 Ajp端口都是各不相同的。
只配置一个 <Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”/>时 Tomcat默认会为我们配置如下内容:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
channelSendOptions="8">
<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="4000"
autoBind="100"
selectorTimeout="5000"
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"/>
</Channel>
<Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
filter=""/>
<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.JvmRouteSessionIDBinderListener">
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener">
</Cluster>
关于 Tomcat集群的详细配置信息请参考 Tomcat的官方文档 http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html。
使用 Tomcat进行集群时,如果我们 Session能够在多个节点之间进行自动复制,我们需要保证存在在 Session中的 attribute都是可序列化的,即都是实现了 java.io.Serializable接口的,此外我们需要部署在每个 Tomcat节点上的应用的 web.xml文件中定义了 <distribuable/>。
1.3.2mod_proxy进行负载均衡
为使用 mod_proxy能够支持负载均衡,我们需要加载 mod_proxy_balancer模块,该模块提供的功能就是负载均衡,但是使用的负载均衡算法并不由它提供,而是由对应的算法模块提供。 Apache自带的算法模块有如下四种。
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
mod_proxy_balancer默认使用的负载均衡算法是 byrequests,所以默认情况下我们还需要加载 mod_lbmethod_byrequests模块。此外,还需要加载提供共享内存的模块 mod_slotmem_shm.so。所以,总的来说我们需要加载如下三个模块。
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so
LoadModule slotmem_shm_module modules/mod_slotmem_shm.so
接下来,我们可以在 VirtualHost下配置如下内容:
<VirtualHost *:80>
<Proxy "balancer://elim">
#定义负载均衡的成员, loadfactor用于指定负载权重的
BalancerMember "http://localhost:8080" loadfactor=1
BalancerMember "http://localhost:9090" loadfactor=2
#ProxySet指令用于设定 balancer的参数
ProxySet lbmethod=byrequests
</Proxy>
#代理什么路径就在 balancer://elim后加什么路径
ProxyPass "/" "balancer://elim/"
ProxyPassReverse "/" "balancer://elim/"
</VirtualHost>
在上述配置中我们通过 <Proxy>标签来定义了一个负载均衡代理,名叫“ balancer://elim”,在使用 <Proxy>标签进行代理的定义时,如果我们的前缀是以“ balancer://”开始的,则定义的是一个负载均衡代理。在其中可以通过 BalancerMember来指定对应的成员, loadfactor用来指定对应的负载权重。通过 ProxySet指令我们指定了负载均衡代理 balancer://elim的负载均衡算法为 byrequests,这也是负载均衡代理的默认算法。然后通过 ProxyPass指定对应路径的代理时,我们就可以指定为我们定义的负载均衡代理 balancer://elim。需要注意的是如果我们需要代理的是根路径,需要在 balancer://elim后也加上根路径“ /”。通过如上配置以后我们的负载均衡代理就建立起来了。
关于 mod_proxy_balancer负载均衡的更多介绍请参考文档 http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html。更多负载均衡配置信息请参考 http://httpd.apache.org/docs/2.4/mod/mod_proxy.html。
Apache为我们提供了一个 mod_status模块,通过该模块我们可以监测我们的负载均衡代理的运行情况,或在运行时修改我们的负载均衡的成员的配置信息。首先我们需要加载 mod_status模块。
LoadModule status_module modules/mod_status.so
然后我们需要在 httpd.conf文件中通过 Location指定我们监测负载均衡的路径和对应的处理器。如下配置则表示我们将监测路径定义为 /balancer-status,对应的处理器为 balancer-manager,然后允许所有的用户请求该地址。
<Location /balancer-status>
SetHandler balancer-manager
Order deny,allow
Allow from all
</Location>
如果我们需要监测的是我们的 Apache服务器的运行情况,则可以将上述的 SetHandler设置为 server-status。需要注意的是当和代理一起使用的时候,需要避免指定的访问路径和代理的代理路径相冲突,此时需要我们将监测 Apache服务器运行情况的访问路径从代理中移除。
1.3.3mod_jk进行负载均衡
当使用 mod_jk进行负载均衡的时候,我们需要修改我们的 workers.properties文件的定义。此时,我们将 workers.properties的内容修改为如下形式。
worker.list=cluster
#指定名为 cluster的 worker的类型是 lb,即负载均衡
worker.cluster.type=lb
#指定负载均衡 worker的参与者为 worker1和 worker2
worker.cluster.balance_workers=worker1,worker2
#当为 true时同一个 Session发送的请求只会代理到相同的 Tomcat节点上
worker.cluster.sticky_session=false
#表示是否强制绑定 session,该参数只针对 sticky_session为 true时才有效。当 sticky_session和 sticky_session_force都为 true
#时,如果对应 Session的 Tomcat不可用了,对应的请求将会返回对应的错误页面给客户端,否则将由其它节点来进行接管处理。
worker.cluster.sticky_session_force=false
#指定 worker1连接 Tomcat的协议类型
worker.worker1.type=ajp13
#指定 worker1的对应的 Tomcat的 IP
worker.worker1.host=localhost
#指定 worker1连接 Tomcat时使用的端口号
worker.worker1.port=8009
#指定 worker1在集群中负载的权重为 1,数字越大负载越高
worker.worker1.lbfactor=1
#指定 worker2连接 Tomcat的协议类型
worker.worker2.type=ajp13
#指定 worker2的对应的 Tomcat的 IP
worker.worker2.host=localhost
#指定 worker2连接 Tomcat时使用的端口号
worker.worker2.port=18009
#指定 worker2在集群中负载的权重为 2,由于 worker1为 1,所以 worker2将占总负载的 2/3。
worker.worker2.lbfactor=2
该配置表示我们的 Tomcat集群中拥有两台 Tomcat服务器,然后这两台 Tomcat都是部署在同一台服务器上的。接下来,我们需要告诉 Apache哪些请求将交给我们的负载均衡 worker—— cluster处理。
<VirtualHost *:80>
# 指定将所有的请求都交给我们的负载均衡 worker—— cluster进行处理。
JkMount /* cluster
</VirtualHost>
使用 mod_jk进行负载均衡的时候需要注意的是我们需要在我们的 Tomcat的 server.xml文件中为我们的 Engine指定 jvmRoute,且对应的值还必须和我们在 workers.properties文件中指定的负载均衡 worker的名称一致。
<Engine name="Catalina" defaultHost="localhost" jvmRoute="worker1">
经过上述配置以后我们的 mod_jk对 Tomcat集群的负载均衡就搭建好了。其默认的负载均衡策略是通过 Request来进行负载均衡的,我们可以通过在 worker.properties文件中对类型为 lb的 worker指定其 method属性来显示的指定负载均衡策略。除了 Request外,还有 Session、 Next、 Traffic、 Business,关于这几种负载均衡策略的详细介绍请参考文档 http://tomcat.apache.org/connectors-doc/reference/workers.html。
mod_jk中有一类特殊的 worker类型, status类型,它可以用来监测 worker的运行情况和在运行时动态更改 worker的配置信息等。定义 status类型的 worker非常简单,只需要指定一个 worker的 type为 status,同时在 worker.list中进行声明。
#指定名为 cluster的 worker的类型是 lb,即负载均衡
worker.cluster.type=lb
#指定负载均衡 worker的参与者为 worker1和 worker2
worker.cluster.balance_workers=worker1,worker2
#当为 true时同一个 Session发送的请求只会代理到相同的 Tomcat节点上
worker.cluster.sticky_session=false
#表示是否强制绑定 session,该参数只针对 sticky_session为 true时才有效。当 sticky_session和 sticky_session_force都为 true
#时,如果对应 Session的 Tomcat不可用了,对应的请求将会返回对应的错误页面给客户端,否则将由其它节点来进行接管处理。
worker.cluster.sticky_session_force=false
…
…
#指定 worker的类型为 status
worker.status.type=status
之后我们需要为类型为 status的 worker指定一个对应的访问路径。
<VirtualHost *:80>
# 指定将请求路径 /status交给名叫 status的 worker处理。
JkMount /status status
# 指定将所有的请求都交给我们的负载均衡 worker—— cluster进行处理。
JkMount /* cluster
</VirtualHost>
这样我们在请求路径为 /status的时候就可以监测 worker的运行状态等信息了。更多关于类型为 status的 worker的介绍请参考官方文档 http://tomcat.apache.org/connectors-doc/reference/status.html。
参考文档
http://httpd.apache.org/docs/2.4/mod/mod_proxy.html
http://tomcat.apache.org/connectors-doc/reference/apache.html
http://tomcat.apache.org/connectors-doc/reference/workers.html
http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
http://tomcat.apache.org/connectors-doc/generic_howto/loadbalancers.html
http://tomcat.apache.org/connectors-doc/reference/status.html
http://httpd.apache.org/docs/2.4/mod/mod_proxy_balancer.html
http://httpd.apache.org/docs/2.4/mod/mod_status.html
(注:本文是基于 Apache Tomcat7.0.50版本和 Apache Httpd2.4版本所写)
(注:原创文章,转载请注明出处。原文地址:http://haohaoxuexi.iteye.com/blog/2247244)
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com