1、Apache+Tomcat集群配置 一、 技术基础 Apache和Tomcat同是Apache基金会下面的两个项目。一个是HTTP WEB服务器,另一个是servlet容器(servlet container),最新的5.5.X系列实现Servlet 2.4/JSP 2.0Spec,一般也可以把Tomcat看做是应用服务器。 Apache是目前比较受欢迎的网站服务器软件,它不但功能强大,而且完全免费,并且支持市场上流行的各种操作系统(Windows,Linux,Mac os)。 Tomcat也是Apache出品的,应用于对Java Servlet/JSP的支持的应用服务器。
2、Tomcat除了支持Java Servlet/JSP之外,也可以当做网站服务器使用。 但是在对于静态的html文件、图片文件等的解析效率上不如Apache的执行效率高。例如应用tomcat的服务器如果网站的访问量较大,系统资源占用会明显升高,服务器负担会加重,从而导致系统或服务器崩溃。 因此在实际应用中,常常把Tomcat与Apache集成。当Tomcat与Apache集成时,Apache负责静态资源处理,tomcat负责jsp和java servlet等动态资源的处理。在我们生产的环境中,往往需要Apache做前端服务器,Tomcat做后端服务器。此时我们就需要一个连接器,这
3、个连接器的作用就是把 所有Servlet/JSP的请求转给Tomcat来处理。Tomcat服务器的工作模式通常为进程外的Servlet容器,Tomcat服务器与Apache之间通过专门的插件来通信。 利用apache来解析*.html *.htm *.jpg *.gif *.js等静态网页与内容 当遇到*.jsp,* servlet和*.do时,通过一个apache中的module把这些内容抛给Tomcat来处理。 第一个连接器监听8080端口,负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器。 第二个连接器监听8
4、009端口,负责和其他的HTTP服务器建立连接。在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器。 Web客户访问Tomcat服务器上JSP组件的两种方式如图所示: 二、 环境说明 Apache: apache_2.2.2 Tomcat: apache-tomcat-5.5.17 (zip版) mod_jk: mod_jk-apache-2.2.4.so(Apache与Tomcat通信的插件) 操作系统:windows XP或windows 2K 三、 具体步骤
5、第一部分:负载均衡 负载均衡,就是apache将客户请求均衡的分给tomcat1,tomcat2....等多个服务器的多个不同的Tomcat去处理!如此就把单个Tomcat的负担降到最低了! 1. 安装apche,tomcat 注意:安装apache时必须写明主机地址或域名,邮箱随便填 假设有两台机器负载,那么各装1个tomcat 2.在apache安装目录下conf目录中找到http.conf 在文件最后加上下面一句话就可以了(假设我的apache在E:\ide\apache目录下) include "E:\ide\apache\conf\mod_jk.conf"
6、 作用:加入这句话指定mod_jk配置文件路径。 3. http.conf 同目录下新建mod_jk.conf文件,内容如下 #加载mod_jk Module(把mod_jk-apache-2.2.4.so拷贝到E:\ide\apache\modules文件夹) LoadModule jk_module modules/ mod_jk-apache-2.2.4.so #指定 workers.properties文件路径 JkWorkersFile conf/workers.properties #指定把哪些请求交给tomcat处理,"controller"为在w
7、orkers.propertise里指定的负载分配控制器 JkMount /*.jsp controller JKMount /*.do controller JKMount /*servlet controller(注:为了配置方便,务必使servlet都以servlet结尾) ---备注:这里也可以设置是否把*.jpg,*.js,*.html,*.htm,*.txt,*.gif, *.xml, *.dtd……等静态内容的请求交给tomcat处理(最好不这样处理),一般都是静态内容给apache而动态内容给tomcat,那么只要在这里分配*.jsp,*.do,*servlet等这
8、些动态内容给tomcat即可,其他静态内容给apache处理,具体的配置路径请见注意事项2。 作用:配置插件与属性文件并且处理各种请求格式的分配 4. 在http.conf同目录下新建 workers.properties文件,内容如下: worker.list = controller,tomcat1,tomcat2 #server 列表,命名controller与mod_jk.conf文件中的controller相对应 #========tomcat1======== worker.tomcat1.port=8009 #ajp1
9、3 端口号,在tomcat下server.xml配置,默认8009,ajp为tomcat与apache通讯协议 worker.tomcat1.host=localhost #tomcat所在主机地址,如不为本机,请填写ip地址 worker.tomcat1.type=ajp13 #使用ajp13协议 worker.tomcat1.lbfactor = 1 #server的加权比重,值越高,分得的请求越多,都为1时为平均分配 #========tomcat2======== worker.tomcat2.port=8009 #ajp13 端口号,
10、在tomcat下server.xml配置,默认8009,ajp为tomcat与apache通讯协议
(ps:若有端口冲突,请在tomcat/conf/server.xml文件中的
11、worker.tomcat2.port=9009) worker.tomcat2.host=localhost #tomcat所在主机地址,如不为本机,请填写ip地址 worker.tomcat2.type=ajp13 #使用ajp13协议 worker.tomcat2.lbfactor = 1 #server的加权比重,值越高,分得的请求越多,都为1时为平均分配 #========controller负载均衡控制器======== worker.controller.type=lb worker.controller.balanced_workers=tomcat1,t
12、omcat2 #指定分担请求的tomcat worker.controller.sticky_session=1 #允许负载均衡控制器复制session 5. 编写一个测试jsp 建立一个目录test.里面新建一个test.jsp,内容为 <% System.out.println("==========================="); %> 把test放到tomcat1,tomcat2的webapps下 6. 启动apache,tomcat1,tomcat2,进行测试 通过 http://(apache配置时候的主机地址)/test/t
13、est.jsp 访问,查看tomcat1的窗口,可以看到打印了一行"=========="
再刷新一次,tomcat2也打印了一条,再刷新,可以看到请求会被tomcat1,tomcat2轮流处理,实现了负载均衡!
第二部分,配置集群
只配置负载均衡还不行,还要session复制,也就是说其中任何一个tomcat的添加的session,是要同步复制到其它tomcat, 集群内的tomcat都有相同的session
1. 修改tomcat1, tomcat2的server.xml
将集群部分配置的在注释符删掉即可.
集群部分的配置如下:(只要把此部分的注释符去掉即可)
14、uster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
managerClassName="org.apache.catalina.cluster.session.DeltaManager"
expireSessionsOnShutdown="false"
useDirtyFlag="true"
notifyListenersOnReplication="true">
15、 16、sName="org.apache.catalina.cluster.tcp.ReplicationListener"
tcpListenAddress="auto"
tcpListenPort="4001"
tcpSelectorTimeout="100"
tcpThreadCount="6"/>
19、 watchEnabled="false"/>
20、mcat负责下一个session到其生命周期结束或网页关闭。这也是一种轮流操作,只不过这种操作是轮流session操作,要想得到这种效果,必须设置jvmRoute(给控制器设置序列),方法如下:
在tomcat的conf中的server.xml文件中修改如下:
21、" %>
<%@ page import="java.util.*" %>
22、request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("Session 列表");
Enumeration e = session.getAttributeNames();
while (e.hasMo 23、reElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+" 26、测试结果
先输入一个session提交,然后不输直接提交,只要可以在后台看到两边的tomcat会都有同一个session的信息显示,那么session复制就成功了!
四、 注意事项
以下针对本公司的upload工程做进一步的注意事项介绍:
1. 配置apache时要注意配置好apache机器的网络地址或域名
2. 为了直接打网址就可以打开工程主页可以把Tomcat中webapps\ROOT文件全部删除后把自己工程目录内的文件复制进ROOT文件夹—就是把tomcat中绑定的upload工程目录下的所有文件和文件夹放进ROOT目录内即可,即把ROOT目录看作是upload工 27、程目录。
把Apache中的htdocs文件夹原来的文件删除掉,然后把自己的工程目录内的静态文件夹以及文件复制进htdocs文件夹即可:
以upload为例,具体目录结构如下所示:
htdocs(相当于eclipse中upload工程的主目录upload)
pages(upload工程目录中的pages文件夹以及此文件夹中所有静态内容)
upload(upload工程目录中的upload文件夹以及此文件夹中所有静态内容)
其次还要进行一项配置:在apache/conf/httpd.conf中修改如下:
28、 dir_module>
DirectoryIndex index.html,192.168.1.112/upload/index.jsp
29、controller
JkMount /*getUploadInfo controller
JkMount /*getAppendUploadInfo controller
JkMount /*getFileInfo controller
JkMount /*insertFileInfo controller
JkMount /*getGroupUploadInfo controller
JkMount /*getGroupAppendUploadInfo controller
JkMount /*insertGroupFileInfo controller
JkMount / 30、updateFileInfo controller
JkMount /*initUid controller
JkMount /*userAction.zip controller
JkMount /*UploadFileNormal controller
4.由于本项目使用了url改写,导致mod_jk.conf中无法识别改写后的页面,
解决方法:把WEB-ROOT下的urlrewrite.xml具体如下修改(以.shtml为后缀)
/user/(.*)/([0-9]+).shtml$
/user/(.*)\.shtml
/group/(.*)\.shtml
为了 31、匹配后缀为.shtml必须修改一些使用过url改写的页面,具体需要修改的页面统计如下:
Tomcat中的jsp页面中:
upload/pages/registerSuccess.jsp
upload/pages/loginsuccess.jsp
upload/pages/space/spacefiles.jsp
upload/pages/index2.jsp
upload/pages/main2.0/navi.jsp(有两层)
以上jsp中均把改写的url地址后面加上后缀.shtml。
Apache中的js文件中:
upload/pages/main2.0/js/navi_c 32、ontrol.js修改uid后加.shtml。
5.图片上传的问题:由于网页上传图片后原先是存储在tomcat中某个文件夹中,而集群配置后会有两个问题,一:图片不应该存放在tomcat中而应该存放在apache中某文件夹中,因为图片是静态内容 二:即使是存放在apache中当tomcat与apache不在同一机器上时上传图片也会很困难。
解决方法:使用socket通信编程,当上传图片读图片时就把图片通过socket传送给apache的服务器中的另外一个tomcat工程ImageServer,此工程会根据配置情况把图片写入apache中固定的存放图片的月份目录中,并且在上传图片同时把图片 33、的存放相对路径存入数据库中,按月份定义图片目录。
注意:
1:在userAction中注意给文件目录加月份
2:由于此tomcat工程ImageServer是使用另外一个tomcat,因此注意此tomcat必须改下端口,比如9080
目前有两处图片上传:
1:个人头像图片上传
2:个人收藏图片上传
五、 优化建议
Tomcat优化方法
第一部分:---线程
Tomcat当线程加到150时服务端就会抛出socket资源用尽的错误,根本没法再往上加,响应的速度也是相当的慢,在server.xml中修改一部分,增加节点数目,可以很好的提高性能:
34、ctor port="8080" maxHttpHeaderSize="8192" maxThreads="150"
minSpareThreads="30" maxSpareThreads="75" enableLookups="false"
redirectPort="8443" acceptCount="100" connectionTimeout="20000"
disableUploadTimeout="true" />
以上为默认配置,适当修改红色字体部分的值,几个参数意义分别为:
maxThreads:Tomcat使用线程来处理接收的每个请求。这个 35、值表示Tomcat可创建的最大的线程数。
acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。
connnectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。
minSpareThreads:Tomcat初始化时创建的线程数。
maxSpareThreads:一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程
第二部分:---内存
Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的 36、需要调大。
Windows下,在文件{tomcat_home}/bin/catalina.bat,第一行加上:
set JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】'
需要把这个两个参数值调大。例如:
set JAVA_OPTS=-Xms256m -Xmx512m
表示初始化内存为256MB,可以使用的最大内存为512MB。
另外相关JVM堆大小的调整,需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关,应该通过分析实际的 37、垃圾收集的时间和频率来调整。如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。调整堆大小的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能,要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。
如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈,那么需要指定代的大小,检查垃圾收集的详细输出,研究垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增 38、加内存,因为分配可以并行进行,而垃圾收集不是并行的。
一般来说设置为256m-512m就可以优化JVM堆。
Apache的优化方法
在apache1.3版本,大家常用mod_gzip对输出内容进行压缩,现在主流的浏览器都支持gzip解压缩。在apache2下,这个模块换名为mod_deflate,对应的模块文件名是mod_deflate.so。下面描述一下在Apache2下如何启用并配置mod_deflate模块。默认安装的Apache不管是Windows还是Linux/Unix,都是不启用该模块的, Linux/Unix下甚至不带该模块,你需要手工编译这个模块。
下面我们分别 39、介绍在Windows操作系统下如何启用并配置mod_deflate模块。
在Windows下采用安装程序安装的Apache服务器已经带有deflate所需要的模块 mod_deflate.so和mod_headers.so,我们只需要在httpd.conf配置文件中启用并进行相关的配置即可,配置如下:
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
# Insert filter
SetOutputFilter DEFLATE
# 40、Netscape 4.x has some problems...
BrowserMatch ^Mozilla/4 gzip-only-text/html
# Netscape 4.06-4.08 have some more problems
BrowserMatch ^Mozilla/4\.0[678] no-gzip
# MSIE masquerades as Netscape, but it is fine
# BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
# NOTE: Due to a bug in mod_sete 41、nvif up to Apache 2.0.48
# the above regex won't work. You can use the following
# workaround to get the desired effect:
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Don't compress images
SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
");%>
<%
out.println("
ID " + session.getId()+"
");
// 如果有新的 Session 属性设置
String dataName =
");
System.out.println( name + " = " + value);
}
%>






