<?xml version="1.0" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="css/rss.xslt"?>
<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>完美生活 - JAVA</title><link>http://blog.hnce.net/</link><description>专注于网站技术与网络营销的博客 - </description><generator>RainbowSoft Studio Z-Blog 1.8 Arwen Build 81206</generator><language>zh-CN</language><copyright>Copyright 2005 - 2009, 完美生活(专注于网站技术与网络营销的博客). Some Rights Reserved. </copyright><pubDate>Thu, 09 Sep 2010 09:30:53 +0800</pubDate><item><title>Apache HTTP Server 与 Tomcat 的三种连接方式介绍</title><author>a@b.com (slick)</author><link>http://blog.hnce.net/post/315.html</link><pubDate>Tue, 23 Jan 2007 10:35:00 +0800</pubDate><guid>http://blog.hnce.net/post/315.html</guid><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 整合 Apache Http Server 和 Tomcat 可以提升对静态文件的处理性能、利用 Web 服务器来做负载均衡以及容错、无缝的升级应用程序。本文介绍了三种整合 Apache 和 Tomcat 的方式。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先我们先介绍一下为什么要让 Apache 与 Tomcat 之间进行连接。事实上 Tomcat 本身已经提供了 HTTP 服务，该服务默认的端口是 8080，装好 tomcat 后通过 8080 端口可以直接使用 Tomcat 所运行的应用程序，你也可以将该端口改为 80。<br/><p>既然 Tomcat 本身已经可以提供这样的服务，我们为什么还要引入 Apache 或者其他的一些专门的 HTTP 服务器呢？原因有下面几个：</p><p>1. 提升对静态文件的处理性能</p><p>2. 利用 Web 服务器来做负载均衡以及容错</p><p>3. 无缝的升级应用程序</p><p>这三点对一个 web 网站来说是非常之重要的，我们希望我们的网站不仅是速度快，而且要稳定，不能因为某个 Tomcat 宕机或者是升级程序导致用户访问不了，而能完成这几个功能的、最好的 HTTP 服务器也就只有 apache 的 http server 了，它跟 tomcat 的结合是最紧密和可靠的。</p><p>接下来我们介绍三种方法将 apache 和 tomcat 整合在一起。</p><p><a name="N1005B"><span class="atitle"><strong>JK</strong></span></a></p><p>这是最常见的方式，你可以在网上找到很多关于配置JK的网页，当然最全的还是其官方所提供的文档。JK 本身有两个版本分别是 1 和 2，目前 1 最新的版本是 1.2.19，而版本 2 早已经废弃了，以后不再有新版本的推出了，所以建议你采用版本 1。</p><p>JK 是通过 AJP 协议与 Tomcat 服务器进行通讯的，Tomcat 默认的 AJP Connector 的端口是 8009。JK 本身提供了一个监控以及管理的页面 jkstatus，通过 jkstatus 可以监控 JK 目前的工作状态以及对到 tomcat 的连接进行设置，如下图所示：</p><br /><br /><a name="N10069"><b>图 1：监控以及管理的页面 jkstatus</b></a><br /><img height="228" alt="图 1：监控以及管理的页面 jkstatus" src="HTTP://blog.hnce.net/UserFiles/Image/20071231041065093.jpg" width="554" border="0" /> <br /><br/><p>在这个图中我们可以看到当前JK配了两个连接分别到 8109 和 8209 端口上，目前 s2 这个连接是停止状态，而 s1 这个连接自上次重启后已经处理了 47 万多个请求，流量达到 6.2 个 G，最大的并发数有 13 等等。我们也可以利用 jkstatus 的管理功能来切换 JK 到不同的 Tomcat 上，例如将 s2 启用，并停用 s1，这个在更新应用程序的时候非常有用，而且整个切换过程对用户来说是透明的，也就达到了无缝升级的目的。关于 JK 的配置文章网上已经非常多了，这里我们不再详细的介绍整个配置过程，但我要讲一下配置的思路，只要明白了配置的思路，JK 就是一个非常灵活的组件。</p><p>JK 的配置最关键的有三个文件，分别是 </p><p><b>httpd.conf </b><br />Apache 服务器的配置文件，用来加载 JK 模块以及指定 JK 配置文件信息</p><p><b>workers.properties</b> <br />到 Tomcat 服务器的连接定义文件</p><p><b>uriworkermap.properties</b> <br />URI 映射文件，用来指定哪些 URL 由 Tomcat 处理，你也可以直接在 httpd.conf 中配置这些 URI，但是独立这些配置的好处是 JK 模块会定期更新该文件的内容，使得我们修改配置的时候无需重新启动 Apache 服务器。</p><p>其中第二、三个配置文件名都可以自定义。下面是一个典型的 httpd.conf 对 JK 的配置</p><br /><br/><table cellspacing="0" cellpadding="0" width="100%" border="0">    <tbody>        <tr>            <td class="code-outline" bgcolor="#cccccc">            <pre class="displaycode"># (httpd.conf)<br/>            # 加载 mod_jk 模块<br/>            LoadModule jk_module modules/mod_jk.so<br/>            #<br/>            # Configure mod_jk<br/>            #<br/>            JkWorkersFile conf/workers.properties<br/>            JkMountFile conf/uriworkermap.properties<br/>            JkLogFile logs/mod_jk.log<br/>            JkLogLevel warn<br/>            </pre>            </td>        </tr>    </tbody></table><br /><br/><p>接下来我们在 Apache 的 conf 目录下新建两个文件分别是 workers.properties、uriworkermap.properties。这两个文件的内容大概如下</p><br /><br/><table cellspacing="0" cellpadding="0" width="100%" border="0">    <tbody>        <tr>            <td class="code-outline" bgcolor="#cccccc">            <pre class="displaycode">#<br/>            # workers.properties<br/>            #<br/>            # list the workers by name<br/>            worker.list=DLOG4J, status<br/>            # localhost server 1<br/>            # ------------------------<br/>            worker.s1.port=8109<br/>            worker.s1.host=localhost<br/>            worker.s1.type=ajp13<br/>            # localhost server 2<br/>            # ------------------------<br/>            worker.s2.port=8209<br/>            worker.s2.host=localhost<br/>            worker.s2.type=ajp13<br/>            worker.s2.stopped=1<br/>            worker.DLOG4J.type=lb<br/>            worker.retries=3<br/>            worker.DLOG4J.balanced_workers=s1, s2<br/>            worker.DLOG4J.sticky_session=1<br/>            worker.status.type=status<br/>            </pre>            </td>        </tr>    </tbody></table><br /><br/><p>以上的 workers.properties 配置就是我们前面那个屏幕抓图的页面所用的配置。首先我们配置了两个类型为 ajp13 的 worker 分别是 s1 和 s2，它们指向同一台服务器上运行在两个不同端口 8109 和 8209 的 Tomcat 上。接下来我们配置了一个类型为 lb（也就是负载均衡的意思）的 worker，它的名字是 DLOG4J，这是一个逻辑的 worker，它用来管理前面配置的两个物理连接 s1 和 s2。最后还配置了一个类型为 status 的 worker，这是用来监控 JK 本身的模块。有了这三个 worker 还不够，我们还需要告诉 JK，哪些 worker 是可用的，所以就有 <b>worker.list = DLOG4J, status</b> 这行配置。</p><p>接下来便是 URI 的映射配置了，我们需要指定哪些链接是由 Tomcat 处理的，哪些是由 Apache 直接处理的，看看下面这个文件你就能明白其中配置的意义</p><br /><br/><table cellspacing="0" cellpadding="0" width="100%" border="0">    <tbody>        <tr>            <td class="code-outline" bgcolor="#cccccc">            <pre class="displaycode">/*=DLOG4J<br/>            /jkstatus=status<br/>            !/*.gif=DLOG4J<br/>            !/*.jpg=DLOG4J<br/>            !/*.png=DLOG4J<br/>            !/*.css=DLOG4J<br/>            !/*.js=DLOG4J<br/>            !/*.htm=DLOG4J<br/>            !/*.html=DLOG4J<br/>            </pre>            </td>        </tr>    </tbody></table><br /><br/><p>相信你已经明白了一大半了：所有的请求都由 DLOG4J 这个 worker 进行处理，但是有几个例外，/jkstatus 请求由 status 这个 worker 处理。另外这个配置中每一行数据前面的感叹号是什么意思呢？感叹号表示接下来的 URI 不要由 JK 进行处理，也就是 Apache 直接处理所有的图片、css 文件、js 文件以及静态 html 文本文件。</p><p>通过对 workers.properties 和 uriworkermap.properties 的配置，可以有各种各样的组合来满足我们前面提出对一个 web 网站的要求。您不妨动手试试！</p><br /><br/><p><a name="N100C7"><span class="atitle"><strong>http_proxy</strong></span></a></p><p>这是利用 Apache 自带的 mod_proxy 模块使用代理技术来连接 Tomcat。在配置之前请确保是否使用的是 2.2.x 版本的 Apache 服务器。因为 2.2.x 版本对这个模块进行了重写，大大的增强了其功能和稳定性。</p><p>http_proxy 模式是基于 HTTP 协议的代理，因此它要求 Tomcat 必须提供 HTTP 服务，也就是说必须启用 Tomcat 的 HTTP Connector。一个最简单的配置如下</p><br /><br /><br/><table cellspacing="0" cellpadding="0" width="100%" border="0">    <tbody>        <tr>            <td class="code-outline" bgcolor="#cccccc">            <pre class="displaycode">ProxyPass /images !<br/>            ProxyPass /css !<br/>            ProxyPass /js !<br/>            ProxyPass / http://localhost:8080/<br/>            </pre>            </td>        </tr>    </tbody></table><br /><br/><p>在这个配置中，我们把所有 http://localhost 的请求代理到 http://localhost:8080/ ，这也就是 Tomcat 的访问地址，除了 images、css、js 几个目录除外。我们同样可以利用 mod_proxy 来做负载均衡，再看看下面这个配置</p><br /><br /><br/><table cellspacing="0" cellpadding="0" width="100%" border="0">    <tbody>        <tr>            <td class="code-outline" bgcolor="#cccccc">            <pre class="displaycode">ProxyPass /images !<br/>            ProxyPass /css !<br/>            ProxyPass /js !<br/>            ProxyPass / balancer://example/<br/>            &lt;Proxy balancer://example/&gt;<br/>            BalancerMember http://server1:8080/<br/>            BalancerMember http://server2:8080/<br/>            BalancerMember http://server3:8080/<br/>            &lt;/Proxy&gt;<br/>            </pre>            </td>        </tr>    </tbody></table><br /><br/><p>配置比 JK 简单多了，而且它也可以通过一个页面来监控集群运行的状态，并做一些简单的维护设置。</p><br /><br /><a name="N100ED"><b>图 2：监控集群运行状态</b></a><br /><img height="427" alt="图 2：监控集群运行状态" src="HTTP://blog.hnce.net/UserFiles/Image/20071231041781926.gif" width="553" border="0" />&nbsp;<br /><br /><br /><br/><p><a name="N100FD"><span class="atitle"><strong>ajp_proxy</strong></span></a></p><p>ajp_proxy 连接方式其实跟 http_proxy 方式一样，都是由 mod_proxy 所提供的功能。配置也是一样，只需要把 http:// 换成 ajp:// ，同时连接的是 Tomcat 的 AJP Connector 所在的端口。上面例子的配置可以改为：</p><br /><br /><br/><table cellspacing="0" cellpadding="0" width="100%" border="0">    <tbody>        <tr>            <td class="code-outline" bgcolor="#cccccc">            <pre class="displaycode">ProxyPass /images !<br/>            ProxyPass /css !<br/>            ProxyPass /js !<br/>            ProxyPass / balancer://example/<br/>            &lt;Proxy balancer://example/&gt;<br/>            BalancerMember ajp://server1:8080/<br/>            BalancerMember ajp://server2:8080/<br/>            BalancerMember ajp://server3:8080/<br/>            &lt;/Proxy&gt;<br/>            </pre>            </td>        </tr>    </tbody></table><br /><br/><p>采用 proxy 的连接方式，需要在 Apache 上加载所需的模块，mod_proxy 相关的模块有 mod_proxy.so、mod_proxy_connect.so、mod_proxy_http.so、mod_proxy_ftp.so、mod_proxy_ajp.so， 其中 mod_proxy_ajp.so 只在 Apache 2.2.x 中才有。如果是采用 http_proxy 方式则需要加载 mod_proxy.so 和 mod_proxy_http.so；如果是 ajp_proxy 则需要加载 mod_proxy.so 和 mod_proxy_ajp.so这两个模块。</p><br /><br /><br/><p><a name="N10112"><span class="atitle"><strong>三者比较</strong></span></a></p><p>相对于 JK 的连接方式，后两种在配置上是比较简单的，灵活性方面也一点都不逊色。但就稳定性而言就不像 JK 这样久经考验，毕竟 Apache 2.2.3 推出的时间并不长，采用这种连接方式的网站还不多，因此，如果是应用于关键的互联网网站，还是建议采用 JK 的连接方式。</p><br /><br/><p><a name="resources"><span class="atitle"><strong>参考资料</strong> </span></a></p><ul>    <li>获得 <a href="http://httpd.apache.org/" target="_blank"><font color="#5c81a7">Apache Http Server</font></a>。 <br /><br /></li>    <li>获得 <a href="http://tomcat.apache.org/" target="_blank"><font color="#5c81a7">Apache Tomcat</font></a>。 <br /><br /></li>    <li><a href="http://tomcat.apache.org/connectors-doc/" target="_blank"><font color="#5c81a7">JK 文档</font></a>。 </li></ul>]]></description><category>JAVA</category><comments>http://blog.hnce.net/post/315.html#comment</comments><wfw:comment>http://blog.hnce.net/</wfw:comment><wfw:commentRss>http://blog.hnce.net/feed.asp?cmt=315</wfw:commentRss><trackback:ping>http://blog.hnce.net/cmd.asp?act=tb&amp;id=315&amp;key=e0e1e1b1</trackback:ping></item><item><title>Tomcat性能优化(2)</title><author>a@b.com (slick)</author><link>http://blog.hnce.net/post/292.html</link><pubDate>Wed, 29 Nov 2006 12:49:00 +0800</pubDate><guid>http://blog.hnce.net/post/292.html</guid><description><![CDATA[<br /><br /><strong>2</strong>.操作系统性能优化<br /><br />这里说的操作系统是指运行web服务器的系统软件，当然，不同的操作系统是为不同的目的而设计的。比如OpenBSD是面向安全的，因此在它的内核中有许多的限制来防止不同形式的服务攻击（OpenBSD的一句座右铭是&ldquo;默认是最安全的&rdquo;）。这些限制或许更多地用来运行活跃的web服务器。<br /><br />而我们常用的Linux操作系统的目标是易用使用，因此它有着更高的限制。使用BSD内核的系统都带有一个名为&ldquo;Generic&rdquo;的内核，表明所有的驱动器都静态地与之相连。这样就使系统易于使用，但是如果你要创建一个自定义的内核来加强其中某些限制，那就需要排除不需要的设备。Linux内核中的许多驱动都是动态地加载的。但是换而言之，内存现在变得越来越便宜，所以因为加载额外的设备驱动就显得不是很重要的。重要的是要有更多的内存，并且在服务器上腾出更多的可用内存。<br /><br /><u>小提示</u>：虽然现在内存已经相当的便宜，但还是尽量不要购买便宜的内存。那些有牌子的内存虽然是贵一点，但是从可靠性上来说，性价比会更高一些。<br /><br />如果是在Windows操作系统上使用Tomcat，那么最好选择服务器版本。因为在非服务器版本上，最终用户授权数或者操作系统本身所能承受的用户数、可用的网络连接数或其它方面的一些方面都是有限制的。并且基于安全性的考虑，必须经常给操作系统打上最新的补丁。<br /><br /><strong>3</strong>.Tomcat与其它web服务器整合使用<br /><br />虽然tomcat也可以作web服务器,但其处理静态html的速度比不上apache,且其作为web服务器的功能远不如apache,因此我们想把 apache和tomcat集成起来，将html与jsp的功能部分进行明确分工，让tomcat只处理jsp部分，其它的由apache,IIS等这些 web服务器处理，由此大大节省了tomcat有限的工作&ldquo;线程&rdquo;。<br /><br /><strong>4</strong>.负载均衡<br /><br />在负载均衡的思路下，多台服务器为对称方式，每台服务器都具有同等的地位，可以单独对外提供服务而无须其他服务器的辅助。通过负载分担技术，将外部发送来的请求按一定规则分配到对称结构中的某一台服务器上，而接收到请求的服务器都独立回应客户机的请求。<br /><br />提供服务的一组服务器组成了一个应用服务器集群(cluster)，并对外提供一个统一的地址。当一个服务请求被发至该集群时，根据一定规则选择一台服务器，并将服务转定向给该服务器承担，即将负载进行均衡分摊。<br /><br />通过应用负载均衡技术，使应用服务超过了一台服务器只能为有限用户提供服务的限制，可以利用多台服务器同时为大量用户提供服务。当某台服务器出现故障时，负载均衡服务器会自动进行检测并停止将服务请求分发至该服务器，而由其他工作正常的服务器继续提供服务，从而保证了服务的可靠性。<br /><br />负载均衡实现的方式大概有四种：第一是通过DNS，但只能实现简单的轮流分配，不能处理故障，第二如果是基于MS IIS，Windows 2003 server本身就带了负载均衡服务，第三是硬件方式，通过交换机的功能或专门的负载均衡设备可以实现，第四种是软件方式，通过一台负载均衡服务器进行，上面安装软件。使用Apache Httpd Server做负载平衡器，Tomcat集群节点使用Tomcat就可以做到以上第四种方式。这种方式比较灵活，成本相对也较低。另外一个很大的优点就是可以根据应用的情况和服务器的情况采取一些策略。&nbsp;&nbsp;]]></description><category>JAVA</category><comments>http://blog.hnce.net/post/292.html#comment</comments><wfw:comment>http://blog.hnce.net/</wfw:comment><wfw:commentRss>http://blog.hnce.net/feed.asp?cmt=292</wfw:commentRss><trackback:ping>http://blog.hnce.net/cmd.asp?act=tb&amp;id=292&amp;key=21f09582</trackback:ping></item><item><title>Tomcat性能调整(1)</title><author>a@b.com (slick)</author><link>http://blog.hnce.net/post/291.html</link><pubDate>Wed, 29 Nov 2006 12:45:00 +0800</pubDate><guid>http://blog.hnce.net/post/291.html</guid><description><![CDATA[<p style="text-indent: 2em;"><strong>一. 引言<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>性能测试与分析是软件开发过程中介于架构和调整的一个广泛并比较不容易理解的领域，更是一项较为复杂的活动。就像下棋游戏一样，有效的性能测试和分析只能在一个良好的计划策略和具备了对不可预料事件的处理能力的条件下顺利地完成。一个下棋高手赢得比赛靠的不仅仅是对游戏规则的认识，更是靠他的自己的能力和不断地专注于分析自己对手的实力来更加有效地利用和发挥规则的作用。同样一个优秀的性能测试和分析人员将要面对的是来自一个全新的应用程序和环境下带来的整个项目的挑战。本文中作者结合自己的使用经验和参考文档，对Tomcat性能方面的调整做一简要的介绍，并给出Tomcat性能的测试、分析和调整优化的一些方法。<br /></p><p style="text-indent: 2em;"><strong>二. 测量Web服务器的性能</strong></p><p style="text-indent: 2em;">测量web服务器的性能是一项让人感到畏缩的任务，但是我们在这里将给出一些需要注意的地方并且指点你了解其中更多的细节性的内容。它不像一些简单的任务，如测量CPU的速率或者是测量程序占用CPU的比例，web服务器的性能优化中包括许调整许多变量来达到目标。许多的测量策略中都包含了一个看似简单的浏览实际上是在向服务器发送大量的请求，我们称之为客户端的程序，来测量响应时间。客户端和服务器端是在同一台机器上吗？服务器在测试的时候还运行着其它的什么程序吗？客户端和服务器端的通讯是通过局域网，100baseT，10baseT还是使用调制解调器？客户端是否一直重复请求相同的页面，还是随机地访问不同的页面？（这些影响到了服务缓存的性能）客户端发送请求的有规律的还是突发的？你是在最终的配置环境下运行服务的还是在调试的配置环境下运行服务的？客户端请求中包含图片还是只有HTML页面？是否有请求是通过servlets和 JSP的，CGI程序，服务端包含（Server-Side Includes ，SSI是一个可以让你使用动态HTML文件的技术）？所有这些都将是我们要关心的，并且几乎我们不可能精确地把所有的问题都清楚地列出来。</p><p style="text-indent: 2em;"><strong>1</strong>.压力测试工具</p><p style="text-indent: 2em;">&ldquo;工欲善其事，必先利其器&rdquo;，压力测试只有借助于一些工具才可得以实施。</p><p style="text-indent: 2em;">大多数web压力测试工具的实现原理都是通过重复的大量的页面请求来模拟多用户对被测系统的并发访问，以此达到产生压力的目的。产生压力的手段都是通过录制或者是编写压力脚本，这些脚本以多个进程或者线程的形式在客户端运行，这样通过人为制造各种类型的压力，我们可以观察被测系统在各种压力状况下的表现，从而定位系统瓶颈，作为系统调优的基础。目前已经存在的性能测试工具林林总总，数量不下一百种，从单一的开放源码的免费小工具如 Aapache 自带的 web 性能测试工具 Apache Benchmark、开源的Jmeter 到大而全的商业性能测试软件如 Mercury 的 LoadRunner 等等。任何性能测试工具都有其优缺点，我们可以根据实际情况挑选用最合适的工具。您可以在这里找到一些web压力测试工具http://www.softwareqatest.com/qatweb1.html#LOAD</p><p style="text-indent: 2em;">这里我们所使用的工具要支持web应用服务认证才可以，要支持接收发送cookies，不仅如此Tomcat支持多种认证方式，比如基本认证、基于表单的认证、相互认证和客户端认证，而一些工具仅仅支持HTTP基本认证。真实地模拟用户认证是性能测试工具的一个重要的部分，因为认证机制将对一个web站点的性能特征产生重要的影响。基于你在产品中使用的不同的认证方式，你需要从上面的工具列表中选择使用这种特性的测试工具。</p><p style="text-indent: 2em;">Apache Benchmark和http_load是命令行形式的工具，非常易于使用。Apache Benchmark可以模仿单独的URL请求并且重复地执行，可以使用不同的命令行参数来控制执行迭代的次数，并发用户数等等。它的一个特点是可以周期性地打印出处理过程的信息，而其它工具只能给出一个全局的报告。</p><p style="text-indent: 2em;"><strong>2</strong>.压力测试工具介绍</p><p style="text-indent: 2em;"><strong>三. 外部环境的调整<br /><br /></strong>　　在 Tomcat和应用程序进行了压力测试后，如果您对应用程序的性能结果不太满意，就可以采取一些性能调整措施了，当然了前提是应用程序没有问题，我们这里只讲Tomcat的调整。由于Tomcat的运行依赖于JVM，所以在这里我们把Tomcat的调整可以分为两类来详细描述：<br /><br />外部环境调整 <br /><br />调整非Tomcat组件，例如Tomcat运行的操作系统和运行Tomcat的java虚拟机。<br /><br />自身调整 <br /><br />修改Tomcat自身的参数，调整Tomcat配置文件中的参数。<br /><br />下面我们将详细讲解外部环境调整的有关内容，Tomcat自身调整的内容将在第2部分中阐述。<br /><br /><strong>1</strong>.JAVA虚拟机性能优化<br /><br />Tomcat本身不能直接在计算机上运行，需要依赖于硬件基础之上的操作系统和一个java虚拟机。您可以选择自己的需要选择不同的操作系统和对应的 JDK的版本（只要是符合Sun发布的Java规范的），但我们推荐您使用Sun公司发布的JDK。确保您所使用的版本是最新的，因为Sun公司和其它一些公司一直在为提高性能而对java虚拟机做一些升级改进。一些报告显示JDK1.4在性能上比JDK1.3提高了将近10%到20%。<br /><br />可以给Java虚拟机设置使用的内存，但是如果你的选择不对的话，虚拟机不会补偿。可通过命令行的方式改变虚拟机使用内存的大小。如下表所示有两个参数用来设置虚拟机使用内存的大小。<br /></p><p style="text-indent: 2em;"><table width="342" cellspacing="1" cellpadding="1" border="1" style="width: 342px; height: 73px;">    <tbody>        <tr>            <td align="center">            <p align="left" style="margin: 0cm 0cm 0pt; text-align: left;" class="MsoNormal"><font size="3"><span style="font-family: 宋体;">参数</span><span lang="EN-US" style="font-family: Arial;"></span></font></p>            </td>            <td align="center">            <p align="left" style="margin: 0cm 0cm 0pt; text-align: left;" class="MsoNormal"><font size="3"><span style="font-family: 宋体;">描述</span><span lang="EN-US" style="font-family: Arial;"></span></font></p>            </td>        </tr>        <tr>            <td align="center">            <p align="left" style="margin: 0cm 0cm 0pt; text-align: left;" class="MsoNormal"><span lang="EN-US" style="font-family: Arial;"><font size="3">-Xms&lt;size&gt;</font></span></p>            </td>            <td align="center">            <p align="left" style="margin: 0cm 0cm 0pt; text-align: left;" class="MsoNormal"><font size="3"><span lang="EN-US" style="font-family: Arial;">JVM</span><span style="font-family: 宋体;">初始化堆的大小</span><span lang="EN-US" style="font-family: Arial;"></span></font></p>            </td>        </tr>        <tr>            <td align="center"><span lang="EN-US" style="font-family: Arial;"><font size="3">            <p align="left" style="margin: 0cm 0cm 0pt; text-align: left;" class="MsoNormal"><span lang="EN-US" style="font-family: Arial;"><font size="3">-Xmx&lt;size&gt;</font></span></p>            </font></span></td>            <td align="center">            <p align="left" style="margin: 0cm 0cm 0pt; text-align: left;" class="MsoNormal"><font size="3"><span lang="EN-US" style="font-family: Arial;">JVM</span><span style="font-family: 宋体;">堆的最大值</span><span lang="EN-US" style="font-family: Arial;"></span></font></p>            </td>        </tr>    </tbody></table><br /><br />这两个值的大小一般根据需要进行设置。初始化堆的大小执行了虚拟机在启动时向系统申请的内存的大小。一般而言，这个参数不重要。但是有的应用程序在大负载的情况下会急剧地占用更多的内存，此时这个参数就是显得非常重要，如果虚拟机启动时设置使用的内存比较小而在这种情况下有许多对象进行初始化，虚拟机就必须重复地增加内存来满足使用。由于这种原因，我们一般把-Xms和-Xmx设为一样大，而堆的最大值受限于系统使用的物理内存。一般使用数据量较大的应用程序会使用持久对象，内存使用有可能迅速地增长。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出，并且导致应用服务崩溃。因此一般建议堆的最大值设置为可用内存的最大值的80%。<br /><br />Tomcat默认可以使用的内存为128MB，在较大型的应用项目中，这点内存是不够的，需要调大。<br /><br />Windows下，在文件{tomcat_home}/bin/catalina.bat，Unix下，在文件{tomcat_home}/bin/catalina.sh的前面，增加如下设置：<br /><br />JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】'<br /><br />需要把这个两个参数值调大。例如：<br /><br />JAVA_OPTS='-Xms256m -Xmx512m'<br /><br />表示初始化内存为256MB，可以使用的最大内存为512MB。<br /><br />另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关，应该通过分析实际的垃圾收集的时间和频率来调整。如果堆的大小很大，那么完全垃圾收集就会很慢，但是频度会降低。如果你把堆的大小和内存的需要一致，完全收集就很快，但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间，以在特定的时间内最大化处理客户的请求。在基准测试的时候，为保证最好的性能，要把堆的大小设大，保证垃圾收集不在整个基准测试的过程中出现。<br /><br />如果系统花费很多的时间收集垃圾，请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈，那么需要指定代的大小，检查垃圾收集的详细输出，研究垃圾收集参数对性能的影响。一般说来，你应该使用物理内存的 80% 作为堆大小。当增加处理器时，记得增加内存，因为分配可以并行进行，而垃圾收集不是并行的。</p>]]></description><category>JAVA</category><comments>http://blog.hnce.net/post/291.html#comment</comments><wfw:comment>http://blog.hnce.net/</wfw:comment><wfw:commentRss>http://blog.hnce.net/feed.asp?cmt=291</wfw:commentRss><trackback:ping>http://blog.hnce.net/cmd.asp?act=tb&amp;id=291&amp;key=aca1ef2a</trackback:ping></item><item><title>TOMCat 5.5.9+Mysql5.0.15中的数据源配置</title><author>a@b.com (slick)</author><link>http://blog.hnce.net/post/252.html</link><pubDate>Thu, 18 May 2006 00:37:00 +0800</pubDate><guid>http://blog.hnce.net/post/252.html</guid><description><![CDATA[<p><br /><br />1.现在%tomcat home%/conf/catalina/localhost 下面添加一段独立的context xml段,命名为MyWebProject.xml,例如</p><p>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br />&lt;Context path=&quot;/MyWebProject&quot; docBase=&quot;MyWebProject&quot; debug=&quot;1&quot; reloadable=&quot;true&quot; crossContext=&quot;true&quot;&gt; <br />&lt;/Context&gt;</p><p>2.通过admin的界面(或手动在server.xml界面里进行配置)数据源,以mysql5.0.15为例,配置后的server.xml,只添加全局资源就可以了</p><p>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br />&lt;Server&gt;<br />&nbsp; &lt;Listener className=&quot;org.apache.catalina.mbeans.GlobalResourcesLifecycleListener&quot;/&gt;<br />&nbsp; &lt;Listener className=&quot;org.apache.catalina.storeconfig.StoreConfigLifecycleListener&quot;/&gt;<br />&nbsp; &lt;Listener className=&quot;org.apache.catalina.mbeans.ServerLifecycleListener&quot;/&gt;<br />&nbsp; &lt;GlobalNamingResources&gt;</p><p>&nbsp;&nbsp;&nbsp; &lt;!-- Test entry for demonstration purposes --&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Environment name=&quot;simpleValue&quot; type=&quot;java.lang.Integer&quot; value=&quot;30&quot;/&gt;</p><p>&nbsp;&nbsp;&nbsp; &lt;!-- Editable user database that can also be used by<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UserDatabaseRealm to authenticate users --&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Resource name=&quot;UserDatabase&quot; auth=&quot;Container&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type=&quot;org.apache.catalina.UserDatabase&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description=&quot;User database that can be updated and saved&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; factory=&quot;org.apache.catalina.users.MemoryUserDatabaseFactory&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pathname=&quot;conf/tomcat-users.xml&quot; /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Resource<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name=&quot;mysql/test&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type=&quot;javax.sql.DataSource&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; password=&quot;123456&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driverClassName=&quot;com.mysql.jdbc.Driver&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxIdle=&quot;2&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxWait=&quot;5000&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; username=&quot;root&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url=&quot;jdbc:mysql://localhost:3306/test&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxActive=&quot;20&quot;/&gt;<br />&nbsp; &lt;/GlobalNamingResources&gt;&nbsp; </p><p>&lt;Service<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name=&quot;Catalina&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Connector<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port=&quot;80&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; redirectPort=&quot;8443&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minSpareThreads=&quot;25&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connectionTimeout=&quot;20000&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxSpareThreads=&quot;75&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxThreads=&quot;150&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxHttpHeaderSize=&quot;8192&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Connector&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Connector<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; port=&quot;8009&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; redirectPort=&quot;8443&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protocol=&quot;AJP/1.3&quot;&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Connector&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Engine<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defaultHost=&quot;localhost&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name=&quot;Catalina&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Realm className=&quot;org.apache.catalina.realm.UserDatabaseRealm&quot;/&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Host<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; appBase=&quot;webapps&quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name=&quot;localhost&quot;&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/Host&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/Engine&gt;<br />&nbsp; &lt;/Service&gt;<br />&lt;/Server&gt;</p><p>3.在conf下面的context.xml文件中,&lt;/Context&gt;之前加入</p><p>&nbsp; &lt;ResourceLink name=&quot;mysql/test&quot; global=&quot;mysql/test&quot; type=&quot;javax.sql.DataSourcer&quot;/&gt;</p><p><br />4.在你的web文件夹下面的WEB-INF中找到web.xml,在最后&lt;/web-app&gt;之前加入</p><p>&lt;resource-ref&gt;<br />&nbsp;&nbsp;&nbsp; &lt;description&gt;mysqlDB Connection&lt;/description&gt;<br />&nbsp;&nbsp;&nbsp; &lt;res-ref-name&gt;mysql/test&lt;/res-ref-name&gt;<br />&nbsp;&nbsp;&nbsp; &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />&nbsp;&nbsp;&nbsp; &lt;res-auth&gt;Container&lt;/res-auth&gt;<br />&lt;/resource-ref&gt;</p><p>5:测试页面:testDataSource.jsp</p><p>&lt;%@ page contentType=&quot;text/html;charset=gb2312&quot; %&gt;<br />&lt;%@ page import=&quot;java.sql.*&quot;%&gt;<br />&lt;%@ page import=&quot;javax.sql.*&quot;%&gt;<br />&lt;%@ page import=&quot;javax.naming.*&quot;%&gt;<br />&lt;%@ page session=&quot;false&quot; %&gt;<br />&lt;html&gt;<br />&lt;head&gt;<br />&lt;title&gt;&lt;/title&gt;<br />&lt;% <br />&nbsp;&nbsp; out.print(&quot;我的测试开始&quot;+&quot;&lt;br/&gt;&quot;);<br />&nbsp;&nbsp; DataSource ds = null;<br />&nbsp;&nbsp; try{<br />&nbsp;&nbsp; InitialContext ctx=new InitialContext();<br />&nbsp;&nbsp; ds=(DataSource)ctx.lookup(&quot;java:comp/env/dhzMySql&quot;);<br />&nbsp;&nbsp; Connection conn = ds.getConnection();<br />&nbsp;&nbsp; Statement stmt = conn.createStatement();<br />&nbsp;&nbsp; String strSql = &quot; select * from tabur&quot;;<br />&nbsp;&nbsp; ResultSet rs = stmt.executeQuery(strSql);<br />&nbsp;&nbsp; while(rs.next()){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.print(rs.getString(1)+&quot;&lt;br/&gt;&quot;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp; }<br />&nbsp;&nbsp; rs.close();<br />&nbsp;&nbsp; stmt.close();<br />&nbsp;&nbsp; conn.close();<br />&nbsp;out.print(&quot;我的测试结束&quot;);</p><p>&nbsp;&nbsp; }</p><p>&nbsp;&nbsp; catch(Exception ex){</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.print(&quot;出现例外，信息是:&quot;+ex.getMessage());</p><p>&nbsp;&nbsp;&nbsp; ex.printStackTrace();</p><p>&nbsp;&nbsp; }</p><p>%&gt;</p><p>&lt;/head&gt;</p><p>&lt;body&gt;</p><p>&lt;/body&gt;</p><p>&lt;/html&gt;</p>]]></description><category>JAVA</category><comments>http://blog.hnce.net/post/252.html#comment</comments><wfw:comment>http://blog.hnce.net/</wfw:comment><wfw:commentRss>http://blog.hnce.net/feed.asp?cmt=252</wfw:commentRss><trackback:ping>http://blog.hnce.net/cmd.asp?act=tb&amp;id=252&amp;key=33ff7e6c</trackback:ping></item><item><title>JAVA 面试基础试题</title><author>a@b.com (slick)</author><link>http://blog.hnce.net/post/208.html</link><pubDate>Mon, 16 Jan 2006 13:54:00 +0800</pubDate><guid>http://blog.hnce.net/post/208.html</guid><description><![CDATA[<p>　　找工作要面试，有面试就有对付面试的办法。以下一些题目来自我和我朋友痛苦的面试经历，提这些问题的公司包括IBM, E*Trade, Siebel, Motorola, SUN, 以及其它大小公司。<br /><br />　　面试是没什么道理可讲的，它的题目有的不合情理、脱离实际。有在纸上写的，有当面考你的，也有在电话里问的，给你IDE的估计很少(否则你赶快去买彩票， 说不定中)。所以如果你看完此文后，请不要抱怨说这些问题都能用IDE来解决。你必须在任何情况下准确回答这些问题，在面试中如果出现一两题回答不准确很 有可能你就被拒之门外了。</p><p>　　当然这些都是Java的基本题，那些面试的人大多数不会问你Hibernate有多先进，Eclipse的三个组成部分，或command design pattern，他们都是老一辈了，最喜欢问的就是基础知识。别小看了这些基础，我朋友水平一流，结果就栽在一到基础知识的问题下，和高薪无缘。</p><p>　　好了废话少说，开始正题。</p><p>　　第一，谈谈final, finally, finalize的区别。<br />最常被问到。</p><p>　　第二，Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类，是否可以implements(实现)interface(接口)?</p><p>　　第三，Static Nested Class 和 Inner Class的不同，说得越多越好(面试题有的很笼统)。</p><p>　　第四，&amp;和&amp;&amp;的区别。<br />这个问得很少。</p><p>　　第五，HashMap和Hashtable的区别。<br />常问。</p><p>　　第六，Collection 和 Collections的区别。<br />你千万别说一个是单数一个是复数。</p><p>　　第七，什么时候用assert。<br />API级的技术人员有可能会问这个。</p><p>　　第八，GC是什么? 为什么要有GC? <br />基础。</p><p>　　第九，String s = new String(&quot;xyz&quot;);创建了几个String Object?</p><p>　　第十，Math.round(11.5)等於多少? Math.round(-11.5)等於多少?</p><p>　　第十一，short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错?<br />面试题都是很变态的，要做好受虐的准备。</p><p>　　第十二，sleep() 和 wait() 有什么区别?<br />搞线程的最爱。</p><p>　　第十三，Java有没有goto?<br />很十三的问题，如果哪个面试的问到这个问题，我劝你还是别进这家公司。</p><p>　　第十四，数组有没有length()这个方法? String有没有length()这个方法?</p><p>　　第十五，Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型?<br />常问。</p><p>　　第十六，Set里的元素是不能重复的，那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?</p><p>　　第十七，给我一个你最常见到的runtime exception。<br />如果你这个答不出来，面试的人会认为你没有实际编程经验。</p><p>　　第十八，error和exception有什么区别?</p><p>　　第十九，List, Set, Map是否继承自Collection接口?</p><p>　　第二十，abstract class和interface有什么区别?<br />常问。</p><p>　　第二十一，abstract的method是否可同时是static,是否可同时是native，是否可同时是synchronized?</p><p>　　第二十二，接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)?</p><p>　　第二十三，启动一个线程是用run()还是start()?</p><p>　　第二十四，构造器Constructor是否可被override?</p><p>　　第二十五，是否可以继承String类?</p><p>　　第二十六，当一个线程进入一个对象的一个synchronized方法后，其它线程是否可进入此对象的其它方法?</p><p>　　第二十七，try {}里有一个return语句，那么紧跟在这个try后的finally {}里的code会不会被执行，什么时候被执行，在return前还是后?</p><p>　　第二十八，编程题: 用最有效率的方法算出2乘以8等於几?<br />有C背景的程序员特别喜欢问这种问题。</p><p>　　第二十九，两个对象值相同(x.equals(y) == true)，但却可有不同的hash code，这句话对不对?</p><p>　　第三十，当一个对象被当作参数传递到一个方法后，此方法可改变这个对象的属性，并可返回变化后的结果，那么这里到底是值传递还是引用传递?</p><p>　　第三十一，swtich是否能作用在byte上，是否能作用在long上，是否能作用在String上?</p><p>　　第三十二，编程题: 写一个Singleton出来。</p>]]></description><category>JAVA</category><comments>http://blog.hnce.net/post/208.html#comment</comments><wfw:comment>http://blog.hnce.net/</wfw:comment><wfw:commentRss>http://blog.hnce.net/feed.asp?cmt=208</wfw:commentRss><trackback:ping>http://blog.hnce.net/cmd.asp?act=tb&amp;id=208&amp;key=9e9e5eb3</trackback:ping></item></channel></rss>
