<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>龙浩的blog</title>
	<atom:link href="http://www.longtask.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.longtask.com/blog</link>
	<description>用技术创造价值，用艺术塑造自我！</description>
	<lastBuildDate>Fri, 20 Apr 2012 10:26:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Jetty8.0.4的ClassLoader的体系结构</title>
		<link>http://www.longtask.com/blog/?p=755</link>
		<comments>http://www.longtask.com/blog/?p=755#comments</comments>
		<pubDate>Fri, 20 Apr 2012 10:19:31 +0000</pubDate>
		<dc:creator>longhao</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.longtask.com/blog/?p=755</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160;1：JDK的ClassLoader基础 

Bootstrap ClassLoader/启动类加载器&#160;
主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。
Extension ClassLoader/扩展类加载器&#160;
主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。
System ClassLoader/系统类加载器&#160;
主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。
User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)&#160;
在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。
&#160;
自User Custom向Bootstrap的检查类是否已经加载；自Bootstrap向User Custom的尝试加载类


&#160;//检查类是否被装载过
&#160; &#160; &#160; Class c = findLoadedClass(name);
&#160; &#160; &#160; //指定类未被装载过，自顶部向下的尝试加载类
&#160;&#160;&#160;&#160;&#160;&#160;if&#160;(c ==&#160;null) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;try&#160;{

&#160; &#160; &#160; &#160; &#160; &#160; //如果父类加载器不为空，指定为父类加载器加载
				&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if&#160;(parent&#160;!=&#160;null) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; c =&#160;parent.loadClass(name,&#160;false);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}&#160;else&#160;{
