<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet href='http://feed.feedsky.com/styles/temp01.xsl' type='text/xsl' ?><!--这是一个由Feedsy提供技术支持的Feed，为了提高读者阅读的体验，以及满足用户美化自己Feed的需要，我们设计了多种精美的Feed模板，提供给大家选择，所有最终呈现出来的样式，皆由用户自愿选择使用，未经许可，任何团体和个人，请不要擅自修改样式或者盗用，这是对于用户选择权的尊重。--><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:fs="http://www.feedsky.com/namespace/feed" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link href="http://feed.feedsky.com/longhao" type="application/rss+xml" rel="self"></atom:link><fs:self_link href="http://feed.feedsky.com/longhao" type="application/rss+xml"></fs:self_link><lastBuildDate>Wed, 11 Jan 2012 06:16:25 GMT</lastBuildDate><title>简单的龙浩</title><description>简单，清晰，坚持不懈！</description><image><url>http://www.feedsky.com/feed/longhao/sc/gif</url><title>简单的龙浩</title><link>http://www.longtask.com/blog</link></image><link>http://www.longtask.com/blog</link><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><language>en</language><pubDate>Wed, 11 Jan 2012 06:16:25 GMT</pubDate><item><title>Jetty部署中tmpdir导致服务不可用的问题</title><link>http://item.feedsky.com/~feedsky/longhao/~7092337/595515436/5200873/1/item.html</link><content:encoded>&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 问题现象 &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;Java进程存在，Servlet服务存在，cpu使用率低，未发现死锁。重启服务器，问题得到解决。&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 问题分析 &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; 根据tomcat的解压部署方式，发现jetty中设置为：-Djava.io.tmpdir=/tmp ， 根据返回的错误搜索/tmp jetty，发现linux存在watchdong自动清理tmp目录。&lt;/p&gt;
&lt;div style=&quot;border-top: 1px solid #000; border-bottom: 1px solid #000; padding: 9px 0pt 9px 16px; background-color: #000;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;[root@updata jetty]# &lt;strong&gt;cat /etc/cron.daily/tmpwatch&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;#! /bin/sh&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;flags=-umc&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;/usr/sbin/tmpwatch &amp;quot;$flags&amp;quot; -x /tmp/.X11-unix -x /tmp/.XIM-unix \&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -X &amp;#39;/tmp/hsperfdata_*&amp;#39; 10d /tmp&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;/usr/sbin/tmpwatch &amp;quot;$flags&amp;quot; 30d /var/tmp&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;&amp;nbsp; &amp;nbsp; if [ -d &amp;quot;$d&amp;quot; ]; then&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; /usr/sbin/tmpwatch &amp;quot;$flags&amp;quot; -f 30d &amp;quot;$d&amp;quot;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;&amp;nbsp; &amp;nbsp; fi&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color:#fff0f5;&quot;&gt;done&lt;/span&gt;&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;系统默认每10天清理一次/tmp目录。&lt;/p&gt;
&lt;p&gt;Spring会在系统启动加载类到内存中，但是不会加载servlet的相关内容。查看jetty的文档，&lt;strong&gt;&lt;a href=&quot;http://docs.codehaus.org/display/JETTY/Temporary+Directories&quot;&gt;Temporary Directories&lt;/a&gt;&lt;/strong&gt; 有如下说明：&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;【本段文字为翻译】Jetty 本身没有临时目录，每个应用在war解压的时候指定temp目录，JSPs在运行是编译。&lt;/p&gt;
&lt;p&gt;确定一个应用临时目录的算法如下：&lt;/p&gt;
&lt;p&gt;1：尝试使用这个应用明确指定的目录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 webapp.getTempDirectory() 设置了，则使用它，在JVM运行时不要删除这个目录。&lt;/li&gt;
&lt;li&gt;如果web应用的javax.servlet.context.tempdir这个上下文属性设置，这个目录存在，并且可写。则使用它，在JVM运行时不要删除它。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2：基于全局设置创建一个目录。这个目录中在war解压后产生的目录是这样的： &amp;quot;Jetty_&amp;quot;host&amp;quot;&amp;quot;port&amp;quot;&amp;quot;context&amp;quot;&amp;quot;+virtualhost&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 $(jetty.home)/work 存在，不要在JVM运行的时候删除，不能在文件夹存在的时候删除里面的内容&lt;/li&gt;
&lt;li&gt;如果WEB-INF/work存在，不能在jvm运行的时候删除，不能删除文件夹中的内容。&lt;/li&gt;
&lt;li&gt;或者是创建目录 $(java.io.tmpdir) ，在JVM退出的时候删除这个目录，如果该目录存在，删除该目录的内容。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个重要的提示：webapp的临时目录只能在它停止的时候删除里面的内容。&lt;/p&gt;
&lt;p&gt;一旦临时目录被分配，它将作为一个web应用的javax.servlet.context.tempdir的文件实例被设置和检索。&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 解决问题的方法： &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;color:#b22222;&quot;&gt;方法1：在jetty.home目录下面创建一个可写的文件夹work，去掉davinci.sh中的-Djava.io.tmpdir=/tmp 设置。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;方法2：修改davinci.sh中的-Djava.io.tmpdir=/tmp为-Djava.io.tmpdir=指定的目录 ，然后在davinci.sh的stop函数中设置删除该目录中的内容。重要提示：每个应用设置的目录不能相同&lt;/p&gt;
&lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/595515436/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/595515436/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=734</wfw:commentRss><slash:comments>0</slash:comments><description>&amp;#160;&amp;#160;&amp;#160;&amp;#160; 问题现象 

