﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-ipanda-文章分类-java方面</title><link>http://www.blogjava.net/ipanda/category/11136.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 02:44:26 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 02:44:26 GMT</pubDate><ttl>60</ttl><item><title>apache+tomcat+mysql 负载平衡和集群</title><link>http://www.blogjava.net/ipanda/articles/46221.html</link><dc:creator>傻傻猫的博客</dc:creator><author>傻傻猫的博客</author><pubDate>Mon, 15 May 2006 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/ipanda/articles/46221.html</guid><wfw:comment>http://www.blogjava.net/ipanda/comments/46221.html</wfw:comment><comments>http://www.blogjava.net/ipanda/articles/46221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ipanda/comments/commentRss/46221.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ipanda/services/trackbacks/46221.html</trackback:ping><description><![CDATA[
		<table class="fixedTable blogpost" cellspacing="0" width="100%" border="0">
				<tbody>
						<tr>
								<td id="msgcns!1peMxEO2X2a8AOxim43yhQiw!109">
										<div>
												<div>前言：<br />公司开发了一个网站，估计最高在线人数是3万，并发人数最多100人。开发的网站是否能否承受这个压力，如何确保网站的负荷没有问题，经过研究决定如下：<br />（1） 采用负载平衡和集群技术，初步机构采用Apache+Tomcat的机群技术。<br />（2） 采用压力测试工具，测试压力。工具是Loadrunner。<br />硬件环境搭建：<br />为了能够进行压力测试，需要搭建一个环境。刚开始时，测试在公司局域网内进行，但很快发现了一个问题，即一个脚本的压力测试结果每次都不一样，并且差别很大。原来是受公司网络的影响，于是决定搭建一个完全隔离的局域网测试。搭建后的局域网配置如下：<br />（1） 网络速度：100M<br />（2） 三台服务器：<br />负载服务器 ：操作系统windows2003，<br />Tomcat服务器：操作系统windows2000 Professional<br />数据库服务器：操作系统windows2000 Professional<br />三台机器的cpu 2.4 G, 内存 1G。<br />软件环境搭建：<br />软件的版本如下：<br />Apache 版本：2.054，<br />Tomcat5.0.30,<br />mysql ：4.1.14.<br />JDK1.5<br />压力测试工具：Loadrunner7.8。 