&#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; //在父类加载器为空的情况下，指定为系统启动类加载（native），不存在则返回null
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; c = findBootstrapClassOrNull(name);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }&#160;catch&#160;(ClassNotFoundException e) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// ClassNotFoundException thrown if  <a href="http://www.longtask.com/blog/?p=755" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp;1：JDK的ClassLoader基础 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p><strong>Bootstrap ClassLoader/启动类加载器&nbsp;</strong></p>
<p>主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。</p>
<p><strong>Extension ClassLoader/扩展类加载器&nbsp;</strong></p>
<p>主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。</p>
<p><strong>System ClassLoader/系统类加载器&nbsp;</strong></p>
<p>主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。</p>
<p><strong>User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类)&nbsp;</strong></p>
<p>在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。</p>
<p>&nbsp;</p>
<p><strong>自User Custom向Bootstrap的检查类是否已经加载；自Bootstrap向User Custom的尝试加载类</strong></p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">
<div>
<div><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Tahoma; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><font face="Tahoma, Helvetica, Arial, 宋体, sans-serif"><span style="line-height: 20px;">&nbsp;//检查类是否被装载过</span></font></span></div>
<div align="left" style="line-height: 20px;"><font face="Tahoma, Helvetica, Arial, 宋体, sans-serif"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp; &nbsp; &nbsp; Class c = findLoadedClass(name);</span></font></font></div>
<div align="left" style="line-height: 20px;"><font face="Tahoma, Helvetica, Arial, 宋体, sans-serif"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp; &nbsp; &nbsp; //指定类未被装载过，自顶部向下的尝试加载类</span></font></font></div>
<div align="left" style="line-height: 20px;"><font face="Tahoma, Helvetica, Arial, 宋体, sans-serif"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>if</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">(c ==</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>null</b></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">) {</span></font></font></div>
<div align="left" style="line-height: 20px;"><font face="Tahoma, Helvetica, Arial, 宋体, sans-serif"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>try</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">{</span></font></font></div>
<div align="left" style="line-height: 20px;">
<div><font face="Tahoma, Helvetica, Arial, 宋体, sans-serif"><font face="Courier New" size="2"><span style="font-size: 10pt;"><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Tahoma; line-height: normal; text-align: -webkit-auto; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "><span style="font-family: 'Courier New'; font-size: 13px; line-height: 20px; text-align: -webkit-left;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //如果父类加载器不为空，指定为父类加载器加载</span></span></span></font></font></div>
<p>				<font face="Tahoma, Helvetica, Arial, 宋体, sans-serif">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>if</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">(</span></font><font color="#0000C0" face="Courier New" size="2"><span style="font-size: 10pt;">parent</span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">!=</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>null</b></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">) {</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c =</span></font>&nbsp;<font color="#0000C0" face="Courier New" size="2"><span style="font-size: 10pt;">parent</span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">.loadClass(name,</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>false</b></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">);</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>else</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">{</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //在父类加载器为空的情况下，指定为系统启动类加载（native），不存在则返回null</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = findBootstrapClassOrNull(name);</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>catch</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">(ClassNotFoundException e) {</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font>&nbsp;<font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// ClassNotFoundException thrown if class not found</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font>&nbsp;<font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// from the non-null parent class loader</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>if</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">(c ==</span></font>&nbsp;<font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>null</b></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">) {</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font>&nbsp;<font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// If still not found, then invoke findClass in order</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font>&nbsp;<font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// to find the class.</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = findClass(name); //通过自己的findClass来加载类</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></font></div>
<div align="left" style="line-height: 20px;"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
<div align="left" style="line-height: 20px;">
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;"><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>&nbsp; &nbsp; &nbsp; if</b></span></font>&nbsp;<font face="Courier New" size="2"><span style="font-size: 10pt;">(resolve) {</span></font></span></font></div>
<div align="left"><font face="Courier New" size="2"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resolveClass(c);//用来做类链接操作</span></font></font></div>
<div align="left"><font face="Courier New" size="2"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></font></div>
</p></div>
</p></div>
</p></div>
<p>&nbsp; &nbsp; &nbsp;JVM在加载类时默认采用的是双亲委派机制。通俗的讲，就是某个特定的类加载器在接到加载类的请求时，首先将加载任务委托给父类加载器，依次递归，如果父类加载器可以完成类加载任务，就成功返回；只有父类加载器无法完成此加载任务时，才自己去加载。关于虚拟机默认的双亲委派机制，我们可以从系统类加载器和标准扩展类加载器为例作简单分析。</p>
</div>
<p>&nbsp;</p>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 2：Jetty的classloader </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p><strong>2.1：Jetty的classloader架构</strong></p>
<p>&nbsp; &nbsp; web容器的classloader比普通java应用略为复杂。</p>
<p>&nbsp; &nbsp; 每个web上下文（web应用和war文件）的普通配置是有自身的classloader，系统的classloader是它的父类。这是普通的java classloader的层次，但是servlet规范提出了负责的层次要求：</p>
<p>1. 在WEB-INF/lib和WEB-INF/classes中包含的类的加载优先级高于父classloader中的类。这和普通的java2的classloader加载动作相反。</p>
<p>2. 像java.lang.String这样的系统类不会被WEB-INF/lib或者WEB-INF/classes中的类替代。不幸的是，servlet规范并没有清楚的规定哪些类是系统类，也没有清楚的指出javax类应该作为系统类</p>
<p>3. Server实现类应该对web应用和其他classloader不可见。不幸的是，servelt规范并没有规定什么是server class ，也没有清楚的指出像xerces parser 这样的common libraries应该作为实现类。</p>
<p><strong>2.2：如何配置classloading</strong></p>
<p>&nbsp; &nbsp; jetty提供配置来控制以上三个选项。org.mortbay.jetty.webapp.WebAppContext.setParentLoaderPriority(boolean) 来控制所有类是否双亲委派的方式加载，这个配置解决了web应用加载的类在web应用和系统classpath同时存在的情况。</p>
<p>&nbsp; &nbsp; org.mortbay.jetty.webapp.WebAppContext.setSystemClasses(String[])和org.mortbay.jetty.webapp.WebAppContext.setServerClasses(String[])用来控制那些能够被web应用看到或者覆写的类。</p>
<p>* SystemClasses 不能被webapp 上下文 classloaders覆写. 默认的是：&nbsp;</p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">{&quot;java.&quot;,&quot;javax.servlet.&quot;,&quot;javax.xml.&quot;,&quot;org.mortbay.&quot;,&quot;org.xml.&quot;,&quot;org.w3c.&quot;, &quot;org.apache.commons.logging.&quot;,&quot;org.eclipse.jetty.continuation.&quot;,&quot;org.eclipse.jetty.jndi.&quot;,&quot;org.eclipse.jetty.plus.jaas.&quot;,&quot;org.eclipse.jetty.websocket.WebSocket&quot;, &quot;org.eclipse.jetty.websocket.WebSocketFactory&quot;, &quot;org.eclipse.jetty.servlet.DefaultServlet&quot;}</div>
<p>* ServerClasses (on the container classpath) 不能被webapp 上下文 classloaders看到但是可以被webapp覆写. 默认配置是:&nbsp;</p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">{&quot;-org.eclipse.jetty.continuation.&quot;,&quot;-org.eclipse.jetty.jndi.&quot;, &quot;-org.eclipse.jetty.plus.jaas.&quot;, &quot;-org.eclipse.jetty.websocket.WebSocket&quot;,&quot;-org.eclipse.jetty.websocket.WebSocketFactory&quot;,&quot;-org.eclipse.jetty.servlet.DefaultServlet&quot;, &quot;-org.eclipse.jetty.servlet.listener.&quot;, &quot;org.eclipse.jetty.&quot;};</div>
<p>&nbsp; &nbsp; [<strong>这段不知道如何翻译</strong>]Absolute classname can be passed, names ending with . are treated as packages names and names starting with &#8211; are treated as negative matches and must be listed before any enclosing packages.</p>
<p>&nbsp; &nbsp; &nbsp; 具体的类名可以不写，名称以.结尾代表是package名称，名称以&quot;-&quot;开头被认为是负面符号， and must be listed before any enclosing packages.</p>
<p><strong>2.3：给jetty添加额外的classpaths</strong></p>
<p>&nbsp; &nbsp; 在启动时，jetty会自动加载$jetty.home/lib下所有的jars，随之加载在start.jar中的文件start.config中明确配置的子目录（例如：$jetty.home/lib/management，$jetty.home/lib/naming/ 等）中的jars。所以，给jetty添加拓展的jars，需要在$jetty.home/lib/ext中创建一个任何你想的深度的文件层次。当然，你可以在自己创建start.config来定义默认加载动作来代替系统动作，否则，你需要使用以下方法：&nbsp;&nbsp;</p>
<p><strong>2.4：使用 jetty.class.path 系统属性</strong></p>
<p>&nbsp; &nbsp; 如果你想添加一个类目录或者jar到jetty，但是你不想把东西放到$jetty.home/lib/ext/中，或者你不想自己创建start.config文件，你可以简单的使用系统属性-Djetty.class.path，示例：</p>
<p>&nbsp; &nbsp; java -Djetty.class.path=&quot;../my/classes:../my/jars/special.jar:../my/jars/other.jar&quot; -jar start.jar</p>
<p><strong>2.5：在WebAppContext中使用extraClasspath()方法</strong></p>
<p>&nbsp; &nbsp; 如果你因为某种原因不想把jars或者classes放到 $jetty.home/lib ,同事也不想放到WEB-INF/lib 或者 WEB-INF/classes中，你可以把它添加到 $JETTY_HOME/contexts/mycontext.xml 文件中</p>
<p>&nbsp; &nbsp; &lt;Configure class=&quot;org.mortbay.jetty.webapp.WebAppContext&quot;&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &#8230;</p>
<p>&nbsp; &nbsp; &nbsp; &lt;Set name=&quot;extraClasspath&quot;&gt;../my/classes:../my/jars/special.jar:../my/jars/other.jar&lt;/Set&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &#8230;</p>
<p><strong>2.6：使用惯用的WebAppClassLoader</strong></p>
<p>&nbsp; &nbsp;最后，没有其他替代方案满足你的需求，你可以在自己的webapp中定制classloader，建议你的classloader是 &nbsp; &nbsp;org.mortbay.jetty.webapp.WebAppClassLoader的子类，但这不是必须的。你可以像如下的方式配置自己的webapp的classloader：</p>
<p>&nbsp; &nbsp; &nbsp;MyCleverClassLoader myCleverClassLoader = new MyCleverClassLoader();</p>
<p>&nbsp; &nbsp; &nbsp;&#8230;</p>
<p>&nbsp; &nbsp; &nbsp;WebAppContext webapp = new WebAppContext();</p>
<p>&nbsp; &nbsp; &nbsp;&#8230;</p>
<p>&nbsp; &nbsp; &nbsp;webapp.setClassLoader(myCleverClassLoader);</p>
</div>
<p>&nbsp;</p>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 参考资料： </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<ul>
<li><a href="http://docs.codehaus.org/display/JETTY/Classloading">What is Jetty&#39;s classloading architecture?</a></li>
<li><a href="http://docs.codehaus.org/display/JETTY/SystemProperties">如何设置children/parent frist</a></li>
<li><a href="http://docs.codehaus.org/display/JETTY/WebAppDeployer">Web Application Deployer</a></li>
<li><a href="http://onjava.com/pub/a/onjava/2003/11/12/classloader.html">Inside Class Loaders</a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=755</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Guava V11 中的Cache操作</title>
		<link>http://www.longtask.com/blog/?p=753</link>
		<comments>http://www.longtask.com/blog/?p=753#comments</comments>
		<pubDate>Thu, 05 Apr 2012 07:46:03 +0000</pubDate>
		<dc:creator>longhao</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[callable]]></category>
		<category><![CDATA[guava]]></category>

		<guid isPermaLink="false">http://www.longtask.com/blog/?p=753</guid>
		<description><![CDATA[Google Guava cache的主要功能点： 

&#160;&#160;&#160; * 你需要给现有系统加速；
		&#160;&#160;&#160; * 有些key需要不知一次的查询获取；
		&#160;&#160;&#160; * 从策略上讲，你的应用需要从策略上把所有的value从cache中清理出来 &#8212; 你试图减少重复的工作；[注：weakKey , weakValue]
		&#160;&#160;&#160; * cache仅仅存储在内存中，没有在文件中或者其他的server上面，如果不满足你的需求，可以考虑Memcached

API的两种调用方式 

1：普通的调用方式，通过key得到value的时间较短


&#160;/**
&#160;&#160;&#160;&#160;&#160;&#160; * 不需要延迟处理(泛型的方式封装)
&#160;&#160;&#160;&#160;&#160;&#160; *&#160;@return
&#160;&#160;&#160;&#160;&#160;&#160; */
&#160;&#160;&#160;&#160;&#160;&#160;public&#160;static&#160;&#60;K , V&#62; LoadingCache&#60;K , V&#62; cached(CacheLoader&#60;K , V&#62; cacheLoader) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;LoadingCache&#60;K , V&#62; cache = CacheBuilder.newBuilder()
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.maximumSize(10000)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.weakKeys()
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.softValues()
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.refreshAfterWrite(120, TimeUnit.SECONDS)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.expireAfterWrite(10, TimeUnit.MINUTES)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// .removalListener(RemovalListeners.asynchronous(listener,executor))
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// .removalListener(MY_LISTENER)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;.build(cacheLoader);
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return&#160;cache;
&#160;&#160;&#160;&#160;&#160;&#160;}
&#160;&#160;&#160;&#160;&#160;&#160;/**
&#160;&#160;&#160;&#160;&#160;&#160; * 通过key获取value
&#160;&#160;&#160;&#160;&#160;&#160; * 调用方式 commonCache.get(key) ; return String
&#160;&#160;&#160;&#160;&#160;&#160; *&#160;@param&#160;key
&#160;&#160;&#160;&#160;&#160;&#160; *&#160;@return
&#160;&#160;&#160;&#160;&#160;&#160; *&#160;@throws&#160;Exception
&#160;&#160;&#160;&#160;&#160;&#160; */
&#160;&#160;&#160;&#160;&#160;&#160;public&#160;static&#160;LoadingCache&#60;String , String&#62; commonCache(final&#160;String  <a href="http://www.longtask.com/blog/?p=753" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>Google Guava cache的主要功能点： </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp;&nbsp;&nbsp; * 你需要给现有系统加速；<br />
		&nbsp;&nbsp;&nbsp; * 有些key需要不知一次的查询获取；<br />
		&nbsp;&nbsp;&nbsp; * 从策略上讲，你的应用需要从策略上把所有的value从cache中清理出来 &#8212; 你试图减少重复的工作；[注：weakKey , weakValue]<br />
		&nbsp;&nbsp;&nbsp; * cache仅仅存储在内存中，没有在文件中或者其他的server上面，如果不满足你的需求，可以考虑Memcached</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>API的两种调用方式 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>1：普通的调用方式，通过key得到value的时间较短</p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">
<div>
<div align="left"><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;/**</span></font></span></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 不需要延迟处理(泛型的方式封装)</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@return</b></span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>public</b></span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>static</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">&lt;K , V&gt; LoadingCache&lt;K , V&gt; cached(CacheLoader&lt;K , V&gt; cacheLoader) {</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LoadingCache&lt;K , V&gt; cache = CacheBuilder.</span><span style="font-size: 10pt;"><i>newBuilder</i></span><span style="font-size: 10pt;">()</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.maximumSize(10000)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.weakKeys()</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.softValues()</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.refreshAfterWrite(120, TimeUnit.</span></font><font color="#0000C0" face="Courier New" size="2"><span style="font-size: 10pt;"><i>SECONDS</i></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.expireAfterWrite(10, TimeUnit.</span></font><font color="#0000C0" face="Courier New" size="2"><span style="font-size: 10pt;"><i>MINUTES</i></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// .removalListener(RemovalListeners.asynchronous(listener,executor))</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// .removalListener(MY_LISTENER)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.build(cacheLoader);</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>return</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">cache;</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">/**</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 通过key获取value</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 调用方式 commonCache.get(key) ; return String</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@param</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">key</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@return</b></span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@throws</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">Exception</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>public</b></span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>static</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">LoadingCache&lt;String , String&gt; commonCache(</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>final</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">String key)</span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>throws</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Exception{</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>return</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;"><i>cached</i></span><span style="font-size: 10pt;">(</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>new</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">CacheLoader&lt;String , String&gt;(){</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#646464" face="Courier New" size="2"><span style="font-size: 10pt;">@Override</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>public</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">String load(String key)</span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>throws</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Exception {</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>return</b></span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>null</b></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">;</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
</p></div>
</p></div>
<p></p>
<p>2：延迟加载的处理方式，通过key得到value的时间较长</p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">
<div>
<div align="left"><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Tahoma; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium;"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">/**</span></font></span></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 对需要延迟处理的可以采用这个机制；(泛型的方式封装)</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@param</b></span></font><span>&nbsp;</span><font color="#7F7F9F" face="Courier New" size="2"><span style="font-size: 10pt;">&lt;K&gt;</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@param</b></span></font><span>&nbsp;</span><font color="#7F7F9F" face="Courier New" size="2"><span style="font-size: 10pt;">&lt;V&gt;</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@param</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">key</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@param</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">callable</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@return</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">V</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@throws</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">Exception</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>public</b></span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>static</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">&lt;K,V&gt; Cache&lt;K , V&gt; callableCached(Callable&lt;V&gt; callable)</span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>throws</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Exception {</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cache&lt;K, V&gt; cache = CacheBuilder.</span><span style="font-size: 10pt;"><i>newBuilder</i></span><span style="font-size: 10pt;">()</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.maximumSize(10000)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.expireAfterWrite(10, TimeUnit.</span></font><font color="#0000C0" face="Courier New" size="2"><span style="font-size: 10pt;"><i>MINUTES</i></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// .removalListener(RemovalListeners.asynchronous(listener,executor))</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// .removalListener(MY_LISTENER)</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// .weakKeys()</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F7F5F" face="Courier New" size="2"><span style="font-size: 10pt;">// .weakValues()</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.build();</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>return</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">cache;</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">/**</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 通过</span><span style="font-size: 10pt;"><u>callable</u></span><span style="font-size: 10pt;">的方式获取value；</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * 调用方式 callableCache.get(key) ; return String</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@param</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">key</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@return</b></span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *</span></font><span>&nbsp;</span><font color="#7F9FBF" face="Courier New" size="2"><span style="font-size: 10pt;"><b>@throws</b></span></font><span>&nbsp;</span><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">Exception</span></font></div>
<div align="left"><font color="#3F5FBF" face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>public</b></span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>static</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Cache&lt;String , String&gt; callableCache(</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>final</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">String key)</span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>throws</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Exception{</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>return</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;"><i>callableCached</i></span><span style="font-size: 10pt;">(</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>new</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Callable&lt;String&gt;(){</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#646464" face="Courier New" size="2"><span style="font-size: 10pt;">@Override</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>public</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">String call()</span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>throws</b></span></font><span>&nbsp;</span><font face="Courier New" size="2"><span style="font-size: 10pt;">Exception {</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></font><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>return</b></span></font><span>&nbsp;</span><font color="#7F0055" face="Courier New" size="2"><span style="font-size: 10pt;"><b>null</b></span></font><font face="Courier New" size="2"><span style="font-size: 10pt;">;</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</span></font></div>
<div align="left"><font face="Courier New" size="2"><span style="font-size: 10pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></font></div>
</p></div>
</p></div>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 回收的参数设置 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp;&nbsp;&nbsp; 1. 大小的设置：CacheBuilder.maximumSize(long)&nbsp; CacheBuilder.weigher(Weigher)&nbsp; CacheBuilder.maxumumWeigher(long)<br />
		&nbsp;&nbsp;&nbsp; 2. 时间：expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)<br />
		&nbsp;&nbsp;&nbsp; 3. 引用：CacheBuilder.weakKeys() CacheBuilder.weakValues()&nbsp; CacheBuilder.softValues()<br />
		&nbsp;&nbsp;&nbsp; 4. 明确的删除：invalidate(key)&nbsp; invalidateAll(keys)&nbsp; invalidateAll()<br />
		&nbsp;&nbsp;&nbsp; 5. 删除监听器：CacheBuilder.removalListener(RemovalListener)</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; refresh机制 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp;&nbsp;&nbsp; 1. LoadingCache.refresh(K)&nbsp; 在生成新的value的时候，旧的value依然会被使用。<br />
		&nbsp;&nbsp;&nbsp; 2. CacheLoader.reload(K, V) 生成新的value过程中允许使用旧的value<br />
		&nbsp;&nbsp;&nbsp; 3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 自动刷新cache</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 未来要实现的功能 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp;&nbsp;&nbsp; 1. 更多统计信息，通过Cache.stats()来获取统计类CacheStats，例如缓存命中率，缓存获取实践统计等<br />
		&nbsp;&nbsp;&nbsp; 2. asMap，把缓存动作一个ConcurrentMap</p>
</div>
<p>
	参考资料 ：<a href="http://code.google.com/p/guava-libraries/wiki/CachesExplained#Inserted_Directly" target="_blank">http://code.google.com/p/guava-libraries/wiki/CachesExplained#Inserted_Directly &nbsp;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=753</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux kernel 性能压力下的优化实践(V0.1)</title>
		<link>http://www.longtask.com/blog/?p=750</link>
		<comments>http://www.longtask.com/blog/?p=750#comments</comments>
		<pubDate>Sun, 01 Apr 2012 05:32:41 +0000</pubDate>
		<dc:creator>longhao</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[conntrack_max]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[sysctl]]></category>

		<guid isPermaLink="false">http://www.longtask.com/blog/?p=750</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160; 做benchmark测试的过程中，总是会涉及到linux操作系统底层的设置导致无法充分利用机器的性能，在调试的过程中，不少资料没能和linux kernel版本对应上导致一些参数的设置错误。根据现有服务器的硬件条件和软件版本做相关优化，把一些实践的心得分享出来。
&#160;&#160;&#160;&#160;&#160; Kernel version ： 2.6.32-71.el6.x86_64
&#160;&#160;&#160;&#160;&#160; Cpu：Intel(R) Xeon(R) CPU&#160;&#160;&#160; E5606&#160; @ 2.13GHz
&#160;&#160;&#160;&#160;&#160; Memory：8G
&#160;&#160;&#160;&#160;&#160; Release notes ： v0.1&#160; 2012-03-31&#160; 句柄数&#160; ， 网络参数
&#160;&#160;&#160;&#160; 问题1：句柄数的问题 

&#160;&#160;&#160; 使用webbench在Linux下做varlish访问压力测试的时候，遇到Socket/File: Can&#8217;t open so many files的问题，原因是linux下所有的东西都是文件，包括socket接口，对于大量的网络连接，不仅仅消耗socket文件描述符，对于进程本身还打开相当多的文件，Linux的默认句柄数是1024。
解决方式：
修改/etc/security/limits.conf
		&#160;&#160;&#160;&#160; 你的用户名&#160; soft nofile 65535&#160;&#160;&#160;&#160;&#160; ##ulimit -Sn
		&#160;&#160;&#160;&#160; 你的用户名 hard nofile 65535&#160;&#160;&#160;&#160;&#160; ##ulimit -Hn
		unlimt -n 查看
参考资料：
		

通过ulimit改善系统性能
			


&#160;&#160;&#160;&#160; 问题2：网络参数 

&#160;&#160;&#160;&#160;&#160; 使用ab或者webbench做压力测试，如果并发数开到1000的时候，无法完成测试。到晚上查看资料发现是linux网络参数设置。
		解决方式：
[longhao@longhao etc]# vi /etc/sysctl.conf
		在kernel2.6之前的添加项：
		net.ipv4.netfilter.ip_conntrack_max = 655360
		net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 180
		kernel2.6之后的添加项：
		net.nf_conntrack_max =  <a href="http://www.longtask.com/blog/?p=750" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp; 做benchmark测试的过程中，总是会涉及到linux操作系统底层的设置导致无法充分利用机器的性能，在调试的过程中，不少资料没能和linux kernel版本对应上导致一些参数的设置错误。根据现有服务器的硬件条件和软件版本做相关优化，把一些实践的心得分享出来。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Kernel version ： 2.6.32-71.el6.x86_64</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Cpu：Intel(R) Xeon(R) CPU&nbsp;&nbsp;&nbsp; E5606&nbsp; @ 2.13GHz</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Memory：8G</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Release notes ： v0.1&nbsp; 2012-03-31&nbsp; 句柄数&nbsp; ， 网络参数</p>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 问题1：句柄数的问题 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp;&nbsp;&nbsp; 使用webbench在Linux下做varlish访问压力测试的时候，遇到Socket/File: Can&rsquo;t open so many files的问题，原因是linux下所有的东西都是文件，包括socket接口，对于大量的网络连接，不仅仅消耗socket文件描述符，对于进程本身还打开相当多的文件，Linux的默认句柄数是1024。</p>
<p><strong>解决方式：</strong></p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">修改/etc/security/limits.conf<br />
		&nbsp;&nbsp;&nbsp;&nbsp; 你的用户名&nbsp; soft nofile 65535&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ##ulimit -Sn<br />
		&nbsp;&nbsp;&nbsp;&nbsp; 你的用户名 hard nofile 65535&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ##ulimit -Hn<br />
		unlimt -n 查看</div>
<p><strong>参考资料：<br />
		</strong></p>
<ol>
<li><a href="http://www.ibm.com/developerworks/cn/linux/l-cn-ulimit/" target="_blank">通过ulimit改善系统性能<br />
			</a></li>
</ol>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 问题2：网络参数 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用ab或者webbench做压力测试，如果并发数开到1000的时候，无法完成测试。到晚上查看资料发现是linux网络参数设置。</p>
<p>		<strong>解决方式：</strong></p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">[longhao@longhao etc]# vi /etc/sysctl.conf<br />
		<u>在kernel2.6之前的添加项：</u><br />
		net.ipv4.netfilter.ip_conntrack_max = 655360<br />
		net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 180</p>
<p>		<u>kernel2.6之后的添加项：</u><br />
		net.nf_conntrack_max = 655360&nbsp; # net.nf_conntrack_max = 655360 也可以<br />
		net.netfilter.nf_conntrack_tcp_timeout_established = 1200</p>
<p>		[longhao@longhao etc]# sysctl -p /etc/sysctl.conf</p>
<p>如果报错：error: &quot;net.nf_conntrack_max&quot; is an unknown key 则需要使用modprobe载入ip_conntrack模块，lsmod查看模块已载入。<br />
			[longhao@longhao etc]# modprobe&nbsp; ip_conntrack</p>
</p></div>
<p><strong>后续说明：</strong><br />
		&nbsp;&nbsp;&nbsp;&nbsp; &#8211;CONNTRACK_MAX 允许的最大跟踪连接条目，是在内核内存中netfilter可以同时处理的&ldquo;任务&rdquo;（连接跟踪条目）<br />
		&nbsp;&nbsp;&nbsp;&nbsp; &#8211;HASHSIZE 存储跟踪连接条目列表的哈西表的大小</p>
<p>		CONNTRACK_MAX和HASHSIZE的默认值<br />
		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一般来说，CONNTRACK_MAX和HASHSIZE都会设置在&ldquo;合理&rdquo;使用的值上，依据可使用的RAM的大小来计算这个值。</p>
<p>		<strong>CONNTRACK_MAX的默认值</strong><br />
		&nbsp;&nbsp;&nbsp;&nbsp; 在i386架构上，CONNTRACK_MAX = RAMSIZE (以bytes记) / 16384 =RAMSIZE (以MegaBytes记) * 64，因此，一个32位的带512M内存的PC在默认情况下能够处理512*1024^2/16384 = 512*64 = 32768个并发的netfilter连接。<br />
		&nbsp;&nbsp;&nbsp;&nbsp; 但是真正的公式是：CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (x / 32) 这里x是指针的bit数，（例如，32或者64bit）</p>
<p>		请注意：<br />
		&nbsp;&nbsp;&nbsp;&nbsp; －默认的CONNTRACK_MAX值不会低于128<br />
		&nbsp;&nbsp;&nbsp;&nbsp; －对于带有超过1G内存的系统，CONNTRACK_MAX的默认值会被限制在65536（但是可以手工设置成更大的值）</p>
<p>		<strong>HASHSIZE的默认值</strong><br />
		&nbsp;&nbsp;&nbsp;&nbsp; 通常，CONNTRACK_MAX = HASHSIZE * 8。这意味着每个链接的列表平均包含8个conntrack的条目（在优化的情况并且CONNTRACK_MAX达到的情况下），每个链接的列表就是一个哈西表条目（一个桶）。<br />
		&nbsp;&nbsp;&nbsp;&nbsp; 在i386架构上，HASHSIZE = CONNTRACK_MAX / 8 =RAMSIZE (以bytes记) / 131072 = RAMSIZE (以MegaBytes记) * 8。举例来说，一个32位、带512M内存的PC可以存储512*1024^2/128/1024 =512*8 = 4096 个桶（链接表）<br />
		&nbsp;&nbsp;&nbsp;&nbsp; 但是真正的公式是：HASHSIZE = CONNTRACK_MAX / 8 = RAMSIZE (以bytes记) / 131072 / (x / 32)这里x是指针的bit数，（例如，32或者64bit）</p>
<p>		请注意：<br />
		&nbsp;&nbsp;&nbsp;&nbsp; －默认HASHSIZE的值不会小于16<br />
		&nbsp;&nbsp;&nbsp;&nbsp; －对于带有超过1G内存的系统，HASHSIZE的默认值会被限制在8192（但是可以手工设置成更大的值）</p>
<p><strong>参考资料：<br />
		</strong></p>
<ol>
<li><a href="http://wiki.khnet.info/index.php/Conntrack_tuning" target="_blank">Conntrack tuning</a></li>
<li><a href="http://blog.yorkgu.me/2012/02/09/kernel-nf_conntrack-table-full-dropping-packet/" target="_blank">kernel nf_conntrack: table full, dropping packet 解决办法</a></li>
<li><a href="http://blog.csdn.net/dog250/article/details/7107537" target="_blank">不要盲目增加ip_conntrack_max-理解Linux内核内存
<p>			</a></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=750</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DelayQueue在容错时的使用</title>
		<link>http://www.longtask.com/blog/?p=748</link>
		<comments>http://www.longtask.com/blog/?p=748#comments</comments>
		<pubDate>Wed, 14 Mar 2012 05:08:59 +0000</pubDate>
		<dc:creator>longhao</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[BlockingQueue]]></category>
		<category><![CDATA[concurrent]]></category>
		<category><![CDATA[QelayQueue]]></category>

		<guid isPermaLink="false">http://www.longtask.com/blog/?p=748</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160; 1：异步容错的处理需求 

&#160; &#160; &#160;遇到错误消息后，把消息写入到表中同时写入到queue中，把这个错误的内容异步通知到其他系统中去。同步的时间间隔以2的N次方递增，设计的前提是尽量减小数据库的压力。

&#160;&#160;&#160;&#160; 2：设计 

&#160; &#160; &#160; java.util.concurrent.DelayQueue中的对象必须实现java.util.concurrent.Delayed的接口，Delayed 元素的一个无界阻塞队列，只有在延迟期满时才能从中提取元素。该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满，则队列没有头部，并且 poll 将返回 null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时，将发生到期。即使无法使用 take 或 poll 移除未到期的元素，也不会将这些元素作为正常元素对待。例如，size 方法同时返回到期和未到期元素的计数。此队列不允许使用 null 元素。&#160;
&#160; &#160; 队列中的对象设计：

public class DelayDomain implements Delayed{
&#160; &#160; &#160; /**
&#160; &#160; &#160; &#160;* 处理机制：按照发送次数2的N次方秒递增。
&#160; &#160; &#160; &#160;* @param payInternalNotify
&#160; &#160; &#160; &#160;*/
&#160; &#160; &#160; public DelayDomain(int sendtime ,  <a href="http://www.longtask.com/blog/?p=748" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 1：异步容错的处理需求 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp; &nbsp; &nbsp;遇到错误消息后，把消息写入到表中同时写入到queue中，把这个错误的内容异步通知到其他系统中去。同步的时间间隔以2的N次方递增，设计的前提是尽量减小数据库的压力。</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 2：设计 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp; &nbsp; &nbsp; java.util.concurrent.DelayQueue中的对象必须实现java.util.concurrent.Delayed的接口，Delayed 元素的一个无界阻塞队列，只有在延迟期满时才能从中提取元素。该队列的头部 是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满，则队列没有头部，并且 poll 将返回 null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时，将发生到期。即使无法使用 take 或 poll 移除未到期的元素，也不会将这些元素作为正常元素对待。例如，size 方法同时返回到期和未到期元素的计数。此队列不允许使用 null 元素。&nbsp;</p>
<p><strong>&nbsp; &nbsp; 队列中的对象设计：</strong></p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">
<p>public class DelayDomain implements Delayed{</p>
<p>&nbsp; &nbsp; &nbsp; /**</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;* 处理机制：按照发送次数2的N次方秒递增。</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;* @param payInternalNotify</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;*/</p>
<p>&nbsp; &nbsp; &nbsp; public DelayDomain(int sendtime , String url){</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.sendTime = (new Date()).getTime() + &nbsp;(long)Math.pow(2, sendtime) * TIME_UNIT;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.url = url;</p>
<p>&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; @Override</p>
<p>&nbsp; &nbsp; &nbsp; public int compareTo(Delayed obj) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DelayDomain delayDomain = (DelayDomain)obj;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; long timeout = sendTime &#8211; delayDomain.sendTime;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; return timeout &gt; 0 ? 1 : timeout &lt; 0 ? -1 : 0;</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; @Override</p>
<p>&nbsp; &nbsp; &nbsp; public long getDelay(TimeUnit unit) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return sendTime &#8211; System.currentTimeMillis();&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; private static final int TIME_UNIT = 1000 ; //按照秒来递增</p>
<p>&nbsp; &nbsp; &nbsp; private long sendTime ;</p>
<p>&nbsp; &nbsp; &nbsp; private String url ;</p>
<p>&nbsp; &nbsp; &nbsp; public String getUrl() {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return url;</p>
<p>&nbsp; &nbsp; &nbsp; } &nbsp; &nbsp;&nbsp;</p>
<p>}</p>
</p></div>
<p><strong>&nbsp; &nbsp; &nbsp;Queue的代码：</strong></p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">
<p>&nbsp; &nbsp; &nbsp;public class SendQueue {</p>
<p>&nbsp; &nbsp; &nbsp; public static void put(DelayDomain DelayDomain)</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws InterruptedException{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QUEUE.put(DelayDomain);</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; public static DelayDomain take()throws InterruptedException{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return QUEUE.take();</p>
<p>&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; /**</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;* 添加错误消息到队列中,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;* @param payInternalNotify</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;*/</p>
<p>&nbsp; &nbsp; &nbsp; public static void addSendUrl(int sendTime , String url)</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws InterruptedException{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DelayDomain DelayDomain = new DelayDomain(sendTime , url);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put(DelayDomain);</p>
<p>&nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; private SendQueue(){};</p>
<p>&nbsp; &nbsp; &nbsp; //服务队列</p>
<p>&nbsp; &nbsp; &nbsp; private static final BlockingQueue&lt;DelayDomain&gt; QUEUE = &nbsp;new DelayQueue&lt;DelayDomain&gt;();</p>
<p>&nbsp; &nbsp;}</p>
</p></div>
<p><strong>&nbsp; &nbsp; &nbsp;测试代码：</strong></p>
<div style="border-top: 1px solid rgb(148, 218, 58); border-bottom: 1px solid rgb(148, 218, 58); padding: 9px 0pt 9px 16px; background-color: rgb(224, 255, 182);">
<p>&nbsp; &nbsp; &nbsp;public class DelayMain {</p>
<p>&nbsp; &nbsp; &nbsp; public static void main(String[] args) throws Exception{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(&quot;Start time @ &quot; + getNow());</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendQueue.addSendUrl(2 , &quot;www.baidu.com&quot;);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendQueue.addSendUrl(1 , &quot;www.google.com&quot;);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SendQueue.addSendUrl(3 , &quot;www.hao123.com&quot;);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while(true){</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DelayDomain domain = SendQueue.take();</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(domain.getUrl() + &quot; @ &quot; + getNow());</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; private static String getNow(){</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SimpleDateFormat sdf = new SimpleDateFormat(&quot;HH:mm:ss&quot;);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return sdf.format(new Date());</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp;}</p>
</p></div>
<p><strong>&nbsp; &nbsp; &nbsp;输出结果：</strong></p>
<p>&nbsp; &nbsp; &nbsp;Start time : 11:20:21</p>
<p>&nbsp; &nbsp; &nbsp;www.google.com @ 11:20:23</p>
<p>&nbsp; &nbsp; &nbsp;www.baidu.com @ 11:20:25</p>
<p>&nbsp; &nbsp; &nbsp;www.hao123.com @ 11:20:29</p>
<p><u>&nbsp; &nbsp; 我们看到google在2秒后出队列，百度的4秒，hao123的8秒。放到队列中会自动按照时间顺序来排序，只有时间到了才会被take出队列，否则一直等待。</u></p>
<p>&nbsp;</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 3：设计缺点 </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>&nbsp; &nbsp; 修改数据库状态不能自动同步了。需要通过脚本来执行一些过期的内容，或者通过接口方式处罚容错。</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=748</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring的RMI , Http Invoker, Hessian测试结果</title>
		<link>http://www.longtask.com/blog/?p=742</link>
		<comments>http://www.longtask.com/blog/?p=742#comments</comments>
		<pubDate>Tue, 06 Mar 2012 12:12:23 +0000</pubDate>
		<dc:creator>longhao</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[hessian]]></category>
		<category><![CDATA[http invoker]]></category>
		<category><![CDATA[RMI]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.longtask.com/blog/?p=742</guid>
		<description><![CDATA[&#160;&#160;&#160;&#160; RMI配置说明： 

1：对象序列化：
public class Account implements Serializable{
&#160; &#160; private String name;
&#160; &#160; public String getName(){
&#160; &#160; &#160; &#160; return name;
&#160; &#160; }
&#160; &#160; public void setName(String name) {
&#160; &#160; &#160; this.name = name;
&#160; &#160; }
}
2：远程接口定义：
public interface RemoteCallExample extends Remote {
&#160; &#160; &#160; public String show() throws RemoteException;
}
3：远程接口实现：
public class RemoteCallExampleImpl implements RemoteCallExample {
&#160; &#160; &#160; @Override
&#160;  <a href="http://www.longtask.com/blog/?p=742" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; RMI配置说明： </strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p><strong>1：对象序列化：</strong></p>
<p>public class Account implements Serializable{</p>
<p>&nbsp; &nbsp; private String name;</p>
<p>&nbsp; &nbsp; public String getName(){</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; return name;</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; public void setName(String name) {</p>
<p>&nbsp; &nbsp; &nbsp; this.name = name;</p>
<p>&nbsp; &nbsp; }</p>
<p>}</p>
<p><strong>2：远程接口定义：</strong></p>
<p>public interface RemoteCallExample extends Remote {</p>
<p>&nbsp; &nbsp; &nbsp; public String show() throws RemoteException;</p>
<p>}</p>
<p><strong>3：远程接口实现：</strong></p>
<p>public class RemoteCallExampleImpl implements RemoteCallExample {</p>
<p>&nbsp; &nbsp; &nbsp; @Override</p>
<p>&nbsp; &nbsp; &nbsp; public String show() throws RemoteException{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return &quot;remote test&quot;;</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>}</p>
<p><strong>4：Spring服务器端配置（使用RmiServiceExporter来）：</strong></p>
<p>在WEB-INF目录下面新建remoting-servlet.xml文件，添加相关的配置。</p>
<p>&lt;bean name=&quot;remoteCallExample&quot; class=&quot;com.hqb360.pay.service.impl.RemoteCallExampleImpl&quot; /&gt;</p>
<p>&lt;bean class=&quot;org.springframework.remoting.rmi.RmiServiceExporter&quot;&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;!&#8211; does not necessarily have to be the same name as the bean to be exported &#8211;&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;serviceName&quot; value=&quot;remoteCallExample&quot;/&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;service&quot; ref=&quot;remoteCallExample&quot;/&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;serviceInterface&quot; value=&quot;com.hqb360.pay.service.RemoteCallExample&quot;/&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;!&#8211; defaults to 1099 &#8211;&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;registryPort&quot; value=&quot;1199&quot;/&gt;</p>
<p>&lt;/bean&gt;</p>
<p><strong>5：服务器端类</strong></p>
<p>public class RemoteCallRMI{</p>
<p>&nbsp; &nbsp; &nbsp; public String show() throws RemoteException{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return remoteCallExample.show();</p>
<p>&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; private RemoteCallExample remoteCallExample;</p>
<p>&nbsp; &nbsp; &nbsp; public RemoteCallExample getRemoteCallExample() {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return remoteCallExample;</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; public void setRemoteCallExample(RemoteCallExample remoteCallExample) {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.remoteCallExample = remoteCallExample;</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>}</p>
<p><strong>6：服务器端配置</strong></p>
<p>&lt;bean name=&quot;remoteCallRMI&quot; class=&quot;com.hqb360.pay.service.impl.RemoteCallRMI&quot; &gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;remoteCallExample&quot; ref=&quot;remoteCall&quot; /&gt;</p>
<p>&lt;/bean&gt;</p>
<p>&lt;bean id=&quot;remoteCall&quot; class=&quot;org.springframework.remoting.rmi.RmiProxyFactoryBean&quot;&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;serviceUrl&quot; value=&quot;rmi://192.168.100.10:1199/remoteCallExample&quot;/&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;serviceInterface&quot; value=&quot;com.hqb360.pay.service.RemoteCallExample&quot;/&gt;</p>
<p>&lt;/bean&gt;</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 一些RMI问题说明：</strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p>1. RMI在启动配置中需要添加：<strong>-Djava.rmi.server.hostname=192.168.100.10</strong></p>
<p>2. 需要制定相关的具体IP，把读取配置文件放到系统启动的时候处理。</p>
<p>Spring3.0后默认的HandlerMapping是DefaultAnnotationHandlerMapping，不是以前的BeanNameUrlHandlerMapping，所以配置Hessian和HttpInvoker的时候需要重新定义一下HandlerMapping.</p>
<p>在按照spring手册配置的时候需要添加定义（Spring文档有遗漏的地方）：</p>
<p>&lt;!&#8211;Hessian 启动BeanNameMapping 映射功能,以httpRequest作为处理Adapter&#8211;&gt;</p>
<p>&nbsp; &nbsp; &lt;bean class=&quot;org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping&quot;&gt;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &lt;property name=&quot;defaultHandler&quot; ref=&quot;httpRequestHandlerAdapter&quot; /&gt;</p>
<p>&nbsp; &nbsp; &lt;/bean&gt;</p>
<p>&nbsp; &nbsp; &lt;!&#8211; Hessian 方式以Http进行传递 &#8211;&gt;</p>
<p>&nbsp; &nbsp; &lt;bean id=&quot;httpRequestHandlerAdapter&quot; class=&quot;org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter&quot; /&gt;</p>
</div>
<p style="background-color: rgb(230, 230, 250); height: 25px; width: 100%; padding-top: 9px; font-family: arial,helvetica,sans-serif; font-size: 14px; color: rgb(0, 0, 0);"><span style="font-size:14px;"><strong>&nbsp;&nbsp;&nbsp;&nbsp; 测试结果</strong></span></p>
<div style="border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;">
<p><strong>测试性能：RMI &gt; Hessian &gt; Http Invoker</strong></p>
<p>数据图表如下：</p>
<p><img alt="" height="298" src="http://www.longtask.com/blog/wp-content/uploads/ex(1).jpg" width="485" /></p>
<p><strong>RMI</strong></p>
<p>RMI并发测试（线程池大小：5，线程数：5）</p>
<p>[TestRunner] Starting executor timeOut:1000000ms workers:5 threadPoolSize:5</p>
<p>0 [5,880ms, 100%]</p>
<p>0 [5,881ms, 100%]</p>
<p>0 [5,977ms, 100%]</p>
<p>0 [5,978ms, 100%]</p>
<p>0 [5,989ms, 100%]</p>
<p>RemoteTestNG finishing: 8318 ms</p>
<p>RMI并发测试（线程池大小：5，线程数：10）</p>
<p>[TestRunner] Starting executor timeOut:1000000ms workers:10 threadPoolSize:5</p>
<p>0 [5,843ms, 100%]</p>
<p>0 [5,856ms, 100%]</p>
<p>0 [5,864ms, 100%]</p>
<p>0 [5,967ms, 100%]</p>
<p>0 [5,970ms, 100%]</p>
<p>0 [5,795ms, 100%]</p>
<p>0 [5,810ms, 100%]</p>
<p>0 [5,812ms, 100%]</p>
<p>0 [5,891ms, 100%]</p>
<p>0 [5,935ms, 100%]</p>
<p>RemoteTestNG finishing: 14194 ms</p>
<p><strong>Httpinvoker</strong></p>
<p>并发测试（线程池大小：5，线程数：5）</p>
<p>[TestRunner] Starting executor timeOut:100000ms workers:5 threadPoolSize:5</p>
<p>0 [24,350ms, 100%]</p>
<p>0 [25,384ms, 100%]</p>
<p>0 [27,601ms, 100%]</p>
<p>0 [27,700ms, 100%]</p>
<p>0 [29,443ms, 100%]</p>
<p>RemoteTestNG finishing: 31737 ms</p>
<p>并发测试（线程池大小：5，线程数：10）</p>
<p>[TestRunner] Starting executor timeOut:1000000ms workers:10 threadPoolSize:5</p>
<p>0 [26,519ms, 100%]</p>
<p>0 [26,637ms, 100%]</p>
<p>0 [28,365ms, 100%]</p>
<p>0 [29,744ms, 100%]</p>
<p>0 [29,821ms, 100%]</p>
<p>0 [28,433ms, 100%]</p>
<p>0 [29,914ms, 100%]</p>
<p>0 [31,795ms, 100%]</p>
<p>0 [28,959ms, 100%]</p>
<p>0 [29,407ms, 100%]</p>
<p>RemoteTestNG finishing: 61477 ms</p>
<p><strong>hessian测试结果</strong></p>
<p>并发测试（线程池大小：5，线程数：5）</p>
<p>[TestRunner] Starting executor timeOut:100000ms workers:5 threadPoolSize:5</p>
<p>0 [13,343ms, 100%]</p>
<p>0 [13,957ms, 100%]</p>
<p>0 [14,544ms, 100%]</p>
<p>0 [14,612ms, 100%]</p>
<p>0 [14,822ms, 100%]</p>
<p>RemoteTestNG finishing: 17133 ms</p>
<p>并发测试（线程池大小：5，线程数：10）</p>
<p>[TestRunner] Starting executor timeOut:100000ms workers:10 threadPoolSize:5</p>
<p>0 [13,407ms, 100%]</p>
<p>0 [14,058ms, 100%]</p>
<p>0 [14,271ms, 100%]</p>
<p>0 [14,293ms, 100%]</p>
<p>0 [18,198ms, 100%]</p>
<p>0 [14,496ms, 100%]</p>
<p>0 [15,128ms, 100%]</p>
<p>0 [16,478ms, 100%]</p>
<p>0 [17,680ms, 100%]</p>
<p>0 [17,317ms, 100%]</p>
<p>RemoteTestNG finishing: 37844 ms</p>
<p>&nbsp;</p>
<p>需要测试代码的联系：longtask@gmail.com</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=742</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>并发编程实践PPT</title>
		<link>http://www.longtask.com/blog/?p=740</link>
		<comments>http://www.longtask.com/blog/?p=740#comments</comments>
		<pubDate>Thu, 01 Mar 2012 05:40:40 +0000</pubDate>
		<dc:creator>longhao</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[concurrent]]></category>
		<category><![CDATA[synchronizer]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://www.longtask.com/blog/?p=740</guid>
		<description><![CDATA[&#160;&#160;&#160; 一年多前写的ppt，拿出了和大家分享。自己也顺便回忆一下里面的内容
Java并发编程培训
View more presentations from longhao.

]]></description>
			<content:encoded><![CDATA[<p><span style="font-size:14px;">&nbsp;&nbsp;&nbsp; 一年多前写的ppt，拿出了和大家分享。自己也顺便回忆一下里面的内容</span></p>
<div id="__ss_11808629" style="width:425px;margin:0 auto;"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/longhao/java-11808629" title="Java并发编程培训">Java并发编程培训</a></strong><object height="355" id="__sse11808629" width="425"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=java-120229230045-phpapp01&amp;stripped_title=java-11808629&amp;userName=longhao" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="wmode" value="transparent" /><embed allowfullscreen="true" allowscriptaccess="always" height="355" name="__sse11808629" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=java-120229230045-phpapp01&amp;stripped_title=java-11808629&amp;userName=longhao" type="application/x-shockwave-flash" width="425" wmode="transparent"></embed></object></p>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/longhao">longhao</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=740</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