Java进程存在，Servlet服务存在，cpu使用率低，未发现死锁。重启服务器，问题得到解决。

&amp;#160;&amp;#160;&amp;#160;&amp;#160; 问题分析 

&amp;#160; &amp;#160; 根据tomcat的解压部署方式，发现jetty中设置为：-Djava.io.tmpdir=/tmp ， 根据返回的错误搜索/tmp jetty，发现linux存在watchdong自动清理tmp目录。

[root@updata jetty]# cat /etc/cron.daily/tmpwatch
#! /bin/sh
flags=-umc
/usr/sbin/tmpwatch &amp;#34;$flags&amp;#34; -x /tmp/.X11-unix -x /tmp/.XIM-unix \
&amp;#160; &amp;#160; &amp;#160; &amp;#160; -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \
&amp;#160; &amp;#160; &amp;#160; &amp;#160; -X &amp;#39;/tmp/hsperfdata_*&amp;#39; 10d /tmp
/usr/sbin/tmpwatch &amp;#34;$flags&amp;#34; 30d /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do
&amp;#160; &amp;#160; if [ -d &amp;#34;$d&amp;#34; ]; then
&amp;#160; &amp;#160; &amp;#160; &amp;#160; /usr/sbin/tmpwatch  &lt;a href=&quot;http://www.longtask.com/blog/?p=734&quot; class=&quot;more-link&quot;&gt;More &amp;#62;&lt;/a&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/595515436/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/595515436/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>servlet</category><category>Java</category><category>jetty</category><pubDate>Wed, 11 Jan 2012 14:16:25 +0800</pubDate><author>longhao</author><comments>http://www.longtask.com/blog/?p=734#comments</comments><guid isPermaLink="false">http://www.longtask.com/blog/?p=734</guid><dc:creator>longhao</dc:creator><fs:srclink>http://www.longtask.com/blog/?p=734</fs:srclink><fs:srcfeed>http://www.longtask.com/blog/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/longhao/~7092337/595515436/5200873</fs:itemid></item><item><title>Google Guava v11 Collections示例</title><link>http://item.feedsky.com/~feedsky/longhao/~7092337/594296585/5200873/1/item.html</link><content:encoded>&lt;p&gt;&lt;a href=&quot;http://code.google.com/p/guava-libraries/&quot; target=&quot;_blank&quot;&gt;Guava&lt;/a&gt; 中文是石榴的意思，该项目是 Google 的一个开源项目，包含许多 Google 核心的 Java 常用库。目前主要包含：&lt;/p&gt;
&lt;ul style=&quot;padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 20px; margin-right: 20px; margin-bottom: 20px; margin-left: 20px; list-style-position: inside; color: rgb(51, 51, 51); font-family: Verdana, Simsun, sans-serif; font-size: 13px; line-height: 20px; text-align: left; &quot;&gt;
&lt;li&gt;com.google.common.annotations&lt;/li&gt;
&lt;li&gt;com.google.common.base&lt;/li&gt;
&lt;li&gt;com.google.common.cache&lt;/li&gt;
&lt;li&gt;com.google.common.collect&lt;/li&gt;
&lt;li&gt;com.google.common.eventbus&lt;/li&gt;
&lt;li&gt;com.google.common.io&lt;/li&gt;
&lt;li&gt;com.google.common.net&lt;/li&gt;
&lt;li&gt;com.google.common.primitives&lt;/li&gt;
&lt;li&gt;com.google.common.util.concurrent&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里先介绍一下最常用的&lt;span style=&quot;color: rgb(51, 51, 51); font-family: Verdana, Simsun, sans-serif; font-size: 13px; line-height: 20px; text-align: left; &quot;&gt;com.google.common.collect包中的最常用的一些API，仅仅讨论一下API的使用方法，没有讨论到实现细节。&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1：Collections的构造方法 &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;我们平时直接创建Collections对象的方法一般都是用new关键字，有泛型的情况下看起来会比较长：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;Map&amp;lt;String , Map&amp;lt;String , String&amp;gt;&amp;gt; see = new HashMap&amp;lt;String, Map&amp;lt;String,String&amp;gt;&amp;gt;();&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;在java7中，这个初始化做了简化：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;Map&amp;lt;String , Map&amp;lt;String , String&amp;gt;&amp;gt; see = new HashMap&amp;lt;&amp;gt;();&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;可以通过Guava的API来这样写：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;Map&amp;lt;String , Map&amp;lt;String , String&amp;gt;&amp;gt; see = Maps.newHashMap();&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;得到一个有size的Map：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;Map&amp;lt;String , Map&amp;lt;String , String&amp;gt;&amp;gt; see = Maps.newHashMapWithExpectedSize(32);&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;在JDK的collection类型，在Guava中都可以找到相关的static的构造方法，例如：&lt;strong&gt;Lists ， Sets ， Maps ， Queues&lt;/strong&gt;。新的colleciont类型提供了直接构造的方法，例如：HashMultimap&amp;lt;String, String&amp;gt; multiMap = HashMultimap.create();&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2：有限功能的函数式编程 &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;介绍2个重要的接口：&lt;/p&gt;
&lt;p&gt;com.google.common.base.&lt;strong&gt;Function&lt;/strong&gt; : 根据输入值来得到输出值&lt;/p&gt;
&lt;p&gt;com.google.common.base.&lt;strong&gt;Predicate&lt;/strong&gt; : 根据输入值得到 true 或者 false&lt;/p&gt;
&lt;p&gt;拿Collections2中有2个函数式编程的接口：filter , transform ,例如 ：在Collection&amp;lt;Integer&amp;gt;中过滤大于某数的内容：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;Collection&amp;lt;Integer&amp;gt; filterList = Collections2.filter(collections&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;, new Predicate&amp;lt;Integer&amp;gt;(){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; @Override&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; public boolean apply(Integer input) {&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(input &amp;gt; 4)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return false;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return true;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;把Lis&amp;lt;Integer&amp;gt;中的Integer类型转换为String , 并添加test作为后缀字符：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;List&amp;lt;String&amp;gt; c2 = Lists.transform(list, new Function&amp;lt;Integer , String&amp;gt;(){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; @Override&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; public String apply(Integer input) {&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return String.valueOf(input) + &amp;quot;test&amp;quot;;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;});&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;需要说明的是每次调用返回都是新的对象，同时操作过程不是线程安全的。&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3：Multimap and BiMap &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;Map中一个key只能有一个，后续put进去的内容会覆盖前面的内容，有些业务需要有相同的key，但是有不同的内容，Guava中提供了&lt;/p&gt;
&lt;p&gt;Multimaps 来解决这个问题。&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Multimap&amp;lt;String, String&amp;gt; prosons = HashMultimap.create();&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; prosons.put(&amp;quot;longhao&amp;quot;, &amp;quot;hubei&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; prosons.put(&amp;quot;lilei&amp;quot; , &amp;quot;henan&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; prosons.put(&amp;quot;longhao&amp;quot;, &amp;quot;shanxi&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; prosons.put(&amp;quot;liuxia&amp;quot;, &amp;quot;beijing&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; prosons.put(&amp;quot;lilei&amp;quot;, &amp;quot;hainan&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Iterator&amp;lt;String&amp;gt; it = prosons.get(&amp;quot;longhao&amp;quot;).iterator();&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; while(it.hasNext()){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(it.next());&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;BiMap可以有相同的key，但是不能有相同的value，如果不同的key设置了相同的value，则会抛出IllegalArgumentException异常，可以通过inverse()来反转kv，values()来获取value的set。&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;public void biMapShouldOnlyHaveUniqueValues() {&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;BiMap&amp;lt;Integer, String&amp;gt; biMap = HashBiMap.create();&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;biMap.put(1, &amp;quot;a&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;biMap.put(2, &amp;quot;b&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;biMap.put(3, &amp;quot;a&amp;quot;); //argh! an exception&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4：tables &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;给出一个columns, rows , values， 这个API和Map&amp;lt;K , Map&amp;lt;K , V&amp;gt;&amp;gt;形式差不多，多了一些封装。例子：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;static void tables(){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Table&amp;lt;Integer , String , Integer&amp;gt; user = HashBasedTable.create();&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; user.put(1, &amp;quot;longhao&amp;quot;, 29);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; user.put(1, &amp;quot;shuaige&amp;quot;, 29);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; user.put(2, &amp;quot;xiaomi&amp;quot;, 1);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; user.put(3, &amp;quot;soso&amp;quot;, 3);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(user.containsColumn(&amp;quot;soso&amp;quot;));//true&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(user.containsColumn(&amp;quot;3&amp;quot;));//false&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(user.contains(1, &amp;quot;xiaomi&amp;quot;));//false&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(user.contains(1, &amp;quot;meinv&amp;quot;));//true&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(user.row(1));//{shuaige=29, longhao=29}&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5：更简洁的判断&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;使用Preconditions中的方法来判断是否为空等操作，这个操作和spring，apache common-lang中的API类似&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;import static com.google.common.base.Preconditions.checkArgument;&lt;/p&gt;
&lt;p&gt;import static com.google.common.base.Preconditions.checkNotNull;&lt;/p&gt;
&lt;p&gt;static void checkParam(String name , Integer passwd){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; checkNotNull(name , passwd);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; checkArgument(&amp;quot;&amp;quot; != name , passwd &amp;gt; 0);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;Common-lang，spring中的方法需要逐个调用。而Guava中支持。&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6：约束 &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;对Collection中的新加入元素做约束，只有符合条件的元素才能够被添加到Collection中，可以使用Constraint类来操作。&lt;/p&gt;
&lt;p&gt;示例代码：&lt;/p&gt;
&lt;div style=&quot;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;&gt;
&lt;p&gt;import static com.google.common.collect.Constraints.constrainedList;&lt;/p&gt;
&lt;p&gt;static void constraintExam(){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Constraint&amp;lt;String&amp;gt; chkListStr = new Constraint&amp;lt;String&amp;gt;(){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; @Override&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; public String checkElement(String element) {&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if(element.startsWith(&amp;quot;h&amp;quot;)){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; throw new IllegalArgumentException(&amp;quot;不允许有h开头的内容&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return element;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; };&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;String&amp;gt; list = Lists.newArrayList(&amp;quot;li&amp;quot;,&amp;quot;hao&amp;quot;,&amp;quot;a&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;String&amp;gt; conList = constrainedList(list, chkListStr);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; conList.add(&amp;quot;soso&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; conList.add(&amp;quot;hqb&amp;quot;);// throw IllegalArgumentException&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; for(String str : list){&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println(str);&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/p&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 参考资料 &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;&lt;a href=&quot;http://blog.solidcraft.eu/2010/10/googole-guava-v07-examples.html&quot;&gt;http://blog.solidcraft.eu/2010/10/googole-guava-v07-examples.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://insightfullogic.com/blog/2011/oct/21/5-reasons-use-guava/#&quot;&gt;http://insightfullogic.com/blog/2011/oct/21/5-reasons-use-guava/#&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://codingjunkie.net/google-guava-cache/&quot;&gt;http://codingjunkie.net/google-guava-cache/&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296585/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296585/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=730</wfw:commentRss><slash:comments>0</slash:comments><description>Guava 中文是石榴的意思，该项目是 Google 的一个开源项目，包含许多 Google 核心的 Java 常用库。目前主要包含：

com.google.common.annotations
com.google.common.base
com.google.common.cache
com.google.common.collect
com.google.common.eventbus
com.google.common.io
com.google.common.net
com.google.common.primitives
com.google.common.util.concurrent

这里先介绍一下最常用的com.google.common.collect包中的最常用的一些API，仅仅讨论一下API的使用方法，没有讨论到实现细节。
&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1：Collections的构造方法 

我们平时直接创建Collections对象的方法一般都是用new关键字，有泛型的情况下看起来会比较长：

Map&amp;#60;String , Map&amp;#60;String , String&amp;#62;&amp;#62; see = new HashMap&amp;#60;String, Map&amp;#60;String,String&amp;#62;&amp;#62;();

在java7中，这个初始化做了简化：

Map&amp;#60;String , Map&amp;#60;String , String&amp;#62;&amp;#62; see = new HashMap&amp;#60;&amp;#62;();

可以通过Guava的API来这样写：

Map&amp;#60;String , Map&amp;#60;String , String&amp;#62;&amp;#62; see = Maps.newHashMap();

得到一个有size的Map：

Map&amp;#60;String , Map&amp;#60;String , String&amp;#62;&amp;#62; see = Maps.newHashMapWithExpectedSize(32);

在JDK的collection类型，在Guava中都可以找到相关的static的构造方法，例如：Lists ， Sets ， Maps ， Queues。新的colleciont类型提供了直接构造的方法，例如：HashMultimap&amp;#60;String, String&amp;#62; multiMap = HashMultimap.create();

&amp;#160;&amp;#160;&amp;#160;&amp;#160;2：有限功能的函数式编程 

介绍2个重要的接口：
com.google.common.base.Function : 根据输入值来得到输出值
com.google.common.base.Predicate :  &lt;a href=&quot;http://www.longtask.com/blog/?p=730&quot; class=&quot;more-link&quot;&gt;More &amp;#62;&lt;/a&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296585/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296585/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>guava</category><category>Java</category><pubDate>Sat, 07 Jan 2012 12:50:21 +0800</pubDate><author>longhao</author><comments>http://www.longtask.com/blog/?p=730#comments</comments><guid isPermaLink="false">http://www.longtask.com/blog/?p=730</guid><dc:creator>longhao</dc:creator><fs:srclink>http://www.longtask.com/blog/?p=730</fs:srclink><fs:srcfeed>http://www.longtask.com/blog/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/longhao/~7092337/594296585/5200873</fs:itemid></item><item><title>Vim Get Start</title><link>http://item.feedsky.com/~feedsky/longhao/~7092337/594296586/5200873/1/item.html</link><content:encoded>&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;slideshare.net对微软雅黑字体支持有问题，感兴趣的请&lt;a href=&quot;http://www.slideshare.net/longhao/vim-get-start10&quot; target=&quot;_blank&quot;&gt;下载&lt;/a&gt;。&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div id=&quot;__ss_10665971&quot; style=&quot;width:425px&quot;&gt;&lt;strong style=&quot;display:block;margin:12px 0 4px&quot;&gt;&lt;a href=&quot;http://www.slideshare.net/longhao/vim-get-start10&quot; target=&quot;_blank&quot; title=&quot;Vim get start_1.0&quot;&gt;Vim get start_1.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: right; &quot;&gt;&lt;iframe frameborder=&quot;0&quot; height=&quot;355&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;http://www.slideshare.net/slideshow/embed_code/10665971&quot; width=&quot;425&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;div style=&quot;padding-top: 5px; padding-right: 0px; padding-bottom: 12px; padding-left: 0px; text-align: right; &quot;&gt;View more &lt;a href=&quot;http://www.slideshare.net/&quot; target=&quot;_blank&quot;&gt;presentations&lt;/a&gt; from &lt;a href=&quot;http://www.slideshare.net/longhao&quot; target=&quot;_blank&quot;&gt;longhao&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296586/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296586/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=726</wfw:commentRss><slash:comments>0</slash:comments><description>slideshare.net对微软雅黑字体支持有问题，感兴趣的请下载。
Vim get start_1.0

View more presentations from longhao&lt;img src=&quot;http://www1.feedsky.com/t1/594296586/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296586/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Linux</category><category>python</category><category>vim</category><pubDate>Thu, 22 Dec 2011 22:09:47 +0800</pubDate><author>longhao</author><comments>http://www.longtask.com/blog/?p=726#comments</comments><guid isPermaLink="false">http://www.longtask.com/blog/?p=726</guid><dc:creator>longhao</dc:creator><fs:srclink>http://www.longtask.com/blog/?p=726</fs:srclink><fs:srcfeed>http://www.longtask.com/blog/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/longhao/~7092337/594296586/5200873</fs:itemid></item><item><title>定制Jetty8方式启动web应用</title><link>http://item.feedsky.com/~feedsky/longhao/~7092337/594296587/5200873/1/item.html</link><content:encoded>&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1：Jetty的4种web应用部署方式（不包括嵌入启动）：&lt;br /&gt;
	&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;1：直接修改${JETTY_HOME}/etc/jetty.xml的配置来部署应用；&lt;/p&gt;
&lt;p&gt;2：把war包扔到${JETTY_HOME}/webapps目录中，自动被WebAppDeployer发现去部署；&lt;/p&gt;
&lt;p&gt;3：在${JETTY_HOME}/contents中增加一个配置文件（模仿test.xml的配置），由ContextDeployer自动发现去部署；&lt;/p&gt;
&lt;p&gt;4：定制部署启动配置文件；&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; 前面3中部署方式在J&lt;a href=&quot;http://docs.codehaus.org/display/JETTY/Running+Jetty-7.0.x&quot;&gt;etty7的部署方式&lt;/a&gt;中讲述的较为清楚。&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2：定制化启动Jetty:&lt;br /&gt;
	&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; 由于我们每个应用需要不同端口启动，这样在停止A应用的情况下，B应用不会受到影响。同时，我们希望在每台服务器上只有一份jetty，每个应用的配置文件应该是独立的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.1：jetty容器配置文件&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; 在start.ini中配置了etc/jetty.xml ， etc/jetty-webapps.xml （WebAppDeployer），etc/jetty-contexts.xml（ContextDeployer）三个文件，代表在默认情况下启动jetty，web应用3种部署都是支持的。WebAppDeployer则是会扫描${JETTY_HOME}/webapps目录，寻找war包并部署；ContextDeployer会扫描${JETTY_HOME}/contents目录，找到可以部署的context配置文件并部署。&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; 所以定制jetty之前，我们需要在start.ini中把这3行注释掉。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.2：web应用配置&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; 复制${JETTY_HOME}/etc/jetty.xml文件到bin目录下面，修改port和confidentialPort为自己应用的端口号。在&amp;lt;Array type=&amp;quot;org.eclipse.jetty.server.Handler&amp;quot;&amp;gt;中添加需要部署的war包得Item，如下注意（contextPath和war值）：&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Item&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;New class=&amp;quot;org.eclipse.jetty.webapp.WebAppContext&amp;quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Set name=&amp;quot;contextPath&amp;quot;&amp;gt;/aaa&amp;lt;/Set&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Set name=&amp;quot;war&amp;quot;&amp;gt;/opt/longtask/aaa/webapps/aaa.war&amp;lt;/Set&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Set name=&amp;quot;defaultsDescriptor&amp;quot;&amp;gt;&amp;lt;SystemProperty name=&amp;quot;jetty.home&amp;quot; default=&amp;quot;.&amp;quot;/&amp;gt;/etc/webdefault.xml&amp;lt;/Set&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Set name=&amp;quot;extractWAR&amp;quot;&amp;gt;true&amp;lt;/Set&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Set name=&amp;quot;copyWebDir&amp;quot;&amp;gt;false&amp;lt;/Set&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;Call name=&amp;quot;addServlet&amp;quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Arg&amp;gt;org.eclipse.jetty.servlet.DefaultServlet&amp;lt;/Arg&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;Arg&amp;gt;/&amp;lt;/Arg&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/Call&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/New&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/Item&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.3：启动应用（省略相关sh脚本）&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;JETTY_CONFIG=&amp;quot;${PWD}/jetty-${APP_NAME}.xml ${PWD}/jetty-logging.xml&amp;quot;&lt;/p&gt;
&lt;p&gt;JETTY_OPTS=&amp;quot;-jar ${JETTY_HOME}/start.jar &amp;#8211;pre=${JETTY_CONFIG}&amp;quot;&lt;/p&gt;
&lt;p&gt;java -server $JDK_OPTS $JETTY_OPTS &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.4：OPTIONS的说明&lt;/strong&gt;&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;在jetty8中通过java -jar start.jar &amp;#8211;version命令可以查看到默认启动的OPTIONS：&lt;/p&gt;
&lt;p&gt;Active Options: [Server, annotations, ext, jdbc, jmx, jsp, jta, plus, resources, websocket]&lt;/p&gt;
&lt;p&gt;如果要启动其他OPTIONS，需要自己添加。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3：FAQ:&lt;br /&gt;
	&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;p&gt;3.1：无法启动，报端口错误：&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;Caused by: java.net.BindException: Address already in use&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at sun.nio.ch.Net.bind(Native Method)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:126)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.server.nio.SelectChannelConnector.open(SelectChannelConnector.java:172)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.server.AbstractConnector.doStart(AbstractConnector.java:300)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.server.nio.SelectChannelConnector.doStart(SelectChannelConnector.java:250)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.server.Server.doStart(Server.java:273)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.xml.XmlConfiguration$1.run(XmlConfiguration.java:1203)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at java.security.AccessController.doPrivileged(Native Method)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1126)&lt;/p&gt;
&lt;p&gt;通过lsof -i:port来查看端口是否被占用，如果被占用，需要修改jetty配置文件中的port来启动&lt;/p&gt;
&lt;p&gt;3.2：在去掉start.ini中注释掉jetty.xml后，制定自己的jetty.xml后报错。&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p&gt;问题：&lt;/p&gt;
&lt;p&gt;java.io.FileNotFoundException: Unable to find XML Config: etc/jetty.xml&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.start.Main.resolveXmlConfig(Main.java:671)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.start.Main.resolveXmlConfigs(Main.java:888)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.start.Main.start(Main.java:508)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.start.Main.parseCommandLine(Main.java:265)&lt;/p&gt;
&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; at org.eclipse.jetty.start.Main.main(Main.java:79)&lt;/p&gt;
&lt;p&gt;需要在&amp;#8211;pre中添加启动项，不是在-jar start.jar后面添加&lt;/p&gt;
&lt;p&gt;3.3：网上说war包需要解压缩，是错误的，jetty8不需要解压的。&lt;/p&gt;
&lt;div style=&quot;height:1px;border-bottom:1px dashed #ccc;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p style=&quot;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);&quot;&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4：参考文档：&lt;br /&gt;
	&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;border-left: 2px solid rgb(204, 204, 204); padding-left: 6px; margin-left: 6px; margin-bottom: 10px;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://wiki.eclipse.org/Jetty/Howto/WebappPerConnector&quot;&gt;Serving Webapp A Only from Port A and Webapp B Only from Port B&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.codehaus.org/display/JETTY/Running+Jetty-7.0.x&quot;&gt;Running Jetty-7.0.x&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wiki.eclipse.org/Jetty/Reference/jetty.xml_syntax&quot;&gt;Jetty/Reference/jetty.xml syntax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296587/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296587/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=724</wfw:commentRss><slash:comments>0</slash:comments><description>&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1：Jetty的4种web应用部署方式（不包括嵌入启动）：
	

1：直接修改${JETTY_HOME}/etc/jetty.xml的配置来部署应用；
2：把war包扔到${JETTY_HOME}/webapps目录中，自动被WebAppDeployer发现去部署；
3：在${JETTY_HOME}/contents中增加一个配置文件（模仿test.xml的配置），由ContextDeployer自动发现去部署；
4：定制部署启动配置文件；
&amp;#160; &amp;#160; 前面3中部署方式在Jetty7的部署方式中讲述的较为清楚。

&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2：定制化启动Jetty:
	

&amp;#160; &amp;#160; 由于我们每个应用需要不同端口启动，这样在停止A应用的情况下，B应用不会受到影响。同时，我们希望在每台服务器上只有一份jetty，每个应用的配置文件应该是独立的。
2.1：jetty容器配置文件
&amp;#160;
&amp;#160; &amp;#160; 在start.ini中配置了etc/jetty.xml ， etc/jetty-webapps.xml （WebAppDeployer），etc/jetty-contexts.xml（ContextDeployer）三个文件，代表在默认情况下启动jetty，web应用3种部署都是支持的。WebAppDeployer则是会扫描${JETTY_HOME}/webapps目录，寻找war包并部署；ContextDeployer会扫描${JETTY_HOME}/contents目录，找到可以部署的context配置文件并部署。
&amp;#160; &amp;#160; 所以定制jetty之前，我们需要在start.ini中把这3行注释掉。
2.2：web应用配置
&amp;#160;
&amp;#160; &amp;#160; 复制${JETTY_HOME}/etc/jetty.xml文件到bin目录下面，修改port和confidentialPort为自己应用的端口号。在&amp;#60;Array type=&amp;#34;org.eclipse.jetty.server.Handler&amp;#34;&amp;#62;中添加需要部署的war包得Item，如下注意（contextPath和war值）：
&amp;#160; &amp;#160; &amp;#160;&amp;#60;Item&amp;#62;
&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;&amp;#60;New class=&amp;#34;org.eclipse.jetty.webapp.WebAppContext&amp;#34;&amp;#62;
&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#60;Set name=&amp;#34;contextPath&amp;#34;&amp;#62;/aaa&amp;#60;/Set&amp;#62;
&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#60;Set name=&amp;#34;war&amp;#34;&amp;#62;/opt/longtask/aaa/webapps/aaa.war&amp;#60;/Set&amp;#62;
&amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160;  &lt;a href=&quot;http://www.longtask.com/blog/?p=724&quot; class=&quot;more-link&quot;&gt;More &amp;#62;&lt;/a&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296587/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296587/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>eclipse</category><category>Java</category><category>jetty</category><pubDate>Mon, 28 Nov 2011 23:20:38 +0800</pubDate><author>longhao</author><comments>http://www.longtask.com/blog/?p=724#comments</comments><guid isPermaLink="false">http://www.longtask.com/blog/?p=724</guid><dc:creator>longhao</dc:creator><fs:srclink>http://www.longtask.com/blog/?p=724</fs:srclink><fs:srcfeed>http://www.longtask.com/blog/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/longhao/~7092337/594296587/5200873</fs:itemid></item><item><title>Nginx 还是 Varnish?</title><link>http://item.feedsky.com/~feedsky/longhao/~7092337/594296588/5200873/1/item.html</link><content:encoded>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; height=&quot;438&quot; src=&quot;http://www.longtask.com/blog/wp-content/uploads/varnish部署图.jpg&quot; width=&quot;376&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;单文件压力测试&lt;br /&gt;
	&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 准备用varnish来做图片缓冲服务器，用ab测试了一下单文件读取。发现nginx和varnish都可以把网卡写满（千兆网卡速度》110M/S）。调整了ab测试的并发数，在同样的配置的机器上，发现nginx的在1W并发情况下，依然可以运行；varnish在3600并发测试的时候，直接开始报错。不能不说nginx是神器，varnish不靠谱么？&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 14px;&quot;&gt;&lt;/p&gt;
&lt;p&gt;	&lt;strong&gt;多文件压力测试&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;到图片服务器的图片目录执行：find . -name &amp;quot;*.jpg&amp;quot; -print &amp;gt; jpg_url.txt&lt;br /&gt;
		&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;合计得到38W张图片，用python代码切割成10个文件。&lt;br /&gt;
		&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;启动5个python进程访问其中5个url，varnish即使有缓存也无法写满网卡，修改为启动10个python进程，varnish有缓存可以写满网卡。&lt;br /&gt;
		&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;启动10个经常多文件访问nginx服务器，发现网卡平均流量为60M左右。&lt;br /&gt;
		&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;最后把所有文件用varnish缓存，内存占用大小为19G多。平均每张图片大小为50K&lt;br /&gt;
		&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;br /&gt;
	结论&lt;br /&gt;
	&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们图片的平均大小为50K，varnish的3500的并发，最大处理为175MB，超过网卡125MB的峰值。所以还是用varnish比较靠谱。如果图片的大小为10K，直接用nginx做反向代理或许更好。&lt;br /&gt;
	&lt;/span&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296588/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296588/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=720</wfw:commentRss><slash:comments>1</slash:comments><description>单文件压力测试
	

&amp;#160;&amp;#160;&amp;#160; 准备用varnish来做图片缓冲服务器，用ab测试了一下单文件读取。发现nginx和varnish都可以把网卡写满（千兆网卡速度》110M/S）。调整了ab测试的并发数，在同样的配置的机器上，发现nginx的在1W并发情况下，依然可以运行；varnish在3600并发测试的时候，直接开始报错。不能不说nginx是神器，varnish不靠谱么？

	多文件压力测试


到图片服务器的图片目录执行：find . -name &amp;#34;*.jpg&amp;#34; -print &amp;#62; jpg_url.txt
		
合计得到38W张图片，用python代码切割成10个文件。
		
启动5个python进程访问其中5个url，varnish即使有缓存也无法写满网卡，修改为启动10个python进程，varnish有缓存可以写满网卡。
		
启动10个经常多文件访问nginx服务器，发现网卡平均流量为60M左右。
		
最后把所有文件用varnish缓存，内存占用大小为19G多。平均每张图片大小为50K
		


	结论
	

&amp;#160;&amp;#160;&amp;#160; 我们图片的平均大小为50K，varnish的3500的并发，最大处理为175MB，超过网卡125MB的峰值。所以还是用varnish比较靠谱。如果图片的大小为10K，直接用nginx做反向代理或许更好。&lt;img src=&quot;http://www1.feedsky.com/t1/594296588/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296588/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>varnish</category><category>Linux</category><category>nginx</category><pubDate>Tue, 22 Nov 2011 16:19:44 +0800</pubDate><author>longhao</author><comments>http://www.longtask.com/blog/?p=720#comments</comments><guid isPermaLink="false">http://www.longtask.com/blog/?p=720</guid><dc:creator>longhao</dc:creator><fs:srclink>http://www.longtask.com/blog/?p=720</fs:srclink><fs:srcfeed>http://www.longtask.com/blog/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/longhao/~7092337/594296588/5200873</fs:itemid></item><item><title>通过Sonar来提高类的内聚性</title><link>http://item.feedsky.com/~feedsky/longhao/~7092337/594296589/5200873/1/item.html</link><content:encoded>&lt;p&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 14px; &quot;&gt;&amp;nbsp; &amp;nbsp; 在我们学习面向对象语言时，两个概念相当难理解：&lt;strong&gt;类必须高内聚，低耦合&lt;/strong&gt;。今天的博文我们将解释这两个概念的重要性，同时展示Sonar如何帮助大家来评估类的内聚性。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 几周前，我开始讨论如何《&lt;a href=&quot;http://sonar.codehaus.org/fight-back-design-erosion-by-breaking-cycles-with-sonar/&quot; target=&quot;_blank&quot;&gt;Fight Back Design Erosion by Breaking Cycles with Sonar&lt;/a&gt;》，我提到好的设计应该能够通过很小的努力编写的新代码块就可以替换系统中的相关部分代码。第一个层面需要从&amp;ldquo;宏观水平&amp;rdquo;来看，例如：确保你的&amp;ldquo;packages&amp;rdquo; 没有包的循环依赖；但得到任何水平的模块化设计,你也需要考虑&amp;ldquo;微观&amp;rdquo;，例如，你的类/方法要保证高内聚，低耦合。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 耦合性是指每个类对其他类的依赖程度。换句话说，如果一个类是高耦合的，那么对这个类的修改将直接或间接影响到其他许多类：不是我所说的大模块！你可以通过反转控制来降低类之间的耦合。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 内聚是指一个类中的方法的紧密程度。当一个类中的两个方法不使用一个共同属性或者方法，如果遵守单一职责原则，这意味着它们没有共用任何东西或者它们就不属于同一个类。换句话说，你应该把这个类分解为多个新类来达到类级别模块化的目的。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 所以类应该尽可能的降低耦合关系，而方法需要刚好相反的来提高内聚性。这和一个灵活的组织非常相似：每个团队（class）应该非常自主（低耦合），但是团队中所有的成员（methods）应该彼此联系非常精密（高内聚）&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&lt;strong&gt;&amp;nbsp; &amp;nbsp; Sonar2.0带来了实验性且有前途的度量：用LCOM4 (缺乏内聚性的方法)来衡量类的内聚性。解释这个度量是非常简单的，值1表示这个类只有一个职责(好)，值X代码这个类有X个职责（差），值X得类应该重构/分割。&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 这里没有魔法，只有尝试。让我们用Driver这个类来举例。这个类有2个域：Car 和 Brain，包含5个方法：drive(), goTo(), stop(), getAngry() ， drinkCoffee()。下面是这些组件之间的依赖关系图，这个类有3个不同的职责，所以LCOM4 = 3 ,这打破了单一职责的原则。&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; height=&quot;315&quot; src=&quot;http://sonar.codehaus.org/wp-content/uploads/2010/03/lcom4_story.png&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 当进入Sonar，事情仍然非常简单。在项目面板的第一个窗口小部件就可以快速的查看：&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; height=&quot;153&quot; src=&quot;http://sonar.codehaus.org/wp-content/uploads/2010/03/sonar_lcom4_widget.png&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 在那里，你可以点击下面的链接去查看可疑类。了解一个类的LCOM4只是一个很好的起点，仅仅了解是绝对不够的。点击你感兴趣的类，你将会看到需要内聚的方法块。重构就此开始！&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center; &quot;&gt;&lt;img alt=&quot;&quot; height=&quot;213&quot; src=&quot;http://sonar.codehaus.org/wp-content/uploads/2010/03/lcom4_details_viewer.png&quot; width=&quot;500&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 你可以查看Stuart Gunter的文章《&lt;a href=&quot;http://www.g3it.com/technical/java/assessing-the-single-responsibility-principle-with-lcom4-and-sonar-2-0/&quot; target=&quot;_blank&quot;&gt;Assessing the Single Responsibility Principle with LCOM4 with Sonar 2.0&lt;/a&gt;》。这个反馈是通过实践帮助我们改进相关的度量算法。&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size:14px;&quot;&gt;&amp;nbsp; &amp;nbsp; 说明：翻译文章来源地址：《&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: bold; &quot;&gt;&lt;a href=&quot;http://www.sonarsource.org/clean-up-design-at-class-level-with-sonar/&quot; target=&quot;_blank&quot;&gt;Clean Up Design at Class Level with Sonar&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-weight: normal; &quot;&gt;》&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296589/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296589/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</content:encoded><wfw:commentRss>http://www.longtask.com/blog/?feed=rss2&amp;p=716</wfw:commentRss><slash:comments>0</slash:comments><description>&amp;#160; &amp;#160; 在我们学习面向对象语言时，两个概念相当难理解：类必须高内聚，低耦合。今天的博文我们将解释这两个概念的重要性，同时展示Sonar如何帮助大家来评估类的内聚性。
&amp;#160; &amp;#160; 几周前，我开始讨论如何《Fight Back Design Erosion by Breaking Cycles with Sonar》，我提到好的设计应该能够通过很小的努力编写的新代码块就可以替换系统中的相关部分代码。第一个层面需要从&amp;#8220;宏观水平&amp;#8221;来看，例如：确保你的&amp;#8220;packages&amp;#8221; 没有包的循环依赖；但得到任何水平的模块化设计,你也需要考虑&amp;#8220;微观&amp;#8221;，例如，你的类/方法要保证高内聚，低耦合。
&amp;#160; &amp;#160; 耦合性是指每个类对其他类的依赖程度。换句话说，如果一个类是高耦合的，那么对这个类的修改将直接或间接影响到其他许多类：不是我所说的大模块！你可以通过反转控制来降低类之间的耦合。
&amp;#160; &amp;#160; 内聚是指一个类中的方法的紧密程度。当一个类中的两个方法不使用一个共同属性或者方法，如果遵守单一职责原则，这意味着它们没有共用任何东西或者它们就不属于同一个类。换句话说，你应该把这个类分解为多个新类来达到类级别模块化的目的。
&amp;#160; &amp;#160; 所以类应该尽可能的降低耦合关系，而方法需要刚好相反的来提高内聚性。这和一个灵活的组织非常相似：每个团队（class）应该非常自主（低耦合），但是团队中所有的成员（methods）应该彼此联系非常精密（高内聚）
&amp;#160; &amp;#160; Sonar2.0带来了实验性且有前途的度量：用LCOM4 (缺乏内聚性的方法)来衡量类的内聚性。解释这个度量是非常简单的，值1表示这个类只有一个职责(好)，值X代码这个类有X个职责（差），值X得类应该重构/分割。
&amp;#160; &amp;#160; 这里没有魔法，只有尝试。让我们用Driver这个类来举例。这个类有2个域：Car 和 Brain，包含5个方法：drive(), goTo(), stop(), getAngry() ， drinkCoffee()。下面是这些组件之间的依赖关系图，这个类有3个不同的职责，所以LCOM4 = 3 ,这打破了单一职责的原则。

&amp;#160; &amp;#160; 当进入Sonar，事情仍然非常简单。在项目面板的第一个窗口小部件就可以快速的查看：

&amp;#160; &amp;#160; 在那里，你可以点击下面的链接去查看可疑类。了解一个类的LCOM4只是一个很好的起点，仅仅了解是绝对不够的。点击你感兴趣的类，你将会看到需要内聚的方法块。重构就此开始！

&amp;#160; &amp;#160; 你可以查看Stuart Gunter的文章《Assessing the Single Responsibility Principle with LCOM4 with Sonar 2.0》。这个反馈是通过实践帮助我们改进相关的度量算法。
&amp;#160; &amp;#160; 说明：翻译文章来源地址：《Clean Up Design  &lt;a href=&quot;http://www.longtask.com/blog/?p=716&quot; class=&quot;more-link&quot;&gt;More &amp;#62;&lt;/a&gt;&lt;img src=&quot;http://www1.feedsky.com/t1/594296589/longhao/feedsky/s.gif?r=http://item.feedsky.com/~feedsky/longhao/~7092337/594296589/5200873/1/item.html&quot; border=&quot;0&quot; height=&quot;0&quot; width=&quot;0&quot; style=&quot;position:absolute&quot; /&gt;</description><category>Java</category><category>sonar</category><pubDate>Mon, 21 Nov 2011 15:29:24 +0800</pubDate><author>longhao</author><comments>http://www.longtask.com/blog/?p=716#comments</comments><guid isPermaLink="false">http://www.longtask.com/blog/?p=716</guid><dc:creator>longhao</dc:creator><fs:srclink>http://www.longtask.com/blog/?p=716</fs:srclink><fs:srcfeed>http://www.longtask.com/blog/?feed=rss2</fs:srcfeed><fs:itemid>feedsky/longhao/~7092337/594296589/5200873</fs:itemid></item></channel></rss>