<p><br />负载平衡方案如下：<br />一台机器（操作系统2003）安装apache，作为负载服务器，并安装tomcat作为一个worker；一个单独安装tomcat，作为第二个worker；剩下的一台单独作为数据库服务器。<br />Apache和tomcat的负载平衡采用JK1.2.14（没有采用2.0，主要是2.0不再维护了）。<br />集群方案：<br />采用Tomcat本身的集群方案。在server.xml配置。<br />压力测试问题：<br />压力测试后，发现了一些问题，现一一列出来：<br />（1） 采用Tocmat集群后，速度变得很慢。因为集群后，要进行session复制，导致速度较慢。Tomcatd的复制，目前不支持application复制。复制的作用，主要用来容错的，即一台机器有故障后，apache可以把请求自动转发到另外一个机器。在容错和速度的考虑上，我们最终选择速度，去掉了Tomcat集群。<br />（2） 操作系统最大并发用户的限制：<br />为了采用网站的压力，我们开始的时候，仅测试Tomcat的最大负载数。Tomcat服务器安装的操作系统是windows2000 Professional。当我们用压力测试工具，并发测试时，发现只要超过15个并发用户，会经常出现无法连接服务器的情况。经过研究，发现是操作系统的问题：windows2000 Professional 支持的并发访问用户有限，默认的好像是15个。于是我们把操作系统全部采用windows2003 server版本。<br />（3） 数据库连接池的问题：<br />测试数据库连接性能时，发现数据库连接速度很慢。每增加一些用户，连接性能就差了很多。我们采用的数据库连接池是DBCP，默认的初始化为50个，应该不会很慢吧。查询数据库的连接数，发现初始化，只初始化一个连接。并发增加一个用户时，程序就会重新创建一个连接，导致连接很慢。原因就在这里了。如何解决呢？偶尔在JDK1.4下的Tomcat5.0.30下执行数据库连接压力测试，发现速度很快，程序创建数据库连接的速度也是很快的。看来JDK1.5的JDBC驱动程序有问题。于是我们修改 JDK的版本为1.4.</p><p>（4） C3P0和DBCP<br />C3P0是Hibernate3.0默认的自带数据库连接池，DBCP是Apache开发的数据库连接池。我们对这两种连接池进行压力测试对比，发现在并发300个用户以下时，DBCP比C3P0平均时间快1秒左右。但在并发400个用户时，两者差不多。</p><p>速度上虽然DBCP比C3P0快些，但是有BUG：当DBCP建立的数据库连接，因为某种原因断掉后，DBCP将不会再重新创建新的连接，导致必须重新启动Tomcat才能解决问题。DBCP的BUG使我们决定采用C3P0作为数据库连接池。<br />调整后的方案：<br />操作系统Windows2003 server版本<br />JDK1.4<br />Tomcat 5.0.30<br />数据库连接池C3P0<br />仅采用负载平衡，不采用集群。<br />软件的配置：<br />Apache配置：主要配置httpd.conf和新增加的文件workers.properties<br />Httpd.conf：<br />#一个连接的最大请求数量<br />MaxKeepAliveRequests 10000 <br />#NT环境，只能配置这个参数来提供性能<br />&lt;IfModule mpm_winnt.c&gt; <br />#每个进程的线程数，最大1920。NT只启动父子两个进程，不能设置启动多个进程<br />ThreadsPerChild 1900 <br />每个子进程能够处理的最大请求数<br />MaxRequestsPerChild 10000<br />&lt;/IfModule&gt;</p><p># 加载mod_jk<br />#<br />LoadModule jk_module modules/mod_jk.so<br />#<br /># 配置mod_jk<br />#<br />JkWorkersFile conf/workers.properties<br />JkLogFile logs/mod_jk.log<br />JkLogLevel info<br />#请求分发，对jsp文件，.do等动态请求交由tomcat处理<br />DocumentRoot "C:/Apache/htdocs"<br />JkMount /*.jsp loadbalancer<br />JkMount /*.do loadbalancer<br />JkMount /servlet/* loadbalancer<br />#关掉主机Lookup，如果为on，很影响性能，可以有10多秒钟的延迟。<br />HostnameLookups Off<br />#缓存配置<br />LoadModule cache_module modules/mod_cache.so<br />LoadModule disk_cache_module modules/mod_disk_cache.so<br />LoadModule mem_cache_module modules/mod_mem_cache.so</p><p>&lt;IfModule mod_cache.c&gt;<br />CacheForceCompletion 100<br />CacheDefaultExpire 3600<br />CacheMaxExpire 86400<br />CacheLastModifiedFactor 0.1<br /><br />&lt;IfModule mod_disk_cache.c&gt;<br />CacheEnable disk /<br />CacheRoot c:/cacheroot<br />CacheSize 327680<br />CacheDirLength 4<br />CacheDirLevels 5<br />CacheGcInterval 4<br />&lt;/IfModule&gt;<br />&lt;IfModule mod_mem_cache.c&gt;<br />CacheEnable mem /<br />MCacheSize 8192<br />MCacheMaxObjectCount 10000<br />MCacheMinObjectSize 1<br />MCacheMaxObjectSize 51200<br />&lt;/IfModule&gt;<br />&lt;/IfModule&gt;<br />worker. Properties文件<br />#<br /># workers.properties ，可以参考<br /><a href="http://jakarta.apache.org/tomcat/connectors-doc/config/workers.html">http://jakarta.apache.org/tomcat/connectors-doc/config/workers.html</a><br /># In Unix, we use forward slashes:<br />ps=</p><p># list the workers by name</p><p>worker.list=tomcat1, tomcat2, loadbalancer</p><p># ------------------------<br /># First tomcat server<br /># ------------------------<br />worker.tomcat1.port=8009<br />worker.tomcat1.host=localhost<br />worker.tomcat1.type=ajp13</p><p># Specify the size of the open connection cache.<br />#worker.tomcat1.cachesize</p><p>#<br /># Specifies the load balance factor when used with<br /># a load balancing worker.<br /># Note:<br /># ----&gt; lbfactor must be &gt; 0<br /># ----&gt; Low lbfactor means less work done by the worker.<br />worker.tomcat1.lbfactor=900</p><p># ------------------------<br /># Second tomcat server<br /># ------------------------<br />worker.tomcat1.port=8009<br />worker.tomcat1.host=202.88.8.101<br />worker.tomcat1.type=ajp13</p><p># Specify the size of the open connection cache.<br />#worker.tomcat1.cachesize</p><p>#<br /># Specifies the load balance factor when used with<br /># a load balancing worker.<br /># Note:<br /># ----&gt; lbfactor must be &gt; 0<br /># ----&gt; Low lbfactor means less work done by the worker.<br />worker.tomcat1.lbfactor=2000</p><p># ------------------------<br /># Load Balancer worker<br /># ------------------------</p><p>#<br /># The loadbalancer (type lb) worker performs weighted round-robin<br /># load balancing with sticky sessions.<br /># Note:<br /># ----&gt; If a worker dies, the load balancer will check its state<br /># once in a while. Until then all work is redirected to peer<br /># worker.<br />worker.loadbalancer.type=lb<br />worker.loadbalancer.balanced_workers=tomcat1,tomcat2</p><p>#<br /># END workers.properties<br />#</p><p>Tomcat1配置:<br />&lt;!--配置server.xml<br />去掉8080端口，即注释掉如下代码：--&gt;<br />&lt;Connector <br />port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"<br />enableLookups="false" redirectPort="8443" acceptCount="100"<br />debug="0" connectionTimeout="20000" <br />disableUploadTimeout="true" /&gt;</p><p>&lt;!--配置8009端口如下：--&gt;<br />&lt;Connector port="8009" <br />maxThreads="500" minSpareThreads="400" maxSpareThreads="450"<br />enableLookups="false" redirectPort="8443" debug="0"<br />protocol="AJP/1.3" /&gt;<br />&lt;!--配置引擎--&gt; <br />&lt;Engine name="Catalina" defaultHost="localhost" debug="0" jvmRoute="tomcat1"&gt;</p><p>启动内存配置,开发configure tomcat程序即可配置：<br />Initial memory pool: 200 M<br />Maxinum memory pool:300M<br />Tomcat2配置：<br />配置和tomcat1差不多，需要改动的地方如下：<br />&lt;!--配置引擎--&gt; <br />&lt;Engine name="Catalina" defaultHost="localhost" debug="0" jvmRoute="tomcat2"&gt;</p><p>启动内存配置,开发configure tomcat程序即可配置：<br />Initial memory pool: 512 M<br />Maxinum memory pool:768M<br />Mysql配置：<br />Server类型：Dedicated MySQL Server Machine <br />Database usage:Transational Database Only<br />并发连接数量：Online Transaction Processing(OLTP)<br />字符集：UTF8<br />数据库连接池的配置：<br />我们采用的是spring 框架，配置如下：<br />&lt;property name="hibernateProperties"&gt;<br />&lt;props&gt;<br />&lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;<br />&lt;prop key="hibernate.connection.driver_class"&gt;com.mysql.jdbc.Driver&lt;/prop&gt;<br />&lt;prop key="hibernate.connection.url"&gt;jdbc:mysql://202.88.1.103/db&lt;/prop&gt; <br />&lt;prop key="hibernate.connection.username"&gt;sa&lt;/prop&gt;<br />&lt;prop key="hibernate.connection.password"&gt;&lt;/prop&gt;</p><p>&lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;<br />&lt;prop key="hibernate.use_sql_comments"&gt;false&lt;/prop&gt;</p><p>&lt;prop key="hibernate.cglib.use_reflection_optimizer"&gt;true&lt;/prop&gt;<br />&lt;prop key="hibernate.max_fetch_depth"&gt;2&lt;/prop&gt;</p><p>&lt;prop key="hibernate.c3p0.max_size"&gt;200&lt;/prop&gt;<br />&lt;prop key="hibernate.c3p0.min_size"&gt;5&lt;/prop&gt;<br />&lt;prop key="hibernate.c3p0.timeout"&gt;12000&lt;/prop&gt;<br />&lt;prop key="hibernate.c3p0.max_statements"&gt;50&lt;/prop&gt;<br />&lt;prop key="hibernate.c3p0.acquire_increment"&gt;1&lt;/prop&gt; <br />&lt;/props&gt;<br />&lt;/property&gt;<br />其他的没有额外配置。<br />LoadRunner 常见问题：<br />（1）sofeware caused connction：这种情况，一般是脚本有问题，或者loadrunner有问题。解决方法：重新启动机器，或者重新录制脚本，估计是loadrunner的bug。<br />（2）cannot connect to server:无法连接到服务器。这种情况是服务器的配置有问题，服务器无法承受过多的并发连接了。需要优化服务器的配置，<br />如操作系统采用windows 2003 server，<br />优化tomcat配置：maxThreads="500" minSpareThreads="400" maxSpareThreads="450"。但是tomcat 最多支持500个并发访问<br />优化apache配置：<br />ThreadsPerChild 1900 <br />MaxRequestsPerChild 10000<br />其他的错误如：<br />Action.c(10): Error -27791: Server has shut down the connection prematurely<br />HTTP Status-Code=503 (Service Temporarily Unavailable)<br />一般都是由于服务器配置不够好引起的，按照问题（2）处理，如果仍旧不行，需要优化硬件和调整程序了。<br />Apache问题：<br />（1） File does not exist: C:/Apache/htdocs/favicon.ico：<br />这个问题是apache，htdocs目录没有favicon.ico文件引起的，该文件是网站的图标，仅在firefox,myIE等浏览器出现。<br />（2） 图片无法显示：<br />配置apache后，却无法显示图片。<br />解决方法：把程序的图片，按照程序结构copy到apache的htdocs目录下。<br />（3） 无法处理请求：<br />当我们输入 ***.do 命令后，apache确返回错误信息，而连接tomcat却没有问题。原因是没有把.do命令转发给tomcat处理。解决方法如下：<br />在apache配置文件中配置如下内容：<br />DocumentRoot "C:/Apache/htdocs"<br />JkMount /*.jsp loadbalancer<br />JkMount /*.do loadbalancer</p><p><br />总结：<br />网站的压力测试，涉及的知识面挺广的，不仅要熟悉压力测试工具，还要知道如何配置和优化应用服务器和数据库，并且需要知道如何优化网络、操作系统、硬件系统。<br />测试中不仅要善于发现问题，要知道如何解决。最重要的一点，要有良好的测试方法。刚开始测试时，可以从最简单的测试脚本入手，不需要太复杂的脚本，这样便于发现问题。如我们刚开始时，就从一个简单的下载登陆界面的脚本入手，测试一个tomcat的压力负载。一个简单的获取登陆的脚本，帮助我们优化了tomcat的配置；后来再测试数据库连接，也是一个简单的数据库连接脚本，帮助我们优化了数据库连接池；然后利用这些简单的脚本，测试apache的负载平衡，优化了apache配置。最后运行复杂的脚本，模拟多种角色的用户在不同时间下的处理，以测试网站压力负载。</p></div>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/ipanda/aggbug/46221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ipanda/" target="_blank">傻傻猫的博客</a> 2006-05-15 15:21 <a href="http://www.blogjava.net/ipanda/articles/46221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>