﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-xiaomage234-随笔分类-web tools</title><link>http://www.blogjava.net/xiaomage234/category/28303.html</link><description>生命本就是一次凄美的漂流，记忆中放不下的，永远是孩提时代的那一份浪漫与纯真！</description><language>zh-cn</language><lastBuildDate>Wed, 13 Apr 2016 06:07:23 GMT</lastBuildDate><pubDate>Wed, 13 Apr 2016 06:07:23 GMT</pubDate><ttl>60</ttl><item><title>Jquery Ajax和getJSON获取后台普通Json数据和层级Json数据解析</title><link>http://www.blogjava.net/xiaomage234/archive/2016/04/13/430074.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Wed, 13 Apr 2016 05:47:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2016/04/13/430074.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/430074.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2016/04/13/430074.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/430074.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/430074.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: from:http://blog.csdn.net/smartsmile2012/article/details/17316351版权声明：本文为博主原创文章，未经博主允许不得转载。[html]&nbsp;view plain&nbsp;copy&nbsp;print?&lt;!DOCTYPE&nbsp;html&nbsp;PUBLIC&nbsp;"-//W3C//DTD&nbsp;XHTML&n...&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaomage234/archive/2016/04/13/430074.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaomage234/aggbug/430074.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2016-04-13 13:47 <a href="http://www.blogjava.net/xiaomage234/archive/2016/04/13/430074.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>activemq 监控</title><link>http://www.blogjava.net/xiaomage234/archive/2015/12/24/428817.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 24 Dec 2015 11:18:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2015/12/24/428817.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/428817.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2015/12/24/428817.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/428817.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/428817.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">from:<span style="font-family: verdana, 'courier new'; font-size: 14px; line-height: 21px;">https://m.oschina.net/u/719192?ft=&amp;p=2</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">现在很多公司都遵循一个准则，没有监控的程序不能上线，可见监控的重要性。这里先介绍下ActiveMQ都需要监控的内容。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>监控硬件物理空间是否充足：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">ActiveMQ有3个重要的参数，存储空间百分比，内存空间百分比和临时空间百分比。这三个参数的意义很明显，如果值到了100，则表明硬件空间已满，Broker不能再接受任何的消息了，除非有消息消费并且删除，Broker才可以再接收消息。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">如果这些值长时间都比较高，接近阀值，则表示硬件的配置不能满足要求，建议更换硬件，或者给予ActiveMQ的环境配置比较小，建议给予更多的资源给ActiveMQ。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">如果平时保持在一个稳定值，有一段时间突然增高，则有两种可能。一种可能是用户量大增（当然大家都希望是这样），另一种可能是某个或者某几个消息消费者死机了。需要人工干预重启。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">还有一种可能是平时保持在一个稳定值，但是一段时间内突然降低了，则表示消息的生产者可能出现问题了。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>监控队列：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">如果ActiveMQ使用队列，需要监控队列的未消费消息数量，消费者数量，消息入队和出队的数量。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">未消费消息数量的含义和监控硬件的内存和硬盘空间差不多，过多的消息堆积可能是有消息消费者死机。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="font-size: 12.5px;">消费者数量应该是一个相对固定的值，这个值减少，就直接表示有的消费者已经死机。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">消息入队和出队数量如果增长缓慢或者不增长，则表示消息发送者已经死机。一般是通过增量监控。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong><span style="line-height: 22.5px;">监控主题：</span></strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">如果ActiveMQ使用主题，需要监控的内容和队列相似，但是没有未消费的消息数量。这里指的注意的是，ActiveMQ提供Advisory Message，用于帮助使用统计一些额外信息，详细情况在后面介绍。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong><span style="line-height: 22.5px;">监控订阅者：</span></strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">同样，如果ActiveMQ使用主题，订阅者的信息就十分重要。需要监控已经下线的订阅者。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">介绍完需要监控的内容，下面介绍一下ActiveMQ提供的几种监控方法。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;"><strong>Web Console监控：</strong><br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">之所以先介绍这个，是因为Web Console是最简单的，不需要任何配置就能使用的监控方式。同时也是最直观的监控方式。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">直接在浏览器访问http://activemq-host:8161/admin/。<span style="font-size: 12.5px;">把localhost换成你activemq启动机器的ip，端口号默认是8161，可以在${ACTIVEMQ_HOME}/conf/jetty.xml</span><span style="font-size: 12.5px;">中修改。默认的用户名和密码都是admin。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;"><span style="font-size: 12.5px;">进入页面首先看到</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;"><span style="font-size: 12.5px;"><img src="http://static.oschina.net/uploads/space/2014/0716/151228_iDGe_719192.png" style="max-width: 300px;" alt="" /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span>其中下面的红色框中标示出的就是硬件物理空间。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">然后点击上面红色框可以进入队列的监控页面。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><img src="http://static.oschina.net/uploads/space/2014/0716/151527_MDlN_719192.png" style="max-width: 300px;" alt="" /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">可以看到上面所提到的队列的一些重要数据。点击傍边的Topics可以进入主题监控页面，大致差不多，就不截图了。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">下面看一下订阅者监控界面。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><img src="http://static.oschina.net/uploads/space/2014/0716/152026_bbab_719192.png" style="max-width: 300px;" alt="" /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">需要重点关注的是中间红色框圈住的部分，是离线的订阅者。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">这样的页面一目了然，非常适合人类观看。但是缺点是，不适合程序直接抓数据，写监控脚本，自动报警等。这时你一定发现了这张图右边红色框部分。分别提供了队列，主题和订阅者的xml数据，下图是队列的xml数据。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><img src="http://static.oschina.net/uploads/space/2014/0716/152410_6s59_719192.png" style="max-width: 300px;" alt="" /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">这样就便于程序去访问这些数据。但是缺点是数据不够全，且xml也不如json容易解析，用shell脚本解析的话比较麻烦。shell解析的话，命令行的方式才是最舒服的。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>命令行监控：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">ActiveMQ当然也提供了命令行监控的方式。执行${ACTIVEMQ_HOME}/bin/activemq，会列出命令行的使用帮助。请注意虽然Windows平台也可以使用这个命令行，但是仅仅限于启动ActiveMQ实例，其他命令都不能很好的支持，所以这里所说的命令行方式，都是在Linux平台上的。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><img src="http://static.oschina.net/uploads/space/2014/0716/153014_Tx6n_719192.png" style="max-width: 300px;" alt="" /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">限于篇幅，这里只是截取了重要的部分。可以看到命令行提供了16个命令，包括start，stop，restart，console等启动停止实例相关的命令。还有一些控制ActiveMQ Broker的命令，如create，purge等。这里主要介绍几个监控可能用得到的命令</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">activemq status，显示当前的ActiveMQ是否运行正常，并且能显示pid。<br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><img src="http://static.oschina.net/uploads/space/2014/0716/153443_A9jx_719192.png" style="max-width: 300px;" alt="" /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">activemq list，列出当前Broker名字。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">activemq bstat，显示当前Broker的统计信息。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">activemq query，根据筛选条件显示Broker的统计信息。如：activemq query -QQueue=string_queue，是只显示string_queue这个队列的统计信息。更多使用方法可以使用activemq query --help显示帮助。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">activemq browse，可以查询当前Broker为被消费的消息，会显示消息的详细信息，如消息头，消息内容，优先级等。类似于数据库的查询功能。有自己的一套查询语法但是不是很复杂，同样可以使用activemq browse --help显示帮助。需要注意的是，只有Queue才可以查询，Topic是不可以的，所以这个功能虽然强大，但是有点鸡肋。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">activemq dstat，比较有用的一个功能，可以用来查询队列的关键数值，如队列大小，生产者消费者数量，消息出队入队统计等。还可以支持通过类别查询，如只查询队列或者只查询主题。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><img src="http://static.oschina.net/uploads/space/2014/0716/154556_kNSR_719192.png" style="max-width: 300px;" alt="" /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">个人认为，activemq status和activemq dstat是比较常用的两个监控命令，可以使用shell，然后grep/awk解析。命令行虽然方便，但是明显缺失必要的信息，如硬件使用百分比，订阅者下线信息等。至少目前不能完成监控的全部工作，希望以后可以持续完善功能。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>JMX监控：</strong><br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">由Java开发的程序，一般都是支持JMX监控的，ActiveMQ也不例外。JMX监控是最全的，任何细节都可以通过JMX获取。如果远程连接JMX监控需要一些额外的配置。本机直接连接不需要，但是由于ActiveMQ是部署在linux上，所以应该很少有人会直接连接本地的JMX，除非是本地开发调试阶段。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">1. 修改/etc/hosts 检查hosts文件设置，不用127.0.0.1，用实际IP地址。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">2. 修改${ACTIVEMQ_HOME}/bin/active文件。找到下面几行，是连续的。应该都是注释掉的，解除注释，开启远程连接JMX，端口号默认是11099。</span></p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">ACTIVEMQ_SUNJMX_START="-Dcom.sun.management.jmxremote.port=11099&nbsp;" ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START&nbsp;-Dcom.sun.management.jmxremote.password.file=${ACTIVEMQ_CONF}/jmx.password" ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START&nbsp;-Dcom.sun.management.jmxremote.access.file=${ACTIVEMQ_CONF}/jmx.access" ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START&nbsp;-Dcom.sun.management.jmxremote.ssl=false" ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START&nbsp;-Dcom.sun.management.jmxremote"</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="font-size: 12.5px;">3. 修改JMX用户和密码文件，必须是当前用户只读，别的用户无权限。否则启动时会报异常。</span><br /></p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">chmod&nbsp;400&nbsp;${ACTIVEMQ_HOME}/conf/jmx.*</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="font-size: 12.5px;"></span>其中jmx.access是用户权限配置文件，jmx.password是用户密码配置文件。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">配置到此，就可以使用jconsole等客户端连接了。启动jconsle，选择远程进程，填写remotehost:11099。其中remotehost是ActiveMQ所在机器的ip地址，11099是配置文件中开启的监听端口号。默认用户名是admin,密码是activemq。默认用户名和密码可以在<span style="line-height: 22.5px;">jmx.access和jmx.password修改。连接之后如下图所示：</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><img src="http://static.oschina.net/uploads/space/2014/0716/162519_SaCQ_719192.png" style="max-width: 300px;" alt="" /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">可以看到，从左侧树形菜单可以找到ActiveMQ的mbean，然后可以查看任何公开的JMX属性。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">如果你配置完了前3步，仍然不能远程连接JMX，请继续下面的配置。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">4. 查看${ACTIVEMQ_HOME}/conf/activemq.xml中的broker节点中useJmx="true"属性。这个属性可以没有或者为true，但是不可以是false。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">5. 修改${ACTIVEMQ_HOME}/conf/activemq.xml中的broker节点中找到managementContext节点，修改如下：</span></p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">&lt;managementContext&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;managementContext&nbsp;createConnector="true"&nbsp;connectorPort="11099"&nbsp;/&gt; &lt;/managementContext&gt;</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">其中connectorPort是你想发布的JMX端口号。注意端口号必须和之前${ACTIVEMQ_HOME}/bin/activemq里发布的端口号保持一致。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">JMX可以使用java开发程序，进行监测。但是对其他语言的支持有限。读到这里，你是不是觉得，每种监控方式各有优缺点，但是很难找出一个都很完美的方式，既可以看到全部的信息，又可以轻松的用程序实现监控。如果你有这方面的需求，请你继续看下一个监控方式。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>JMX REST API：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">可能你还记得，之前提到的Web Console也有xml的数据展现形式，但是解析困难且数据不全。而命令行模式数据更加不全。所以，</span>ActiveMQ提供把JMX导出为REST API。这样就最大限度的满足了各种需求，既有完整的数据，又可以方便编写程序监控。当然如果以后命令行的方式能提供更多的信息，那么这个JMX REST API就可以被替代了。但是至少现在来说，他是不可替代的。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">ActiveMQ使用一个开源的组件Jolokia来将JMX自动发布成为REST API。如果使用这个方式，你不需要配置那些上一节提到的繁琐远程JMX配置。他的原理是使用本地的JMX，然后通过HTTP发布出来，并不是远程访问JMX。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">在浏览器访问http://activemq-host:8161/api/jolokia/。默认的用户名和密码同样都是admin。可以看到浏览器会返回json信息来描述当前系统。</p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">{"request":{"type":"version"},"value":{"agent":"1.2.1","protocol":"7.1","config":{"discoveryEnabled":"false","agentId":"xxx.xxx.xxx.xxx-29009-71a9b4c7-servlet","agentType":"servlet","agentDescription":"Apache&nbsp;ActiveMQ"},"info":{"product":"activemq","vendor":"Apache","version":"5.10.0"}},"timestamp":1405499528,"status":200}</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">通过Jolokia API可以访问JMX发布的任何mbean。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">http://activemq-host:8161/api/jolokia/list&nbsp; 显示当前所有的mbean。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">http://activemq-host:8161/api/jolokia/read/&lt;mbean&nbsp;name&nbsp;&gt;/&lt;attribute name&gt; 显示某个mbean的某个属性</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">还有很多其他的操作，如http://activemq-host:8161/api/jolokia/write/&lt;mbean&nbsp;name&nbsp;&gt;/&lt;attribute name&gt;可以动态执行方法。由于本篇文章只涉及监控，所以其他的操作先不深入。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">我们重点关注http://activemq-host:8161/api/jolokia/read/。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">先说一下Mbean名字的规则。一般的MBean名字类似于：<span style="line-height: 22.5px;">org.apache.activemq:type=Broker,brokerName=DemoBroker</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">org.apache.activemq:是ActiveMQ在这个Mbean的Domain名，可以修改managementContext的jmxDomainName中配置名称。</span></p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">&lt;managementContext&gt; &nbsp;&nbsp;&nbsp;&nbsp;&lt;managementContext&nbsp;createConnector="true"&nbsp;connectorPort="11099"&nbsp;jmxDomainName="MyBroker"&nbsp;/&gt; &lt;/managementContext&gt;</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">type=Broker是固定的。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">brokerName=DemoBroker，其中DemoBroker是在配置文件中Broker所配置的名字。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">后面会有一些自定义属性。如：destinationType=Queue,destinationName=pojo_queue。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">看到这里你可能会比较迷惑，</span><span style="font-size: 12.5px;">下面给出例子，请慢慢体会。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">http://10.2activemq-host:8161/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=DemoBroker/TotalEnqueueCount</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">获取入队的消息总数，返回结果如下：</p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">{"request":{"mbean":"org.apache.activemq:brokerName=DemoBroker,type=Broker","attribute":"TotalEnqueueCount","type":"read"},"value":5672,"timestamp":1405501289,"status":200}</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">关键的数据是value的值5672，表示有5672个消息入队。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">如果使用shell编写监控脚本，可以使用命令：</p><pre true;="" auto-links:=""  false;"="" style="color: #333333; line-height: normal; background-color: #f9f9f9;">wget&nbsp;--user&nbsp;admin&nbsp;--password&nbsp;admin&nbsp;--auth-no-challenge&nbsp;http://activemq-host:8161/api/jolokia/read/org.apache.activemq:type=Broker,brokerName=localhost/TotalEnqueueCount</pre><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">下面列出几个关键的监控属性。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,service=Health/CurrentStatus</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">获取当前系统状态</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=<span style="line-height: 22.5px;">localhost</span>/MemoryPercentUsage</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">获取内存使用量</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost/StorePercentUsage</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">获取硬盘空间使用量</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">&lt;base_url&gt;/</span><span style="line-height: 22.5px;">read/org.apache.activemq:type=Broker,brokerName=localhost/TempPercentUsage</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">获取临时文件硬盘空间使用量</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=pojo_queue/QueueSize</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">获取队列pojo_queue的未消费消息数量</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=pojo_queue/ProducerCount</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">获取队列pojo_queue的生产者数量</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=pojo_queue/ConsumerCount</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">获取队列pojo_queue的消费者数量</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><br /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=pojo_queue/EnqueueCount</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">获取队列pojo_queue的已消费消息数量</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;"><br /></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;"></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Queue,destinationName=pojo_queue/DequeueCount</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;">获取队列pojo_queue的已接收消息数量</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: 22.5px; background-color: #f9f9f9;"><br />&lt;base_url&gt;/read/org.apache.activemq:type=Broker,brokerName=localhost,destinationType=Topic,destinationName=pojo_topic,endpoint=Consumer,clientId=pojo_client_1,consumerId=Durable(pojo_client_1_pojo_client_1)/Active</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;">获取主题pojo_topic的client id为pojo_client_1的订阅者是否已经下线</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>Advisory Message监控：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">ActiveMQ提供了一些额外的信息帮助用户获取系统状态，这些额外信息都存在主题中，以<strong>ActiveMQ.Advisory.</strong>开头。这些信息可以通过前面说的任何一种方式查询。这些消息包括Queue/Topic创建销毁的次数，消费比较慢的消费者统计等等。可以参考<a href="http://activemq.apache.org/advisory-message.html" target="_self" rel="nofollow" style="color: #2489ce; font-weight: bold;">官方文档</a>查询每个Advisory Message的意义。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>插件监控：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">ActiveMQ还提供了一些额外的插件来监控系统，主要有可视化插件监控和统计插件监控，需要在activemq.xml中进行配置，最主要的有&lt;connectionDotFilePlugin/&gt;，&lt;destinationDotFilePlugin/&gt;和&lt;statisticsBrokerPlugin/&gt;。对于一些生成图标的监控系统比较有用。下面是<span style="line-height: 22.5px;">connectionDotFilePlugin的使用截图。</span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><span style="line-height: 22.5px;"><img src="http://static.oschina.net/uploads/space/2014/0716/175422_LH45_719192.png" style="max-width: 300px;" alt="" /></span></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;"><strong>第三方监控：</strong></p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">最后一种监控方式就是第三方提供的监控，这种监控主要包括ActiveMQ Monitor，Apache ActiveMQBrowser ，HermesJMS等。由于是第三方提供的监控平台，所以一旦activemq升级，监控平台不升级，可能会带来兼容问题，所以请谨慎使用。</p><p style="color: #333333; font-family: Helvetica, Arial, sans-serif; font-size: medium; line-height: normal; background-color: #f9f9f9;">另外不得不提的是hawtio，也是一个第三方提供的监控平台，提供了HTML5的绚丽界面。已经在ActiveMQ 5.9的版本中内嵌入发布包。但是由于Apache内部的意见分歧，在ActiveMQ 5.9.1的版本中又将其删除。如果想用，只能自己下载<span style="line-height: 22.5px;">hawtio部署到ActiveMQ的环境中。</span></p><div><span style="line-height: 22.5px;"><br /></span></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/428817.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2015-12-24 19:18 <a href="http://www.blogjava.net/xiaomage234/archive/2015/12/24/428817.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>服务监控微信通知</title><link>http://www.blogjava.net/xiaomage234/archive/2015/04/03/424090.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 03 Apr 2015 02:50:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2015/04/03/424090.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/424090.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2015/04/03/424090.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/424090.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/424090.html</trackback:ping><description><![CDATA[from :<br /><div>http://git.oschina.net/yeetrack/weixin-alert<br /><br /><p style="box-sizing: inherit; margin: 0px 0px 15px; line-height: 1.33; color: rgba(0, 0, 0, 0.8); font-family: Lato, 'Helvetica Neue', 'Microsoft YaHei', Arial, Helvetica, sans-serif; font-size: 15px; background-color: #fafafa;">很简单的步骤：</p><ol style="box-sizing: inherit; margin: 0px 0px 15px; padding-left: 30px; color: rgba(0, 0, 0, 0.8); font-family: Lato, 'Helvetica Neue', 'Microsoft YaHei', Arial, Helvetica, sans-serif; font-size: 15px; line-height: 24px; background-color: #fafafa;"><li style="box-sizing: inherit; list-style: decimal; margin: 0px;">登录web微信，打开开发者工具，切到http请求tab</li><li style="box-sizing: inherit; list-style: decimal; margin: 0px;">给要报警的人、或者群组发送一条微信</li><li style="box-sizing: inherit; list-style: decimal; margin: 0px;">在开发者工具中，copy出两条curl请求，一个是发送心跳的，一个是发送消息内容的。</li><li style="box-sizing: inherit; list-style: decimal; margin: 0px;">编译jar包，<code style="box-sizing: inherit; font-family: Menlo, 'Liberation Mono', Consolas, 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace; padding: 0px 5px; color: #dd1144; border: 1px solid #dddddd; white-space: nowrap; margin: 0px 2px; border-radius: 3px; background-color: #f8f8f8;">mvn clean pakcage</code></li><li style="box-sizing: inherit; list-style: decimal; margin: 0px;">将心跳curl保存成**weixin-heart.sh**,将发送curl保存成**weixin-send.sh**。</li><li style="box-sizing: inherit; list-style: decimal; margin: 0px;">将jar包和两个shell文件放在统一路径中，执行<code style="box-sizing: inherit; font-family: Menlo, 'Liberation Mono', Consolas, 'DejaVu Sans Mono', 'Ubuntu Mono', 'Courier New', 'andale mono', 'lucida console', monospace; padding: 0px 5px; color: #dd1144; border: 1px solid #dddddd; white-space: nowrap; margin: 0px 2px; border-radius: 3px; background-color: #f8f8f8;">java -jar weixinalert-1.0-SNAPSHOT-jar-with-dependencies.jar "Hello world!"</code>即可。</li></ol><p style="box-sizing: inherit; margin-top: 0px; margin-right: 0px; margin-left: 0px; line-height: 1.33; color: rgba(0, 0, 0, 0.8); font-family: Lato, 'Helvetica Neue', 'Microsoft YaHei', Arial, Helvetica, sans-serif; font-size: 15px; margin-bottom: 0px !important; background-color: #fafafa;">ps：心跳的那个请求，最好有个定时任务，crontab之类，一分钟一次，防止服务器踢掉该会话。缺点：不能退出手机上的微信（断网可以，只要不手动退出），不能再使用该微信号登录其他客户端的微信，如windows，mac，网页微信等，也就是说一个手机上的微信账号，最多额外产生一个sid，多了会踢掉之前的sid。</p></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/424090.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2015-04-03 10:50 <a href="http://www.blogjava.net/xiaomage234/archive/2015/04/03/424090.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j实现日志集中存储</title><link>http://www.blogjava.net/xiaomage234/archive/2014/07/09/415624.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Wed, 09 Jul 2014 07:31:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2014/07/09/415624.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/415624.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2014/07/09/415624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/415624.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/415624.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">先描述一下问题，多个服务器实现的负载均衡，每个服务器存储在自己的硬盘里。但是现在需要对日志做统一的分析，在多个服务器上统计就麻烦了。思路是把日志统一到一台日志服务器上，再统一做统计分析。怎么统一到一台服务器上，说实话没有特别好的思路，最后尝试了log4j的SocketAppender。查了不少网络资源，都说的有些不明了，还是得亲自尝试之后才见分晓。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;"><strong>1、客户端的配置</strong>：</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">客户端的配置比较简单，只需要告诉log4j需要监听哪个远程服务器的哪个端口即可。直接在log4j.properties里直接配置就好。</span></p><p align="left" style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><div bg_html"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[html]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 674px; top: 591px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;"><span style="color: #993300; font-weight: bold;">&lt;</span><span style="color: #993300; font-weight: bold;">span</span>&nbsp;<span style="color: red;">style</span>=<span style="color: blue;">"font-size:12px;"</span><span style="color: #993300; font-weight: bold;">&gt;</span><span style="color: red;">log4j.appender.logs</span>=<span style="color: blue;">org</span>.apache.log4j.DailyRollingFileAppender&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.logs.File</span>&nbsp;=&nbsp;/data/logs/request/logs.log&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.logs.layout</span>&nbsp;=&nbsp;<span style="color: blue;">org</span>.apache.log4j.PatternLayout&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.logs.layout.ConversionPattern</span>=%d&nbsp;[%t]&nbsp;-&nbsp;%m%n&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.logs.DatePattern</span>='.'<span style="color: blue;">yyyy</span>-MM-dd'.log'&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.socket</span>=<span style="color: blue;">org</span>.apache.log4j.net.SocketAppender&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.socket.RemoteHost</span>=<span style="color: blue;">172</span>.16.2.152&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.socket.Port</span>=<span style="color: blue;">4560</span>&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.socket.LocationInfo</span>=<span style="color: blue;">true</span>&nbsp;&nbsp;</li><li style="line-height: 18px;">#下面这两句感觉没用&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.socket.layout</span>=<span style="color: blue;">org</span>.apache.log4j.PatternLayout&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.socket.layout.ConversionPattern</span>=[%-5p]&nbsp;%d{yyyy-MM-dd&nbsp;HH:mm:ss,SSS}&nbsp;method:%l%n%t%m%n&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">#将日志写入本地和远程日志服务器&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.logger.com.test.core.filter</span>&nbsp;=<span style="color: blue;">DEBUG</span>,socket,logs<span style="color: #993300; font-weight: bold;">&lt;/</span><span style="color: #993300; font-weight: bold;">span</span><span style="color: #993300; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li></ol></div><span style="color: #333333; font-family: Arial; line-height: 26px; font-size: 12px; background-color: #ffffff;">&nbsp;<br /></span><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;"><strong>2、日志服务器的配置</strong>：</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">日志服务器需要单独启动一个java进程，接收客户端给自己发送的socket请求。Log4j提供了org.apache.log4j.net.SocketServer类，直接运行其main函数就行了（当然也可以自己写啦）。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">java -cp /log4jsocket/serverConfig/log4j-1.2.16.jarorg.apache.log4j.net.SocketServer 4560 /log4jsocket/log4jserver.properties /log4jsocket/clientConfig</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">/log4jsocket/serverConfig/log4j-1.2.16.jar是log4j jar包存放的位置，org.apache.log4j.net.SocketServer需要三个参数：</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">1）4560&nbsp;</span><span style="font-size: 12px;">是监听的端口号</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">2）/log4jsocket/log4jserver.properties&nbsp;</span><span style="font-size: 12px;">是记录日志服务器的日志的配置文件</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">3）/log4jsocket/clientConfig&nbsp;</span><span style="font-size: 12px;">是客户端配置文件所在的目录（注意是目录）。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">着重说一下</span><span style="font-size: 12px;">org.apache.log4j.net.SocketServer的第三个参数，这个文件夹下配置的是各个客户端的日志的配置。配置文件以.lcf结尾，文件名可以用客户端的IP命名，log4j会自己找发送请求的客户端IP对应的那个配置文件，如172.16.2.46服务器发送的socket请求会寻找172.16.2.46.lcf配置文件，并根据配置将日志写入对应的文件。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><div bg_html"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[html]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 674px; top: 1434px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;"><span style="color: #993300; font-weight: bold;">&lt;</span><span style="color: #993300; font-weight: bold;">span</span>&nbsp;<span style="color: red;">style</span>=<span style="color: blue;">"font-size:12px;"</span><span style="color: #993300; font-weight: bold;">&gt;</span>#注意logger后面的值要与client的值相同&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.logger.com.test.core.filter</span>=<span style="color: blue;">DEBUG</span>,localLogs&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.localLogs</span>=<span style="color: blue;">org</span>.apache.log4j.DailyRollingFileAppender&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.localLogs.File</span>=/data/logs/request/172.16.2.46/logs.log&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.localLogs.layout</span>=<span style="color: blue;">org</span>.apache.log4j.PatternLayout&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.localLogs.layout.ConversionPattern</span>=%d&nbsp;[%t]&nbsp;-&nbsp;%m%n&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: red;">log4j.appender.localLogs.DatePattern</span>='.'<span style="color: blue;">yyyy</span>-MM-dd'.log'&nbsp;&nbsp;</li><li style="line-height: 18px;"><span style="color: #993300; font-weight: bold;">&lt;/</span><span style="color: #993300; font-weight: bold;">span</span><span style="color: #993300; font-weight: bold;">&gt;</span>&nbsp;&nbsp;</li></ol></div><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;"><br /></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">这样做的好处是可以根据不同客户端，将日志写入不同的文件夹下的。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">其实，配置过程就这么简单，但是当你这么做之后，你会发现运行org.apache.log4j.net.SocketServer后，客户端向日志服务器发送请求时，会报找不到.lcf文件的错误，得不到想要的结果。原因出在org.apache.log4j.net.SocketServer代码中的一个小bug。&nbsp;</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><div bg_java"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 674px; top: 1797px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;">&lt;span&nbsp;style="font-size:12px;"&gt;LoggerRepository&nbsp;configureHierarchy(InetAddress&nbsp;inetAddress)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;cat.info("Locating&nbsp;configuration&nbsp;file&nbsp;for&nbsp;"&nbsp;+&nbsp;inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;inetAddress.toString();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;i&nbsp;=&nbsp;s.indexOf("/");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;==&nbsp;-<span style="color: #c00000;">1</span>)&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cat.warn("Could&nbsp;not&nbsp;parse&nbsp;the&nbsp;inetAddress&nbsp;["&nbsp;+&nbsp;inetAddress&nbsp;+&nbsp;"].&nbsp;Using&nbsp;default&nbsp;hierarchy.");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;genericHierarchy();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;key&nbsp;=&nbsp;s.substring(<span style="color: #c00000;">0</span>,i);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;File&nbsp;configFile&nbsp;=&nbsp;new&nbsp;File(this.dir,&nbsp;key&nbsp;+&nbsp;CONFIG_FILE_EXT);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(configFile.exists())&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hierarchy&nbsp;h&nbsp;=&nbsp;new&nbsp;Hierarchy(new&nbsp;RootLogger(Level.DEBUG));&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.hierarchyMap.put(inetAddress,&nbsp;h);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;PropertyConfigurator().doConfigure(configFile.getAbsolutePath(),&nbsp;h);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;h;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;cat.warn("Could&nbsp;not&nbsp;find&nbsp;config&nbsp;file&nbsp;["&nbsp;+&nbsp;configFile&nbsp;+&nbsp;"].");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;genericHierarchy();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;}&lt;/span&gt;&nbsp;&nbsp;</li></ol></div><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">String key = s.substring(0, i);换成String key = s.substring(i+1);就好了。这段代码是解析IP地址，然后寻找对应IP命名的.lcf配置文件；如果找不到，则解析默认的generic.lcf。由于截取的错误，导致找不到172.16.2.46.lcf，文件夹下又没有generic.lcf，所以会抛异常。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">org.apache.log4j.net.SocketServer代码中的另外一个bug是，只能接收来自一台客户端的日志请求，一旦客户端停止运行，SocketServer也将关闭。查看代码：</span></p><div bg_java"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 674px; top: 2469px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;">public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;argv)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(argv.length&nbsp;==&nbsp;<span style="color: #c00000;">3</span>)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;init(argv[<span style="color: #c00000;">0</span>],&nbsp;argv[<span style="color: #c00000;">1</span>],&nbsp;argv[<span style="color: #c00000;">2</span>]);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usage("Wrong&nbsp;number&nbsp;of&nbsp;arguments.");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cat.info("Listening&nbsp;on&nbsp;port&nbsp;"&nbsp;+&nbsp;port);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerSocket&nbsp;serverSocket&nbsp;=&nbsp;new&nbsp;ServerSocket(port);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cat.info("Waiting&nbsp;to&nbsp;accept&nbsp;a&nbsp;new&nbsp;client.");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;Socket&nbsp;socket&nbsp;=&nbsp;serverSocket.accept();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;InetAddress&nbsp;inetAddress&nbsp;=&nbsp;socket.getInetAddress();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;cat.info("Connected&nbsp;to&nbsp;client&nbsp;at&nbsp;"&nbsp;+&nbsp;inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;LoggerRepository&nbsp;h&nbsp;=&nbsp;(LoggerRepository)server.hierarchyMap.get(inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(h&nbsp;==&nbsp;null)&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h&nbsp;=&nbsp;server.configureHierarchy(inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;cat.info("Starting&nbsp;new&nbsp;socket&nbsp;node.");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;Thread(new&nbsp;SocketNode(socket,&nbsp;h)).start();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;}&nbsp;&nbsp;</li></ol></div><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">问题出在只建立了一个socket连接就不在accept了，加上while循环问题就解决了。</p><div bg_java"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[java]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 674px; top: 3068px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;">ServerSocket&nbsp;serverSocket&nbsp;=&nbsp;new&nbsp;ServerSocket(port);&nbsp;&nbsp;</li><li style="line-height: 18px;">while(true){&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;cat.info("Waiting&nbsp;to&nbsp;accept&nbsp;a&nbsp;new&nbsp;client.");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;Socket&nbsp;socket&nbsp;=&nbsp;serverSocket.accept();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;InetAddress&nbsp;inetAddress&nbsp;=&nbsp;socket.getInetAddress();&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;cat.info("Connected&nbsp;to&nbsp;client&nbsp;at&nbsp;"&nbsp;+&nbsp;inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;LoggerRepository&nbsp;h&nbsp;=&nbsp;(LoggerRepository)server.hierarchyMap.get(inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;if&nbsp;(h&nbsp;==&nbsp;null)&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;h&nbsp;=&nbsp;server.configureHierarchy(inetAddress);&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;cat.info("Starting&nbsp;new&nbsp;socket&nbsp;node.");&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;new&nbsp;Thread(new&nbsp;SocketNode(socket,&nbsp;h)).start();&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li></ol></div><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br /><br />&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">好了。Log4j的配置到此结束。</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">最后一个问题，日志服务器是linux，需要有一个统一的start、shutdown命令来启动和关闭org.apache.log4j.net.SocketServer。那就需要些shell命令了，下面这段代码参考了<a href="http://www.cnblogs.com/baibaluo/archive/2011/08/31/2160934.html" style="color: #336699; text-decoration: none;">http://www.cnblogs.com/baibaluo/archive/2011/08/31/2160934.html</a></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="font-size: 12px;">catalina.sh</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><div bg_plain"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[plain]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 677px; top: 3671px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;">&lt;span&nbsp;style="font-size:12px;"&gt;#!/bin/bash&nbsp;&nbsp;</li><li style="line-height: 18px;">#端口&nbsp;&nbsp;</li><li style="line-height: 18px;">LISTEN_PORT=4560&nbsp;&nbsp;</li><li style="line-height: 18px;">#服务端log4j配置文件&nbsp;&nbsp;</li><li style="line-height: 18px;">SERVER_CONFIG=/log4jsocket/server.properties&nbsp;&nbsp;</li><li style="line-height: 18px;">#客户端的配置&nbsp;&nbsp;</li><li style="line-height: 18px;">CLIENT_CONFIG_DIR=/log4jsocket/clientConfig&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">#Java程序所在的目录（classes的上一级目录）&nbsp;&nbsp;</li><li style="line-height: 18px;">APP_HOME=/opt/log4jsocket/serverConfig&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">#需要启动的Java主程序（main方法类）&nbsp;&nbsp;</li><li style="line-height: 18px;">APP_MAINCLASS=org.apache.log4j.net.SocketServer&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">#拼凑完整的classpath参数，包括指定lib目录下所有的jar&nbsp;&nbsp;</li><li style="line-height: 18px;">CLASSPATH=$APP_HOME&nbsp;&nbsp;</li><li style="line-height: 18px;">for&nbsp;i&nbsp;in&nbsp;"$APP_HOME"/*.jar;&nbsp;do&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;CLASSPATH="$CLASSPATH":"$i"&nbsp;&nbsp;</li><li style="line-height: 18px;">done&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">#JDK所在路径&nbsp;&nbsp;</li><li style="line-height: 18px;">JAVA_HOME="/opt/jdk1.6.0_30"&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">#执行程序启动所使用的系统用户，考虑到安全，推荐不使用root帐号&nbsp;&nbsp;</li><li style="line-height: 18px;">RUNNING_USER=root&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">#java虚拟机启动参数&nbsp;&nbsp;</li><li style="line-height: 18px;">JAVA_OPTS="-ms512m&nbsp;-mx512m&nbsp;-Xmn256m&nbsp;-Djava.awt.headless=true&nbsp;-XX:MaxPermSize=128m"&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">#初始化psid变量（全局）&nbsp;&nbsp;</li><li style="line-height: 18px;">psid=0&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">checkpid()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;javaps=`$JAVA_HOME/bin/jps&nbsp;-l&nbsp;|&nbsp;grep&nbsp;$APP_MAINCLASS`&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;-n&nbsp;"$javaps"&nbsp;];&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;psid=`echo&nbsp;$javaps&nbsp;|&nbsp;awk&nbsp;'{print&nbsp;$1}'`&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;psid=0&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">start()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;checkpid&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$psid&nbsp;-ne&nbsp;0&nbsp;];&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"================================"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"warn:&nbsp;$APP_MAINCLASS&nbsp;already&nbsp;started!&nbsp;(pid=$psid)"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"================================"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;-n&nbsp;"Starting&nbsp;$APP_MAINCLASS&nbsp;..."&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JAVA_CMD="nohup&nbsp;$JAVA_HOME/bin/java&nbsp;-classpath&nbsp;$CLASSPATH&nbsp;$APP_MAINCLASS&nbsp;$LISTEN_PORT&nbsp;$SERVER_CONFIG&nbsp;$CLIENT_CONFIG_DIR&nbsp;&gt;/dev/null&nbsp;2&gt;&amp;1&nbsp;&amp;"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su&nbsp;-&nbsp;$RUNNING_USER&nbsp;-c&nbsp;"$JAVA_CMD"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkpid&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$psid&nbsp;-ne&nbsp;0&nbsp;];&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"(pid=$psid)&nbsp;[OK]"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"[Failed]"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">stop()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;checkpid&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$psid&nbsp;-ne&nbsp;0&nbsp;];&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;-n&nbsp;"Stopping&nbsp;$APP_MAINCLASS&nbsp;...(pid=$psid)&nbsp;"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;su&nbsp;-&nbsp;$RUNNING_USER&nbsp;-c&nbsp;"kill&nbsp;-9&nbsp;$psid"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$?&nbsp;-eq&nbsp;0&nbsp;];&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"[OK]"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"[Failed]"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;checkpid&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$psid&nbsp;-ne&nbsp;0&nbsp;];&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stop&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"================================"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"warn:&nbsp;$APP_MAINCLASS&nbsp;is&nbsp;not&nbsp;running"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"================================"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">status()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;checkpid&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;$psid&nbsp;-ne&nbsp;0&nbsp;];&nbsp;&nbsp;then&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"$APP_MAINCLASS&nbsp;is&nbsp;running!&nbsp;(pid=$psid)"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"$APP_MAINCLASS&nbsp;is&nbsp;not&nbsp;running"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;fi&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li><li style="line-height: 18px;">info()&nbsp;{&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;"System&nbsp;Information:"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;"****************************"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;`head&nbsp;-n&nbsp;1&nbsp;/etc/issue`&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;`uname&nbsp;-a`&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;"JAVA_HOME=$JAVA_HOME"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;`$JAVA_HOME/bin/java&nbsp;-version`&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;"APP_HOME=$APP_HOME"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;"APP_MAINCLASS=$APP_MAINCLASS"&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;echo&nbsp;"****************************"&nbsp;&nbsp;</li><li style="line-height: 18px;">}&nbsp;&nbsp;</li><li style="line-height: 18px;">case&nbsp;"$1"&nbsp;in&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;'start')&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;'stop')&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stop&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;'restart')&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stop&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;'status')&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;'info')&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;*)&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;"Usage:&nbsp;$0&nbsp;{start|stop|restart|status|info}"&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit&nbsp;0&nbsp;&nbsp;&nbsp;</li><li style="line-height: 18px;">esac&nbsp;&nbsp;</li><li style="line-height: 18px;">&lt;/span&gt;&nbsp;&nbsp;</li></ol></div><span style="color: #333333; font-family: Arial; line-height: 26px; font-size: 12px; background-color: #ffffff;">startup.sh</span><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><div bg_plain"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[plain]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 677px; top: 6105px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;">&lt;span&nbsp;style="font-size:12px;"&gt;#!/bin/sh&nbsp;&nbsp;</li><li style="line-height: 18px;">EXECUTABLE=/log4jsocket/catalina.sh&nbsp;&nbsp;</li><li style="line-height: 18px;">exec&nbsp;"$EXECUTABLE"&nbsp;start&nbsp;"$@"&lt;/span&gt;&nbsp;&nbsp;</li></ol></div><span style="color: #333333; font-family: Arial; line-height: 26px; font-size: 12px; background-color: #ffffff;">shutdown.sh</span><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><div bg_plain"="" style="width: 700.90625px; color: #333333; line-height: 26px;"><div><div><strong>[plain]</strong>&nbsp;<a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="view plain" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_plain.gif); background-position: 0% 0%; background-repeat: no-repeat;">view plain</a><a href="http://blog.csdn.net/kdmhh/article/details/8208522#" title="copy" style="padding: 1px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px; background-image: url(http://static.blog.csdn.net/scripts/SyntaxHighlighter/styles/images/default/ico_copy.gif); background-position: 0% 0%; background-repeat: no-repeat;">copy</a><div style="position: absolute; left: 677px; top: 6254px; width: 18px; height: 18px; z-index: 99;"></div></div></div><ol start="1"><li style="line-height: 18px;">&lt;span&nbsp;style="font-size:12px;"&gt;EXECUTABLE=/log4jsocket/catalina.sh&nbsp;&nbsp;</li><li style="line-height: 18px;">exec&nbsp;"$EXECUTABLE"&nbsp;stop&nbsp;"$@"&lt;/span&gt; &nbsp;</li></ol></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/415624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2014-07-09 15:31 <a href="http://www.blogjava.net/xiaomage234/archive/2014/07/09/415624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GYP 简介</title><link>http://www.blogjava.net/xiaomage234/archive/2014/03/18/411169.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Tue, 18 Mar 2014 06:36:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2014/03/18/411169.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/411169.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2014/03/18/411169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/411169.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/411169.html</trackback:ping><description><![CDATA[<p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">说起项目构建工具，Linux 用户最熟悉的恐怕就是&nbsp;<a href="http://en.wikipedia.org/wiki/GNU_build_system" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">Autotools</a>，它将编译安装这个步骤大大简化。但对于项目作者来说，想要使用 Autotools 生成有效的配置文件着实需要下一番功夫，用现在流行的话来说就是用户体验不够友好。对 Unix shell 的依赖，也使得 Autotools 天生对于跨平台支持不佳。</p><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">后来我从<a href="https://twitter.com/zhzhxtrrk" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">大猫</a>同学那里听说了&nbsp;<a href="http://www.cmake.org/" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">CMake</a>，CMake 使用 C++ 编写，原生支持跨平台，不需要像 Autotools 那样写一堆的配置文件，只需一个 CMakeLists.txt 文件即可。简洁的使用方式，强大的功能使得我立马对 CMake 情有独钟。在后来的使用过程中，虽然会遇到一些因为使用习惯带来的小困扰，但我对于 CMake 还是基本满意的。直到我发现了 GYP。</p><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;"><a href="http://code.google.com/p/gyp/" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">GYP</a>（Generate Your Projects）是由 Chromium 团队开发的跨平台自动化项目构建工具，Chromium 便是通过 GYP 进行项目构建管理。为什么我要选择 GYP，而放弃 CMake 呢？功能上 GYP 和 CMake 很是相似，在我看来，它们的最大区别在于配置文件的编写方式和其中蕴含的思想。</p><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">编写 CMake 配置文件相比 Autotools 来说已经简化很多，一个最简单的配置文件只需要写上源文件及生成类型（可执行文件、静态库、动态库等）即可。对分支语句和循环语句的支持也使得 CMake 更加灵活。但是，CMake 最大的问题也是在这个配置文件，请看下面这个示例文件：</p><figure style="margin: 10px 0px 0px; padding: 5px 15px; background-color: #dddddd; border: 1px solid #cccccc; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px;"><div style="margin: 0px; overflow-x: auto;"><table style="margin: 0px; padding: 0px; border: none; border-spacing: 0px;"><tbody style="margin: 0px; padding: 0px;"><tr style="margin: 0px; padding: 0px;"><td style="margin: 0px; padding: 0px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px 15px 0px 0px; background-image: none; border-right-width: 1px; border-style: none solid none none; border-right-color: #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; line-height: 1.5; overflow-x: auto; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;"><span style="margin: 0px; padding: 0px;">1</span> <span style="margin: 0px; padding: 0px;">2</span> <span style="margin: 0px; padding: 0px;">3</span> <span style="margin: 0px; padding: 0px;">4</span> <span style="margin: 0px; padding: 0px;">5</span> <span style="margin: 0px; padding: 0px;">6</span> <span style="margin: 0px; padding: 0px;">7</span> <span style="margin: 0px; padding: 0px;">8</span> <span style="margin: 0px; padding: 0px;">9</span> <span style="margin: 0px; padding: 0px;">10</span> <span style="margin: 0px; padding: 0px;">11</span> <span style="margin: 0px; padding: 0px;">12</span> <span style="margin: 0px; padding: 0px;">13</span> <span style="margin: 0px; padding: 0px;">14</span> <span style="margin: 0px; padding: 0px;">15</span> <span style="margin: 0px; padding: 0px;">16</span> <span style="margin: 0px; padding: 0px;">17</span> <span style="margin: 0px; padding: 0px;">18</span> <span style="margin: 0px; padding: 0px;">19</span> <span style="margin: 0px; padding: 0px;">20</span> <span style="margin: 0px; padding: 0px;">21</span> <span style="margin: 0px; padding: 0px;">22</span> <span style="margin: 0px; padding: 0px;">23</span> <span style="margin: 0px; padding: 0px;">24</span> <span style="margin: 0px; padding: 0px;">25</span> <span style="margin: 0px; padding: 0px;">26</span> <span style="margin: 0px; padding: 0px;">27</span> <span style="margin: 0px; padding: 0px;">28</span> <span style="margin: 0px; padding: 0px;">29</span> <span style="margin: 0px; padding: 0px;">30</span> <span style="margin: 0px; padding: 0px;">31</span> <span style="margin: 0px; padding: 0px;">32</span> <span style="margin: 0px; padding: 0px;">33</span> <span style="margin: 0px; padding: 0px;">34</span> <span style="margin: 0px; padding: 0px;">35</span> <span style="margin: 0px; padding: 0px;">36</span> <span style="margin: 0px; padding: 0px;">37</span> <span style="margin: 0px; padding: 0px;">38</span> <span style="margin: 0px; padding: 0px;">39</span> <span style="margin: 0px; padding: 0px;">40</span> <span style="margin: 0px; padding: 0px;">41</span> <span style="margin: 0px; padding: 0px;">42</span> </pre></td><td style="margin: 0px; padding: 0px 0px 0px 15px; width: 721px; overflow-x: auto;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; background-image: none; border: none; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; line-height: 1.5; overflow-x: auto; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;"><code style="margin: 0px; padding: 0px; background-image: none; border: none; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; background-position: initial initial; background-repeat: initial initial;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">cmake_minimum_required</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">VERSION</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">2.8</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">project</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">VP8</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CXX</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">add_definitions</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">-Wall</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">cmake_policy</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">SET</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMP0015</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">NEW</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">include_directories</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"include"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">link_directories</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"lib"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_ARCHIVE_OUTPUT_DIRECTORY</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"../lib"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">VP8SRC</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">VP8Encoder.cpp</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">VP8Decoder.cpp</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">if</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">X86</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_SYSTEM_NAME</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">Darwin</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_SYSTEM_PROCESSOR</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">i386</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_OSX_ARCHITECTURES</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"i386"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">add_library</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">vp8</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">STATIC</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">${</span><span style="margin: 0px; padding: 0px; color: #268bd2 !important;">VP8SRC</span><span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">}</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">elseif</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">IPHONE</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">if</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">SIMULATOR</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">PLATFORM</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"iPhoneSimulator"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">PROCESSOR</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">i386</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">ARCH</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"i386"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">else</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">()</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">PLATFORM</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"iPhoneOS"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">PROCESSOR</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">arm</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">ARCH</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"armv7"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">endif</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">()</span> </span><span style="margin: 0px; padding: 0px;"> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">SDKVER</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"4.0"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">DEVROOT</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"/Developer/Platforms/${PLATFORM}.platform/Developer"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">SDKROOT</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"${DEVROOT}/SDKs/${PLATFORM}${SDKVER}.sdk"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_OSX_SYSROOT</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"${SDKROOT}"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_SYSTEM_NAME</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">Generic</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_SYSTEM_PROCESSOR</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">${</span><span style="margin: 0px; padding: 0px; color: #268bd2 !important;">PROCESSOR</span><span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">}</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_CXX_COMPILER</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"${DEVROOT}/usr/bin/g++"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">set</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">CMAKE_OSX_ARCHITECTURES</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">${</span><span style="margin: 0px; padding: 0px; color: #268bd2 !important;">ARCH</span><span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">}</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">include_directories</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">SYSTEM</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"${SDKROOT}/usr/include"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">link_directories</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">SYSTEM</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">"${SDKROOT}/usr/lib"</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">add_definitions</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">-D_PHONE</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #859900 !important;">add_library</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">(</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">vp8-armv7-darwin</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">STATIC</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">${</span><span style="margin: 0px; padding: 0px; color: #268bd2 !important;">VP8SRC</span><span style="margin: 0px; padding: 0px; color: #586e75 !important; font-weight: bold !important;">}</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">)</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #859900 !important;">endif</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">()</span> </span></code></pre></td></tr></tbody></table></div></figure><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">你能一眼看出这个配置文件干了什么吗？其实这个配置文件想要产生的目标（target）只有一个，就是通过<code style="margin: 0px 3px; padding: 1px 3px; background-color: #dddddd; border: 1px solid #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; background-position: initial initial; background-repeat: initial initial;">${VP8SRC}</code>&nbsp;编译生成的静态库，但因为加上了条件判断，及各种平台相关配置，使得这个配置文件看起来很是复杂。在我看来，编写 CMake 配置文件是一种线性思维，对于同一个目标的配置可能会零散分布在各个地方。而 GYP 则相当不同，GYP 的配置文件更多地强调模块化、结构化。看看下面这个示例文件：</p><figure style="margin: 10px 0px 0px; padding: 5px 15px; background-color: #dddddd; border: 1px solid #cccccc; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px;"><div style="margin: 0px; overflow-x: auto;"><table style="margin: 0px; padding: 0px; border: none; border-spacing: 0px;"><tbody style="margin: 0px; padding: 0px;"><tr style="margin: 0px; padding: 0px;"><td style="margin: 0px; padding: 0px;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px 15px 0px 0px; background-image: none; border-right-width: 1px; border-style: none solid none none; border-right-color: #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; line-height: 1.5; overflow-x: auto; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;"><span style="margin: 0px; padding: 0px;">1</span> <span style="margin: 0px; padding: 0px;">2</span> <span style="margin: 0px; padding: 0px;">3</span> <span style="margin: 0px; padding: 0px;">4</span> <span style="margin: 0px; padding: 0px;">5</span> <span style="margin: 0px; padding: 0px;">6</span> <span style="margin: 0px; padding: 0px;">7</span> <span style="margin: 0px; padding: 0px;">8</span> <span style="margin: 0px; padding: 0px;">9</span> <span style="margin: 0px; padding: 0px;">10</span> <span style="margin: 0px; padding: 0px;">11</span> <span style="margin: 0px; padding: 0px;">12</span> <span style="margin: 0px; padding: 0px;">13</span> <span style="margin: 0px; padding: 0px;">14</span> <span style="margin: 0px; padding: 0px;">15</span> <span style="margin: 0px; padding: 0px;">16</span> <span style="margin: 0px; padding: 0px;">17</span> <span style="margin: 0px; padding: 0px;">18</span> <span style="margin: 0px; padding: 0px;">19</span> <span style="margin: 0px; padding: 0px;">20</span> <span style="margin: 0px; padding: 0px;">21</span> <span style="margin: 0px; padding: 0px;">22</span> <span style="margin: 0px; padding: 0px;">23</span> <span style="margin: 0px; padding: 0px;">24</span> <span style="margin: 0px; padding: 0px;">25</span> <span style="margin: 0px; padding: 0px;">26</span> <span style="margin: 0px; padding: 0px;">27</span> <span style="margin: 0px; padding: 0px;">28</span> <span style="margin: 0px; padding: 0px;">29</span> <span style="margin: 0px; padding: 0px;">30</span> <span style="margin: 0px; padding: 0px;">31</span> <span style="margin: 0px; padding: 0px;">32</span> <span style="margin: 0px; padding: 0px;">33</span> <span style="margin: 0px; padding: 0px;">34</span> <span style="margin: 0px; padding: 0px;">35</span> <span style="margin: 0px; padding: 0px;">36</span> <span style="margin: 0px; padding: 0px;">37</span> <span style="margin: 0px; padding: 0px;">38</span> <span style="margin: 0px; padding: 0px;">39</span> <span style="margin: 0px; padding: 0px;">40</span> <span style="margin: 0px; padding: 0px;">41</span> </pre></td><td style="margin: 0px; padding: 0px 0px 0px 15px; width: 721px; overflow-x: auto;"><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; background-image: none; border: none; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; line-height: 1.5; overflow-x: auto; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px;"><code style="margin: 0px; padding: 0px; background-image: none; border: none; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; background-position: initial initial; background-repeat: initial initial;"><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #586e75 !important;">{</span> </span><span style="margin: 0px; padding: 0px;">  <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'targets'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #586e75 !important;">{</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'target_name'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'foo'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'type'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'&lt;(library)'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'dependencies'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'bar'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'defines'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'DEFINE_FOO'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'DEFINE_A_VALUE=value'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'include_dirs'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'..'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'sources'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'file1.cc'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'file2.cc'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'conditions'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'OS=="linux"'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">{</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'defines'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">            <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'LINUX_DEFINE'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'include_dirs'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">            <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'include/linux'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #586e75 !important;">}],</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span><span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'OS=="win"'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">{</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'defines'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">            <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'WINDOWS_SPECIFIC_DEFINE'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #586e75 !important;">},</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">{</span> <span style="margin: 0px; padding: 0px; color: #93a1a1 !important; font-style: italic !important;"># OS != "win",</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'defines'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">:</span> <span style="margin: 0px; padding: 0px; color: #586e75 !important;">[</span> </span><span style="margin: 0px; padding: 0px;">            <span style="margin: 0px; padding: 0px; color: #2aa198 !important;">'NON_WINDOWS_DEFINE'</span><span style="margin: 0px; padding: 0px; color: #586e75 !important;">,</span> </span><span style="margin: 0px; padding: 0px;">          <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">        <span style="margin: 0px; padding: 0px; color: #586e75 !important;">}]</span> </span><span style="margin: 0px; padding: 0px;">      <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;">    <span style="margin: 0px; padding: 0px; color: #586e75 !important;">}</span> </span><span style="margin: 0px; padding: 0px;">  <span style="margin: 0px; padding: 0px; color: #586e75 !important;">],</span> </span><span style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; color: #586e75 !important;">}</span> </span></code></pre></td></tr></tbody></table></div></figure><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">我们可以立马看出上面这个配置文件的输出目标只有一个，也就是&nbsp;<code style="margin: 0px 3px; padding: 1px 3px; background-color: #dddddd; border: 1px solid #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; background-position: initial initial; background-repeat: initial initial;">foo</code>，它是一个库文件（至于是静态的还是动态的这需要在生成项目时指定），它依赖的目标、宏定义、包含的头文件路径、源文件是什么，以及根据不同平台设定的不同配置等。这种定义配置文件的方式相比 CMake 来说，让我觉得更加舒服，也更加清晰，特别是当一个输出目标的配置越来越多时，使用 CMake 来管理可能会愈加混乱。</p><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">配置文件的编写方式是我区分 GYP 和 CMake 之间最大的不同点，当然 GYP 也有一些小细节值得注意，比如支持跨平台项目工程文件输出，Windows 平台默认是 Visual Studio，Linux 平台默认是 Makefile，Mac 平台默认是 Xcode，这个功能 CMake 也同样支持，只是缺少了 Xcode。Chromium 团队成员也撰文详细<a href="http://code.google.com/p/gyp/wiki/GypVsCMake" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">比较</a>了 GYP 和 CMake 之间的优缺点，在开发 GYP 之前，他们也曾试图转到&nbsp;<a href="http://www.scons.org/" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">SCons</a>（这个我没用过，有经验的同学可以比较一下），但是失败了，于是 GYP 就诞生了。</p><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">当然 GYP 也不是没有缺点，相反，我觉得它的「缺点」一大堆：</p><ul style="margin: 15px 0px 0px 20px; padding: 0px; font-size: 16px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;"><li style="margin: 0px; padding: 0px;">文档不够完整，项目不够正式，某些地方还保留着 Chromium 的影子，看起来像是还没有完全独立出来。</li><li style="margin: 0px; padding: 0px;">大量的括号嵌套，很容易让人看晕，有过 Lisp 使用经验的同学可以对号入座。对于有括号恐惧症，或者不使用现代编辑器的同学基本可以绕行。</li><li style="margin: 0px; padding: 0px;">为了支持跨平台，有时不得不加入某些特定平台的配置信息，比如只适用于 Visual Studio 的&nbsp;<code style="margin: 0px 3px; padding: 1px 3px; background-color: #dddddd; border: 1px solid #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; background-position: initial initial; background-repeat: initial initial;">RuntimeLibrary</code>配置，这不利于跨平台配置文件的编写，也无形中增加了编写复杂度。</li><li style="margin: 0px; padding: 0px;">不支持&nbsp;<code style="margin: 0px 3px; padding: 1px 3px; background-color: #dddddd; border: 1px solid #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; background-position: initial initial; background-repeat: initial initial;">make clean</code>，唯一的方法就是将输出目录整个删除或者手动删除其中的某些文件。</li></ul><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">如果你已经打算尝试 GYP，那一定记得在生成项目工程文件时加上&nbsp;<code style="margin: 0px 3px; padding: 1px 3px; background-color: #dddddd; border: 1px solid #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; background-position: initial initial; background-repeat: initial initial;">--depth</code>&nbsp;参数，譬如：</p><pre style="margin-top: 10px; margin-bottom: 0px; padding: 5px 15px; background-color: #dddddd; border: 1px solid #cccccc; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; line-height: 1.5; overflow-x: auto; border-top-left-radius: 5px; border-top-right-radius: 5px; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px;"><code style="margin: 0px; padding: 0px; background-image: none; border: none; font-family: Menlo, Monaco, 'Andale Mono', 'lucida console', 'Courier New', monospace; font-size: 0.9em; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; background-position: initial initial; background-repeat: initial initial;">$ gyp --depth=. foo.gyp </code></pre><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">这也是一个从 Chromium 项目遗留下来的历史问题。</p><p style="margin: 20px 0px 0px; padding: 0px; font-size: 17px; font-family: HelveticaNeue-Light, 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 30px; text-align: justify; background-color: #eeeeee;">也许你根本用不上跨平台特性，但是 GYP 依然值得尝试。我编写了一份 GYP 配置文件的<a href="https://github.com/xiaogaozi/princess-alist/blob/master/home/xiaogaozi/.templates/TEMPLATE.gyp.tpl" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: #258fb8;">模板</a>，有兴趣的同学可以参考。GYP 和 CMake 分别代表了两种迥异的「风格」，至于孰优孰劣，还得仁者见仁，智者见智。</p><img src ="http://www.blogjava.net/xiaomage234/aggbug/411169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2014-03-18 14:36 <a href="http://www.blogjava.net/xiaomage234/archive/2014/03/18/411169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>php读取网络文件 curl, fsockopen ,file_get_contents 几个方法的效率对比</title><link>http://www.blogjava.net/xiaomage234/archive/2014/02/14/409869.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 14 Feb 2014 08:44:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2014/02/14/409869.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/409869.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2014/02/14/409869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/409869.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/409869.html</trackback:ping><description><![CDATA[<div clearfix"="" style="zoom: 1; padding: 21px 20px 13px; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: #e2e2e2; color: #454545; font-family: tahoma, helvetica, arial; font-size: 12px; line-height: normal; background-color: #ffffff;"><h2><a href="http://u.ajzhan.com/post/13/" style="line-height: 1.5; font-size: 14px; color: #f16e50;">curl效率及稳定原来可以远远超越file_get_contents</a></h2></div><div id="content" mod-cs-content="" text-content=""  clearfix"="" style="zoom: 1; width: 760px; overflow: visible; line-height: 1.5; margin: 7px 0px 10px; padding: 20px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;"><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">最近需要获取别人网站上的音乐数据。用了file_get_contents函数，但是总是会遇到获取失败的问题，尽管按照手册中的 例子设置了超时，可多数时候不会奏效：</p><br />$config['context'] = stream_context_create(array(&#8216;http&#8217; =&gt; array(&#8216;method&#8217; =&gt; &#8220;GET&#8221;,<br />&nbsp;&nbsp; &#8217;timeout&#8217; =&gt; 5//这个超时时间不稳定，经常不奏效<br />&nbsp;&nbsp; )<br />&nbsp;&nbsp;));<br /><br />这时候，看一下服务器的连接池，会发现一堆类似的错误，让我头疼万分：<br />file_get_contents(http://***): failed to open stream&#8230;<br /><br />现在改用了curl库，写了一个函数替换：<br />function curl_file_get_contents($durl){<br />&nbsp;&nbsp;$ch = curl_init();<br />&nbsp;&nbsp;curl_setopt($ch, CURLOPT_URL, $durl);<br />&nbsp;&nbsp;curl_setopt($ch, CURLOPT_TIMEOUT, 5);<br />&nbsp;&nbsp;curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);<br />&nbsp;&nbsp;curl_setopt($ch, CURLOPT_REFERER,_REFERER_);<br />&nbsp;&nbsp;curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);<br />&nbsp;&nbsp;$r = curl_exec($ch);<br />&nbsp;&nbsp;curl_close($ch);<br />&nbsp;&nbsp; return $r;<br />}<br /><br />如此，除了真正的网络问题外，没再出现任何问题。<br />这是别人做过的关于curl和file_get_contents的测试：<br />file_get_contents抓取google.com需用秒数：<br /><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">2.31319094</p>2.30374217<br />2.21512604<br />3.30553889<br />2.30124092<br /><br />curl使用的时间：<br /><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">0.68719101</p>0.64675593<br />0.64326<br />0.81983113<br />0.63956594<br /><br />差距很大？呵呵，从我使用的经验来说，这两个工具不只是速度有差异，稳定性也相差很大。<br /><p style="margin: 0px; padding: 0px;">建议对网络数据抓取稳定性要求比较高的朋友使用上面的 curl_file_get_contents函数，不但稳定速度快，还能假冒浏览器欺骗目标地址哦！</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">看到的其他文章收藏于此===============================</p><p style="margin: 0px; padding: 0px;"></p><p style="margin: 0px; padding: 0px;">php fsockopen</p><p style="margin: 0px; padding: 0px;"></p><p style="margin: 0px; padding: 0px;"></p><p style="margin: 0px; padding: 0px;">方法1: 用file_get_contents 以get方式获取内容<br />&lt;?php<br />$url='http://www.domain.com/';<br />$html = file_get_contents($url);<br />echo $html;<br />?&gt;</p><p style="margin: 0px; padding: 0px;">方法2: 用fopen打开url, 以get方式获取内容<br />&lt;?php<br />$fp = fopen($url, 'r');<br />stream_get_meta_data($fp);<br />while(!feof($fp)) {<br />$result .= fgets($fp, 1024);<br />}<br />echo "url body: $result";<br />fclose($fp);<br />?&gt;</p><p style="margin: 0px; padding: 0px;"><br /></p><p style="margin: 0px; padding: 0px;"><br /></p><p style="margin: 0px; padding: 0px;">方法3：用file_get_contents函数,以post方式获取url<br />&lt;?php<br />$data = array ('foo' =&gt; 'bar');<br />$data = http_build_query($data);</p><p style="margin: 0px; padding: 0px;">$opts = array (<br />'http' =&gt; array (<br />'method' =&gt; 'POST',<br />'header'=&gt; "Content-type: application/x-www-form-urlencoded\r\n" .<br />"Content-Length: " . strlen($data) . "\r\n",<br />'content' =&gt; $data<br />)<br />);</p><p style="margin: 0px; padding: 0px;">$context = stream_context_create($opts);<br />$html = file_get_contents('http://localhost/e/admin/test.html', false, $context);</p><p style="margin: 0px; padding: 0px;">echo $html;<br />?&gt;</p><p style="margin: 0px; padding: 0px;"><br /></p><p style="margin: 0px; padding: 0px;">方法4：用fsockopen函数打开url，以get方式获取完整的数据，包括header和body</p><p style="margin: 0px; padding: 0px;">&lt;?php<br />function get_url ($url,$cookie=false)<br />{<br />$url = parse_url($url);<br />$query = $url[path]."?".$url[query];<br />echo "Query:".$query;<br />$fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30);<br />if (!$fp) {<br />return false;<br />} else {<br />$request = "GET $query HTTP/1.1\r\n";<br />$request .= "Host: $url[host]\r\n";<br />$request .= "Connection: Close\r\n";<br />if($cookie) $request.="Cookie:&nbsp;&nbsp; $cookie\n";<br />$request.="\r\n";<br />fwrite($fp,$request);<br />while()) {<br />$result .= @fgets($fp, 1024);<br />}<br />fclose($fp);<br />return $result;<br />}<br />}<br />//获取url的html部分，去掉header<br />function GetUrlHTML($url,$cookie=false)<br />{<br />$rowdata = get_url($url,$cookie);<br />if($rowdata)<br />{<br />$body= stristr($rowdata,"\r\n\r\n");<br />$body=substr($body,4,strlen($body));<br />return $body;<br />}</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; return false;<br />}<br />?&gt;</p><p style="margin: 0px; padding: 0px;"><br /></p><p style="margin: 0px; padding: 0px;"><br /></p><p style="margin: 0px; padding: 0px;">方法5：用fsockopen函数打开url，以POST方式获取完整的数据，包括header和body</p><p style="margin: 0px; padding: 0px;">&lt;?php<br />function HTTP_Post($URL,$data,$cookie, $referrer="")<br />{</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; // parsing the given URL<br />$URL_Info=parse_url($URL);</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; // Building referrer<br />if($referrer=="") // if not given use this script as referrer<br />$referrer="111";</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; // making string from $data<br />foreach($data as $key=&gt;$value)<br />$values[]="$key=".urlencode($value);<br />$data_string=implode("&amp;",$values);</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; // Find out which port is needed - if not given use standard (=80)<br />if(!isset($URL_Info["port"]))<br />$URL_Info["port"]=80;</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; // building POST-request:<br />$request.="POST ".$URL_Info["path"]." HTTP/1.1\n";<br />$request.="Host: ".$URL_Info["host"]."\n";<br />$request.="Referer: $referer\n";<br />$request.="Content-type: application/x-www-form-urlencoded\n";<br />$request.="Content-length: ".strlen($data_string)."\n";<br />$request.="Connection: close\n";</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; $request.="Cookie:&nbsp;&nbsp; $cookie\n";</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; $request.="\n";<br />$request.=$data_string."\n";</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; $fp = fsockopen($URL_Info["host"],$URL_Info["port"]);<br />fputs($fp, $request);<br />while(!feof($fp)) {<br />$result .= fgets($fp, 1024);<br />}<br />fclose($fp);</p><p style="margin: 0px; padding: 0px;">&nbsp;&nbsp;&nbsp; return $result;<br />}</p><p style="margin: 0px; padding: 0px;">?&gt;</p><p style="margin: 0px; padding: 0px;"><br /></p><p style="margin: 0px; padding: 0px;">方法6:使用curl库，使用curl库之前，可能需要查看一下php.ini是否已经打开了curl扩展</p><p style="margin: 0px; padding: 0px;">&lt;?php<br />$ch = curl_init();<br />$timeout = 5;<br />curl_setopt ($ch, CURLOPT_URL, 'http://www.domain.com/');<br />curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);<br />curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);<br />$file_contents = curl_exec($ch);<br />curl_close($ch);</p><p style="margin: 0px; padding: 0px;">echo $file_contents;<br />?&gt;</p><p style="margin: 0px; padding: 0px;"></p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;">&nbsp;</p><p style="margin: 0px; padding: 0px;"></p>php中 curl， fsockopen ，file_get_contents&nbsp;三个函数 都可以实现采集模拟发言 。 三者有什么区别，或者讲究么&nbsp;&nbsp;<p style="margin: 0px; padding: 0px;"><strong>赵永斌:</strong><br />有些时候用file_get_contents()调用外部文件,容易超时报错。换成curl后就可以.具体原因不清楚<br />curl 效率比file_get_contents()和fsockopen()高一些,原因是CURL会自动对DNS信息进行缓存(亮点啊 有我待亲测)</p><p style="margin: 0px; padding: 0px;"><strong>范佳鹏:</strong><br />file_get_contents curl fsockopen<br />在当前所请求环境下选择性操作，没有一概而论：<br />具我们公司开发KBI应用来看：<br />刚开始采用：file_get_contents<br />后来采用：fsockopen<br />最后到至今采用：curl</p><p style="margin: 0px; padding: 0px;">（远程）我个人理解到的表述如下（不对请指出，不到位请补充）<br />file_get_contents 需要php.ini里开启allow_url_fopen,请求http时，使用的是http_fopen_wrapper，不会keeplive.curl是可以的。<br />file_get_contents()单个执行效率高，返回没有头的信息。<br />这个是读取一般文件的时候并没有什么问题，但是在读取远程问题的时候就会出现问题。<br />如果是要打一个持续连接，多次请求多个页面。那么file_get_contents和fopen就会出问题。<br />取得的内容也可能会不对。所以做一些类似采集工作的时候，肯定就有问题了。<br />sock较底层，配置麻烦，不易操作。 返回完整信息。<br /><strong><br />潘少宁-腾讯：</strong><br />file_get_contents 虽然可以获得某URL的内容，但不能post&nbsp; get啊。<br />curl 则可以post和get啊。还可以获得head信息<br />而socket则更底层。可以设置基于UDP或是TCP协议去交互<br />file_get_contents 和 curl 能干的，socket都能干。<br />socket能干的，curl 就不一定能干了<br />file_get_contents&nbsp; 更多的时候 只是去拉取数据。效率比较高&nbsp; 也比较简单。<br />赵的情况这个我也遇到过，我通过CURL设置host 就OK了。&nbsp; 这和网络环境有关系</p></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/409869.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2014-02-14 16:44 <a href="http://www.blogjava.net/xiaomage234/archive/2014/02/14/409869.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>thrift rpc 使用常见问题解答和经验</title><link>http://www.blogjava.net/xiaomage234/archive/2014/02/14/409868.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 14 Feb 2014 08:42:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2014/02/14/409868.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/409868.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2014/02/14/409868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/409868.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/409868.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">原文：<a href="http://blog.rushcj.com/2010/08/21/try-thrift/" style="color: #336699; text-decoration: none;">http://blog.rushcj.com/2010/08/21/try-thrift/</a></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;"><a href="http://incubator.apache.org/thrift/" style="color: #0070c5; margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: baseline; font-family: 'trebuchet ms', verdana, sans-serif;">Thrift</a>是一个非常棒的工具，是Facebook的开源项目，目前的开发非常的活跃，由Apache管理，所以用的是Apache Software License，这非常重要，因为可以放心的对其修改并用到自己的项目中。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">谈到修改Thrift,这非常重要。因为我觉得如果要严肃的使用Thrift，不可避免的要深入了解它，并几乎都要修改Thrift的代码。一个通信框架，它不可能帮你做到所有的事情，也不可能在不了解的情况下就贸然的使用。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">1.Thrift 的Java Server/Client有个较为严重的bug(https://issues.apache.org/jira/browse/THRIFT-601 )，随机向thrift&nbsp; sever的监听端口发些数据，可能会导致Server OutOfMemory，细细看看代码，这个bug有点土。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">2.Thrift Client线程不安全，多线程下使用可能导致Server和客户端程序崩溃。Client的每次调用远程方法其实是有多次Socket写操作，因此每个线程中使用的Client要保证独立，如果多个线程混用同一个Client(其实是用同一个Socket)，可能会导致传输的字节顺序混乱，使得Server OutOfMemory(参考1）</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">3.Thrift定义数据结构时，尽量避免用map, 或者set。在cpp下, map被对应为std::map(rb tree)和std::set，thrift生成的类不会重载&#8221;&lt;&#8221;，因此需要手动修改生成类，否则link没法通过。较为麻烦。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">4.如果Client端基于效率考虑，要缓存Socket，需要重新实现其TTransport类，以支持 Socket缓存池。当然，这个实现其实跟thrift没多大关系，算是2次开发。但一般都要这么做的吧？</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">5.如果Client基于效率考虑，缓存了Socket，那么thrift Server端的模式选择就较为重要了。如果使用同步的TThreadPoolServer，那么无可避免的，客户端缓存1个Socket，Server端就会有一个线程一直处于Server状态，等待peek这个Socket上的数据。这个线程就不能用于其它请求了。所以，及时清理Client端的Socket及控制Socket池的大小是非常必要的。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">6.听同事说CPP Thrift Server的Epoll NonBlocking模式有效率问题。其实，并发要求不高的Server用LT模式的EPoll其实很方便的，当然，这个要自己给Thrfit Server做patch了，不过也不麻烦。开发起来也是很方便的。我想给我们的Server加个<strong>EPOLLONESHOT</strong>的同步EPoll实现。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">7.CPP下的 TThreadPoolServer和TThreadServer由一个有趣的问题，如果有客户端维护长连接，那么对这个Server实例做析构的时候会堵塞（前面说过了，在peek中&#8230;）。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">8.用valgrind看，thrift cpp似乎有一些内存问题。没细看。</p><p style="color: #333333; font-family: Arial; line-height: 26px; margin: 0px 0px 1.5385em; padding: 0px; border: 0px; outline: 0px; font-size: 13px; vertical-align: baseline;">9.无论是Java，还是CPP，Server端都无法通过合法的方式获取Client的ip, port。可以通过编写ThriftServerEventHandler可以处理这件事情。如果想要获取Client ip, port的话，可以看看这个东西。</p><img src ="http://www.blogjava.net/xiaomage234/aggbug/409868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2014-02-14 16:42 <a href="http://www.blogjava.net/xiaomage234/archive/2014/02/14/409868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>facebook是如何管理代码的</title><link>http://www.blogjava.net/xiaomage234/archive/2014/01/23/409278.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 23 Jan 2014 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2014/01/23/409278.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/409278.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2014/01/23/409278.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/409278.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/409278.html</trackback:ping><description><![CDATA[<div style="margin: 0px auto 15px; padding: 10px 24px 13px 20px; vertical-align: baseline; overflow: auto; zoom: 1; width: 586px; border-width: 1px 0px; border-top-style: solid; border-bottom-style: solid; border-top-color: #e5e5e5; border-bottom-color: #e5e5e5; background-color: #fbfbfb; line-height: 24px; font-size: 16px; color: #434343; font-family: 微软雅黑, Tahoma, Verdana, 宋体;"><strong>感谢<a href="http://rockux.com/" target="_blank" style="color: #003366; text-decoration: none; cursor: pointer;">Rockux</a>的投递</strong><br /><span style="font-weight: 700;">看完之后，终于明白为什么优秀的工程师都去了/想去facebook，因为那里是工程师们的天堂。</span>我对facebook的运转着迷。这是一个很独特的环境，不容易被复制（他们的体系并不适合所有的公司，即使他们努力尝试过）。下面是我和facebook的朋友们关于他们如何开发和管理项目的记录。</div><div style="margin: 10px; padding-right: 10px; padding-left: 10px; vertical-align: baseline; line-height: 23px; min-height: 150px; font-size: 16px; font-family: 微软雅黑, Tahoma, Verdana, 宋体; background-color: #ffffff;">现在距离我收集的这些信息又过去6个月了，我相信facebook肯定又对他们的项目开发实践进行了改进。所以这些记录可能会有点过时。同时facebook的工程师驱动文化也越来越为大众所知。非常感谢那些帮助我整理这篇文章的facebook的朋友们。<br /><br />记录：<br /><br /><ul style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;"><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">截止到2010年6月，facebook有将近2000名员工，10个月前只有1100名，一年之间差不多翻了一番。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">两个最大的部门是工程师和运维，每个部门大概都是400-500人。这两个部门人数大约占了公司的一半。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">产品经理与工程师的比例大约为1-7到1-10。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">每个工程师入职时，都要接收4-6周的培训，通过修补bugs和听高级开发工程师的课程来熟悉facebook。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">培训结束后，每个工程师都可以接触线上的数据库(更大的权力意味着更大的责任，也有一份"勿做清单"，不然可能会被开，比如共享用户的隐私数据)。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">有非常牢靠的安全体系，以免有人不小心/故意做了些不好的事。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">每个工程师可以修改facebook的任何代码，随时可以迁入。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">浓厚的工程师驱动文化。"产品经理基本可以被忽略"，这是facebook一名员工的话。工程师可以修改流程的细节，重新安排工作任务，随时植入自己的想法。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">在每月的跨部门会议上，由工程师来汇报工作进度，市场部和产品经理会出席会议，也可以做些简短的发言，但如果说得太多，很可能就会被打小报告。他们确实想让工程师来主导产品的开发，对自己的产品负责。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">项目需要的资源都是自愿的</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">一个产品经理把工程师们召集到一起，让他们对他的想法产生兴趣。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">工程师们决定开发那些让他们感兴趣的特性。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">工程师跟他们的经理说："我下周想开发这5个新特性"。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">经理会让工程师独立开发，可能有时会让他优先完成一些特性。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">工程师独立完成所有的特性&#8212;&#8212;前端/后端/数据库，等等所有相关的部分。如果需要得到设计人员的帮助，需要先让设计人员对你的想法产生兴趣。其他如架构之类的也一样。但总体来说，工程师要独立完成所有的任务。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">对于某个特性是否值得开发的争论，通常是这么解决的：花一个星期的时间完成他，并在小部分人群中(如1%)进行测试。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">工程师常常希望解决难题，这能获得声望和尊敬。他们很难对前端项目或UI设计产生太大的兴趣。这跟其他公司可能正好相反。在facebook，后端任务，比如新的feed算法，广告投放算法，memcache优化等等，是工程师真正感兴趣的。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">所有的代码修改都要进行审核(通过一个或多个工程师)，但News Feed是个例外，因为太重要了，Zuckerberg会亲自review。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">所有的修改至少要被一个人审核，而且这个系统可以让任何人很方便地审核其他人的代码，即使你没有邀请他</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">工程师负责测试，代码修复，和维护自己的项目。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">每个办公室或通过VPN连接的员工会使用下一版的facebook，这个版本的facebook会经常更新，通常比公开的早1-12小时。所有的员工被强烈建议提交bugs，而且通常会很快被修复。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">很奇怪只有很少的QA或自动测试&#8212;&#8212;"大部分工程师都能写出基本没有bug的代码，只是在其他公司他们不需要这么做。如果有QA部门，他们只要把代码写完，扔给他们就行了"</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">[针对上一条]我们有自动测试，代码发布前必须要通过测试。我们不相信"所有的工程师都能写出没有bug的代码"，毕竟这是一个商业公司。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">很奇怪，缺少产品经理的影响和控制&#8212;&#8212;产品经理是很独立的和自由的。产生影响力的关键是与工程师和工程师的领导们们搞好关系。需要大致了解技术，不要提一些愚蠢的想法。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">所有提交的代码每周二打包一次。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">只要多一分努力，终于一天会发生改变。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">星期二的代码发布，需要所有的提交过代码的工程师在场。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">代码打包前，工程师必须在一个特殊的IRC channel上。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">运维执行打包过程</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">facebook有大约60000台服务器</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">有9个代码发布级别</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">最小的级别只有6台服务器</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">星期二的代码发布会先发布到6台服务器上，运维组会检测这6台服务器的反应，保证代码正常工作，然后再提交到下一级</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">如果发布出现了一些问题（如报错等等），那么就停止下一级的部署，提交出错代码的工程师负责修复问题，然后从头继续发布。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">所以一次发布可能会经历几次重复：1-2-3-fix. 回到1. 1-2-3-4-5-fix. 回到1. 1-2-3-4-5-6-7-8-9</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">运维组是受过严格训练，倍受尊敬，而且有商业意识的。他们的工作包括分析错误日志，负载和内存状态等等。还包括用户行为。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">代码发布期间，运维组使用IRC-based页面系统，可以通过facebook/email/irc/im/sms ping每一个工程师，如果需要他们注意的话。对运维组不做回应是一件很羞愧的事。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">代码一旦发布到第9级，并且稳定运行，就算发布成功了。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">如果一个特性没有按时完成，也没什么大不了的，下次完成时一并发布即可。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">如果被svn-blamed,public shamed或工作经常疏忽就很可能被开除。"这是一个高效的文化"。不够高效或者不够聪明的员工会被剔除。管理层会在6个月的时间里观察你表现，如果不合格，只能说再见。每一级都是这个待遇，即使是C级别和VP级别，如果不够高效，也会被开除。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">被责骂不会导致解雇。我们特别尊重别人，原谅别人。大部分高级工程师都或多或少犯过一些严重的错误，包括我。但没有人因此被解雇。</li><li style="margin: 0px; padding: 0px; vertical-align: baseline; list-style: none;">我也没有遇到过因为上面提到过的犯错误而被解雇。有些人犯了错，他们会非常努力地去修复，也让其他人得到了学习。</li></ul></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/409278.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2014-01-23 15:21 <a href="http://www.blogjava.net/xiaomage234/archive/2014/01/23/409278.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>php 项目开发基础工具</title><link>http://www.blogjava.net/xiaomage234/archive/2014/01/23/409263.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 23 Jan 2014 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2014/01/23/409263.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/409263.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2014/01/23/409263.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/409263.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/409263.html</trackback:ping><description><![CDATA[1&nbsp;<span style="background-color: #ffffff; font-family: 微软雅黑, Verdana, sans-serif, 宋体; font-size: 13px;">PHPUnit<br />是一个轻量级的PHP测试框架。它是在PHP5下面对JUnit3系列版本的完整移植，是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计)</span><p style="margin: 0px 0px 10px; padding: 0px; font-family: 微软雅黑, Verdana, sans-serif, 宋体; font-size: 13px; background-color: #ffffff;">单元测试是几个现代敏捷开发方法的基础，使得PHPUnit成为许多大型PHP项目的关键工具。这个工具也可以被<a href="http://www.oschina.net/p/xdebug" target="_blank" style="margin: 0px; padding: 0px; color: #3e62a6; outline: 0px;">Xdebug</a>扩展用来生成代码覆盖率报告 ，并且可以与phing集成来自动测试，最合它还可以和<a href="http://www.oschina.net/p/selenium" target="_blank" style="margin: 0px; padding: 0px; color: #3e62a6; outline: 0px;">Selenium</a>整合来完成大型的自动化集成测试。<br />资料:<a href="http://phpunit.de/documentation.html">http://phpunit.de/documentation.html</a><br /><br />2 composer<br />项目依赖管理工具 资料：<a href="http://getcomposer.org/doc/00-intro.md#installation-nix" style="font-family: verdana, 'courier new'; font-size: 14px;">http://getcomposer.org/doc/00-intro.md#installation-nix<br /><br />3</a>&nbsp;syslog-ng &nbsp;<br />集中日志服务器，相比syslog更有优势 资料：<a href="http://www.gaizaoren.org/archives/428" style="font-family: verdana, 'courier new'; font-size: 14px;">http://www.gaizaoren.org/archives/428</a></p><img src ="http://www.blogjava.net/xiaomage234/aggbug/409263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2014-01-23 11:24 <a href="http://www.blogjava.net/xiaomage234/archive/2014/01/23/409263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[开源推荐]Google新的Web UI库：Polymer 【转】</title><link>http://www.blogjava.net/xiaomage234/archive/2013/12/04/407211.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Wed, 04 Dec 2013 07:20:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/12/04/407211.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/407211.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/12/04/407211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/407211.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/407211.html</trackback:ping><description><![CDATA[<div style="margin: 0px 0px 1.5em; padding: 5px 10px; list-style: none; background-color: #f7f7f7; color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px;"><strong>摘要：</strong>Polymer是由原Palm webOS开发Enyo框架的团队加盟Google后打造的，基于Shadow DOM、Custom Elements、MDV等最新浏览器特性，支持Web Components。</div><div news_content"="" style="margin: 0px 0px 30px; list-style: none; color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #ffffff;"><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">今年的Google I/O大会，绝对是一场<a href="http://www.csdn.net/article/2013-05-16/2815304" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;">为开发者所准备的盛会</a>，<a href="http://www.csdn.net/article/2013-05-16/2815305-google-io-2013" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;">发布多个软件产品与服务</a>，并且主要以发布平台和服务为主，比如让<a href="http://www.csdn.net/article/2013-05-16/2815320-Google-IO-2013-Android-Studio" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;">Android开发者称赞的Android Studio</a>、推出Google Play Game服务、对地图进行重大升级等。而在Web平台领域，Google则发布了最新的Web UI库Polymer。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">Polymer基于Shadow DOM、Custom Elements、MDV等最新浏览器特性，代表了下一代Web框架的方向：一切皆组件、尽量减少代码量、尽量减少框架限制。由加盟Google的原Palm webOS开发团队打造。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><a href="http://cms.csdnimg.cn/article/201305/17/5195c5cedfe1f.jpg" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;"><img src="http://cms.csdnimg.cn/article/201305/17/5195c5cedfe1f.jpg" border="0" style="vertical-align: middle; border: none;"  alt="" />&nbsp;</a><br /></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">架构图</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><strong>快速入门</strong></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">1.把项目拷贝到解决方案的根目录文件夹中，参考&nbsp;<a href="http://www.polymer-project.org/getting-the-code.html" style="cursor: pointer; color: #0066cc; text-decoration: none;">Get the code</a>。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><div style="margin: 0px; list-style: none;"><div id="highlighter_91214"  js"="" style="margin: 0px 0px 20px; list-style: none; word-break: break-all;"><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; border: none; width: 618px;"><tbody><tr><td style="margin: 0px; list-style: none; border: none; white-space: nowrap; width: 30px; padding: 0px !important; color: #333333 !important; background-color: #eeeeee !important; text-align: center !important;"><div number1="" index0=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 48px !important;">1</div></td><td style="margin: 0px; list-style: none; border: none; padding: 0px !important;"><div style="margin: 0px; list-style: none;"><div number1="" index0=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">git clone git:</code><code comments"="" style="margin: 0px; padding: 0px; list-style: none; display: block; color: #008200 !important;">//github.com/Polymer/polymer.git --recursive</code></div></div></td></tr></tbody></table></div></div>2.启动Web服务器<p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">3.在主页面引用polymer.js</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><div style="margin: 0px; list-style: none;"><div id="highlighter_710801"  js"="" style="margin: 0px 0px 20px; list-style: none; word-break: break-all;"><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; border: none; width: 618px;"><tbody><tr><td style="margin: 0px; list-style: none; border: none; white-space: nowrap; width: 30px; padding: 0px !important; color: #333333 !important; background-color: #eeeeee !important; text-align: center !important;"><div number1="" index0=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">1</div></td><td style="margin: 0px; list-style: none; border: none; padding: 0px !important;"><div style="margin: 0px; list-style: none;"><div number1="" index0=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;script src=</code><code string"="" style="margin: 0px; padding: 0px; list-style: none; color: #0066cc !important;">"Polymer/polymer.js"</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&gt;&lt;/script&gt;</code></div></div></td></tr></tbody></table></div></div>4.阅读<a href="http://www.polymer-project.org/getting-started.html" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;">开始指南</a><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">5.学习如何使用Polymer内核快速搭建Web组件</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">6.玩转<a href="https://github.com/Polymer/toolkit-ui" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;">toolkit-ui示例</a>（必须在Web服务器上运行）</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">7.加入<a href="http://www.polymer-project.org/discuss.html" style="cursor: pointer; color: #0066cc; text-decoration: none;">mailing list</a>，提问并且得到相应地回复。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><strong>Polymer内核</strong></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">Polymer内核代码由polymer.js这个文件提供，其提供了一个薄层代码来表示Polymer选项，并且提供了所有组件使用的糖。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><ol style="margin: 0px 0px 1em 30px; padding: 0px; list-style-position: initial; list-style-image: initial;"><li style="margin: 0px; padding: 0px; list-style: decimal;">组件声明</li><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">Web组件声明代码如下所示：</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><div style="margin: 0px; list-style: none;"><div id="highlighter_558719"  js"="" style="margin: 0px 0px 20px; list-style: none; word-break: break-all;"><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; border: none; width: 588px;"><tbody><tr><td style="margin: 0px; list-style: none; border: none; white-space: nowrap; width: 30px; padding: 0px !important; color: #333333 !important; background-color: #eeeeee !important; text-align: center !important;"><div number1="" index0=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">1</div><div number2="" index1=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">2</div><div number3="" index2=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">3</div><div number4="" index3=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">4</div><div number5="" index4=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">5</div><div number6="" index5=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">6</div><div number7="" index6=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">7</div><div number8="" index7=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">8</div></td><td style="margin: 0px; list-style: none; border: none; padding: 0px !important;"><div style="margin: 0px; list-style: none;"><div number1="" index0=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;element name=</code><code string"="" style="margin: 0px; padding: 0px; list-style: none; color: #0066cc !important;">"tag-name"</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&gt;</code></div><div number2="" index1=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;template&gt;</code></div><div number3="" index2=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;!-- shadow DOM here --&gt;</code></div><div number4="" index3=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;/template&gt;</code></div><div number5="" index4=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;script&gt;</code></div><div number6="" index5=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code comments"="" style="margin: 0px; padding: 0px; list-style: none; display: block; color: #008200 !important;">// lifecycle setup here</code></div><div number7="" index6=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;/script&gt;</code></div><div number8="" index7=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;/element&gt;</code></div></div></td></tr></tbody></table></div></div><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">在该组件中添加Polymer.register生命周期来初始化组件的&lt;script&gt;块，如下所示：</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><div style="margin: 0px; list-style: none;"><div id="highlighter_972997"  js"="" style="margin: 0px 0px 20px; list-style: none; word-break: break-all;"><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; border: none; width: 588px;"><tbody><tr><td style="margin: 0px; list-style: none; border: none; white-space: nowrap; width: 30px; padding: 0px !important; color: #333333 !important; background-color: #eeeeee !important; text-align: center !important;"><div number1="" index0=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">1</div><div number2="" index1=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">2</div><div number3="" index2=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">3</div><div number4="" index3=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">4</div><div number5="" index4=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">5</div><div number6="" index5=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">6</div><div number7="" index6=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">7</div><div number8="" index7=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">8</div></td><td style="margin: 0px; list-style: none; border: none; padding: 0px !important;"><div style="margin: 0px; list-style: none;"><div number1="" index0=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;font face=</code><code string"="" style="margin: 0px; padding: 0px; list-style: none; color: #0066cc !important;">"Menlo, Monaco, monospace, sans-serif"</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&gt;&lt;element name=</code><code string"="" style="margin: 0px; padding: 0px; list-style: none; color: #0066cc !important;">"tag-name"</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&gt;</code></div><div number2="" index1=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code spaces"="" style="margin: 0px; padding: 0px; list-style: none;">&nbsp;&nbsp;</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;template&gt;</code></div><div number3="" index2=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code spaces"="" style="margin: 0px; padding: 0px; list-style: none;">&nbsp;&nbsp;&nbsp;&nbsp;</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;!-- shadow DOM here --&gt;</code></div><div number4="" index3=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code spaces"="" style="margin: 0px; padding: 0px; list-style: none;">&nbsp;&nbsp;</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;/template&gt;</code></div><div number5="" index4=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code spaces"="" style="margin: 0px; padding: 0px; list-style: none;">&nbsp;&nbsp;</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;script&gt;</code></div><div number6="" index5=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code spaces"="" style="margin: 0px; padding: 0px; list-style: none;">&nbsp;&nbsp;&nbsp;&nbsp;</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">Polymer.register(</code><code keyword"="" style="margin: 0px; padding: 0px; list-style: none; color: #006699 !important; font-weight: bold !important;">this</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">);</code></div><div number7="" index6=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code spaces"="" style="margin: 0px; padding: 0px; list-style: none;">&nbsp;&nbsp;</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;/script&gt;</code></div><div number8="" index7=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">&lt;/element&gt;&lt;/font&gt;</code></div></div></td></tr></tbody></table></div></div><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><li style="margin: 0px; padding: 0px; list-style: decimal;">元素初始化</li><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">第一个参数Polymer.register是引用到&lt;element&gt;元素里的，因为脚本在element标记里运行，所以参数就设为&#8220;this&#8221;。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">你可以提供第二个对象参数到Polymer.register里去定义对象原型，在下面的代码里，该组件初始化了一个message属性和ready方法。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"></p><div style="margin: 0px; list-style: none;"><div id="highlighter_51101"  js"="" style="margin: 0px 0px 20px; list-style: none; word-break: break-all;"><table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; border: none; width: 588px;"><tbody><tr><td style="margin: 0px; list-style: none; border: none; white-space: nowrap; width: 30px; padding: 0px !important; color: #333333 !important; background-color: #eeeeee !important; text-align: center !important;"><div number1="" index0=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">1</div><div number2="" index1=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">2</div><div number3="" index2=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">3</div><div number4="" index3=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">4</div><div number5="" index4=""  alt2"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">5</div><div number6="" index5=""  alt1"="" style="margin: 0px; padding-left: 3px; list-style: none; padding-right: 8px !important; border-right-width: 3px !important; border-right-style: solid !important; border-right-color: #146b00 !important; height: 24px !important;">6</div></td><td style="margin: 0px; list-style: none; border: none; padding: 0px !important;"><div style="margin: 0px; list-style: none;"><div number1="" index0=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">Polymer.register(</code><code keyword"="" style="margin: 0px; padding: 0px; list-style: none; color: #006699 !important; font-weight: bold !important;">this</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">, {</code></div><div number2="" index1=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">message:&nbsp;</code><code string"="" style="margin: 0px; padding: 0px; list-style: none; color: #0066cc !important;">"Hello!"</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">,</code></div><div number3="" index2=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">ready:&nbsp;</code><code keyword"="" style="margin: 0px; padding: 0px; list-style: none; color: #006699 !important; font-weight: bold !important;">function</code><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">() {</code></div><div number4="" index3=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code comments"="" style="margin: 0px; padding: 0px; list-style: none; display: block; color: #008200 !important;">// component is ready now, we can do stuff</code></div><div number5="" index4=""  alt2"="" style="margin: 0px; list-style: none; padding-left: 10px !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">}</code></div><div number6="" index5=""  alt1"="" style="margin: 0px; list-style: none; padding-left: 10px !important; background-color: #f8f8f8 !important;"><code plain"="" style="margin: 0px; padding: 0px; list-style: none;">});</code></div></div></td></tr></tbody></table></div></div></ol><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">目前，Polymer还处于初期阶段，它和其他框架一样，尽可能地拥抱HTML。它的目标是通过使用像Custom Elements和Shadow DOM这些新兴的Web标准的少量独立polyfill发展Web平台。此外，应用于移动平台也是其中的核心目标之一。Polymer开发团队正在研究响应式组件，让其可以正确无误地在台式机、平板电脑、手机上进行自动化配置。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">当然，Polymer的诞生也意味着Google现在有三个相互竞争的Web应用开发库：Polymer、Dart（也具有UI开发功能）和AngularJS。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">对于Polymer，开发者有哪些话要说呢？让我们一起来看下：</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><a href="http://weibo.com/starway99" style="cursor: pointer; color: #0066cc; text-decoration: none;">清风一二两</a>：Palm webOS用另一种方式重生？<br /></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><a href="http://weibo.com/601048793?refer=usercard&amp;wvr=5" style="cursor: pointer; color: #0066cc; text-decoration: none;">三合一赵</a>：Enyo的Google版~换汤不换药~<a href="http://club.weibo.com/intro" style="cursor: pointer; color: #0066cc; text-decoration: none;"></a><br /></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><a href="http://weibo.com/liuhann?refer=usercard&amp;wvr=5" style="cursor: pointer; color: #0066cc; text-decoration: none;">刘晗的微博</a>：在HTML领域离标准太远自己搞一套，出路不大。特别是像这种绑定机制，貌似理念是MVC，但MVC这种东西做简单页面还行。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><a href="https://news.ycombinator.com/user?id=eldude" target="_blank" style="cursor: pointer; color: #0066cc; text-decoration: none;">eldude</a>：声明性质、封装、数据绑定、属性和事件驱动API这些都是数量级的，要比现有JavaScript/HTML UI组件简单。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><a href="https://news.ycombinator.com/user?id=neilk" style="cursor: pointer; color: #0066cc; text-decoration: none;">neilk</a>：这个框架看起来非常酷，但&#8220;built by Google&#8221;有点用词不当，像Closure或Angular、Polymer等这些都Google内部使用的技术，在经过千锤百炼后才像面向公众，因此称作&nbsp;"technologies by Googlers"更为合适。</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;"><strong>相关资料</strong></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">Polymer主页：&nbsp;<a href="http://www.polymer-project.org/" style="cursor: pointer; color: #0066cc; text-decoration: none;">http://www.polymer-project.org/</a></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">项目主页上的FAQ描述比较清晰：&nbsp;<a href="http://www.polymer-project.org/faq.html" style="cursor: pointer; color: #0066cc; text-decoration: none;">http://www.polymer-project.org/faq.html</a>&nbsp;<br /></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">架构图：&nbsp;<a href="http://www.polymer-project.org/images/architecture-diagram.svg?20130516" style="cursor: pointer; color: #0066cc; text-decoration: none;">http://www.polymer-project.org/images/architecture-diagram.svg?20130516</a><br /></p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none;">GitHub：&nbsp;<a href="https://github.com/polymer/polymer" style="cursor: pointer; color: #0066cc; text-decoration: none;">https://github.com/polymer/polymer</a>&nbsp;</p><p style="margin: 0px 0px 1.5em; padding: 0px; list-style: none; font-weight: bold;">本文为CSDN编译整理，未经允许不得转载，如需转载请联系market#csdn.net(#换成@)</p></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/407211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-12-04 15:20 <a href="http://www.blogjava.net/xiaomage234/archive/2013/12/04/407211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>互联网公司linux运维生产场景常用软件工具一览【转自老男孩】</title><link>http://www.blogjava.net/xiaomage234/archive/2013/11/07/406109.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 07 Nov 2013 08:12:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/11/07/406109.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/406109.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/11/07/406109.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/406109.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/406109.html</trackback:ping><description><![CDATA[<p style="padding: 0px; margin: 0px; clear: both; height: auto; overflow: hidden; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><span style="padding: 0px; margin: 0px; font-size: 16px;"><strong style="padding: 0px; margin: 0px;">互联网公司linux运维生产场景常用软件工具一览，同时补充了个别常用但不是开源的软件。</strong><br style="padding: 0px; margin: 0px;" /><br style="padding: 0px; margin: 0px;" />下午受邀请参加了一个BBS活动，于是有了下面的内容。<br style="padding: 0px; margin: 0px;" />下面是在linux网站运维方向老男孩最近几年常用的免费的开源软件，临时即兴想起来的，在这里和大家分享，希望给初学者指引一点路。<br style="padding: 0px; margin: 0px;" />linux的世界真的很精彩，还没入门的朋友赶紧进来吧！</span></p><p style="padding: 0px; margin: 0px; clear: both; height: auto; overflow: hidden; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;"><span style="padding: 0px; margin: 0px; font-size: 16px;">操作系统：Centos<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>Freebsd,Ubuntu,Redhatlinux,suselinux<br style="padding: 0px; margin: 0px;" />网站服务：apache<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>nginx<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,lighttpd,php<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>tomcat<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>resin<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>数据库：Mysql<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>PostgreSQL,Mysql-proxy,<span style="padding: 0px; margin: 0px; background-color: #f8f8f8; text-indent: 28px; font-size: 14px; line-height: 25px; font-family: 宋体; color: #333333;">MariaDB</span><br style="padding: 0px; margin: 0px;" />代理相关：lvs,keepalived,haproxy,nginx,apache,heartbeat（此行都是<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;）<br style="padding: 0px; margin: 0px;" /></span>网站缓存：squid<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>nginx<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>varnish<br style="padding: 0px; margin: 0px;" />内存缓存：memcached<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>memcachedb,TokyoTyrant<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>MongoDB,Cassandra<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>redis&#8251;,tair,CouchDB<br style="padding: 0px; margin: 0px;" />存储相关：Nfs<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>Moosefs<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>Hadoop<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>gfs<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>lustre,FastDFS<br style="padding: 0px; margin: 0px;" />版本管理：cvs,svn<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>git<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>监控报警：mboy,mrtg,nagios<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,cacti<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,zabbix,munin<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,hyperic<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>域名解析：bind<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,powerdns,dnsmq<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>同步软件：rsync,inotify,sersync,drbd,csync2,union,lsyncd,scp（此行都是&#8251;）<br style="padding: 0px; margin: 0px;" />分发工具：Secboy<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,expect<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>puppet<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>cfengine<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>ssh+rsync+sersync<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>虚拟软件：xen<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,kvm<br style="padding: 0px; margin: 0px;" />内网软件：iptables<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,zebra<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,iftraf,ntop<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,tc<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,iftop<br style="padding: 0px; margin: 0px;" />邮件软件：qmail<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>posfix<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>sendmail<br style="padding: 0px; margin: 0px;" />远程拨号：openvpn<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,pptp,openswan<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,ipip<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>统一认证：ldap(可结合微软活动目录)<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>队列工具：ActiveMQ<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;,</span>RabbitMQ,MemcacheQ<br style="padding: 0px; margin: 0px;" />打包发布：mvn<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,ants<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>,jenkins<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;<br style="padding: 0px; margin: 0px;" /></span>测试软件：apacheab,smokeping,siege,JMeter,Webbench,LoadRunner（此行都是<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>）<br style="padding: 0px; margin: 0px;" />日志相关：syslog,rsyslog,Awstats<br style="padding: 0px; margin: 0px;" />DB代理：mysql-proxy,amoeba（更多还是程序实现读写分离）<br style="padding: 0px; margin: 0px;" />搜索软件：Sphinx,Xapian（大公司会自己开发类似百度的小规模内部搜索引擎）<br style="padding: 0px; margin: 0px;" /></span><span style="padding: 0px; margin: 0px; font-size: 16px;"><br style="padding: 0px; margin: 0px;" />提示：<br style="padding: 0px; margin: 0px;" />1）以上所有软件都是老男孩用过或测试过的。<br style="padding: 0px; margin: 0px;" />2）带<strong style="padding: 0px; margin: 0px;"><span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span></strong>的为老男孩最近几年用的比较多，可信任使用的。也是近年来linux运维的大众。<br style="padding: 0px; margin: 0px;" />3）有了功能分类和软件名，大家有需求，可以按功能找软件直接G就知道了。</span><br style="padding: 0px; margin: 0px;" /><span style="padding: 0px; margin: 0px; font-size: 16px;">4）学习要有舍有得，什么都抓必然短时间都不会精，希望大家能抓重点，抓精髓，大众软件（带<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>）先熟练了，这是基础加提高，在研究小众软件（不带<span style="padding: 0px; margin: 0px; color: #ff0000;">&#8251;</span>），这是高手之路，最后在研究偏门的，世外高手之路，当然前提是先掌握前面的大众和小众。<br style="padding: 0px; margin: 0px;" />5）当然还有一些没有大众开源的有一些也很棒，如审计堡垒机程序。<br style="padding: 0px; margin: 0px;" /><br style="padding: 0px; margin: 0px;" />还有用的多的，老男孩落下的，大家补充啊。</span></p><p style="padding: 0px; margin: 0px; clear: both; height: auto; overflow: hidden; color: #555555; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff;">本文出自 &#8220;<a href="http://oldboy.blog.51cto.com/" style="padding: 0px; margin: 0px; color: #015f91; text-decoration: none;">老男孩linux运维</a>&#8221; 博客，请务必保留此出处<a href="http://oldboy.blog.51cto.com/2561410/775056" style="padding: 0px; margin: 0px; color: #015f91; text-decoration: none;">http://oldboy.blog.51cto.com/2561410/775056</a></p><img src ="http://www.blogjava.net/xiaomage234/aggbug/406109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-11-07 16:12 <a href="http://www.blogjava.net/xiaomage234/archive/2013/11/07/406109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>各数据交换的协议优劣比较</title><link>http://www.blogjava.net/xiaomage234/archive/2013/09/11/403948.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Wed, 11 Sep 2013 04:08:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/09/11/403948.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/403948.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/09/11/403948.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/403948.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/403948.html</trackback:ping><description><![CDATA[<div style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal;">@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);<span style="border-collapse: collapse; line-height: 28px;"><span style="border-collapse: separate;"><h2>如何选择数据交换协议</h2><p style="margin: 10px 0px;">　　选择什么样的协议跟我们的应用场景有很大的关系。我们需要考虑我们开发是否方便、接口是否容易发布、是否需要考虑带宽占用成本、序列化和反序列化的性能、接口协议的扩展性等等。下面我们看下几个比较常用的交换协议实现。</p><table border="1" width="654" height="280"><tbody><tr><td style="font-size: 12px;">协议</td><td style="font-size: 12px;">实现</td><td style="font-size: 12px;">跨语言</td><td style="font-size: 12px;">性能</td><td style="font-size: 12px;">传输量</td><td style="font-size: 12px;">RPC</td></tr><tr><td style="font-size: 12px;">xml</td><td style="font-size: 12px;">广泛</td><td style="font-size: 12px;">几乎所有</td><td style="font-size: 12px;">低</td><td style="font-size: 12px;">很大</td><td style="font-size: 12px;">N（可实现）</td></tr><tr><td style="font-size: 12px;">json</td><td style="font-size: 12px;">广泛</td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">一般</td><td style="font-size: 12px;">一般</td><td style="font-size: 12px;">N（可实现）</td></tr><tr><td style="font-size: 12px;">php serialize</td><td style="font-size: 12px;">PHPRPC</td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">一般</td><td style="font-size: 12px;">一般</td><td style="font-size: 12px;">Y</td></tr><tr><td style="font-size: 12px;">hessian</td><td style="font-size: 12px;">hessian</td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">一般</td><td style="font-size: 12px;">小</td><td style="font-size: 12px;">Y</td></tr><tr><td style="font-size: 12px;">thrift</td><td style="font-size: 12px;">thrift</td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">高</td><td style="font-size: 12px;">小</td><td style="font-size: 12px;">Y</td></tr><tr><td style="font-size: 12px;">protobuf</td><td style="font-size: 12px;">protobuf</td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">高</td><td style="font-size: 12px;">小</td><td style="font-size: 12px;">N（可实现）</td></tr><tr><td style="font-size: 12px;">ice</td><td style="font-size: 12px;">ice</td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">高</td><td style="font-size: 12px;">小</td><td style="font-size: 12px;">Y</td></tr><tr><td style="font-size: 12px;">avro</td><td style="font-size: 12px;"><a title="Apache Avro " href="http://avro.apache.org/" target="_self" style="color: #0066aa; text-decoration: none;">Apache Avro</a></td><td style="font-size: 12px;">少量</td><td style="font-size: 12px;">高</td><td style="font-size: 12px;">小</td><td style="font-size: 12px;">Y</td></tr><tr><td style="font-size: 12px;">messagepack</td><td style="font-size: 12px;"><a title="messagepack " href="http://msgpack.org/" target="_self" style="color: #0066aa; text-decoration: none;">messagepack</a></td><td style="font-size: 12px;">大量</td><td style="font-size: 12px;">高</td><td style="font-size: 12px;">小</td><td style="font-size: 12px;">Y</td></tr></tbody></table><p style="margin: 10px 0px;">　　上面表格列出了一些常用数据交换协议的一些特性的比较。这里并没有比较好坏，只是想说明不同数据交换协议是有区别的，所以我们需要在我们的应用场景中进行选择。<br /><br />&nbsp;<a title="messagepack " href="http://msgpack.org/" target="_self" style="color: #0066aa; text-decoration: none;">messagepack</a>相关资料</p><p style="margin: 10px 0px;">http://pluto418.iteye.com/blog/1108457<br /><span style="color: #666666; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 19px;">优势：<br /><strong>1.序列化和反序列化所需要的时间少。通过30000条的记录来测试，msgpack序列化的时间比使用jason来序列化JSON的时间要少三分之一；而反序列化的时间则要少一半。<br />2.生成的文件体积小。同样也是基于30000条记录来测试，msgpack序列化后生成的二进制文件比用jason序列化出来的时间要少一半。</strong>&nbsp;<br />劣势：<br /><strong>1.msgpack对复杂的数据类型（List、Map）支持的不够，序列化没有问题，但是反序列化回来就很麻烦，尤其是对于java开发人员。<br />2.在上面也提到过，msgpack是通过value的顺序来定位属性的，那么需要在不同的语言中都要维护同样的模型以及模型中属性的顺序。这个会让开发人员很困扰。<br />3.msgpack无法支持在模型中包含和嵌套其他自定义的模型（如weibo模型中包含comment的列表）。<br /><br /></strong></span></p></span></span>@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);<p style="margin: 10px 0px; font-size: 0.75em;">posted on 2011-12-26 10:57&nbsp;<a href="http://www.blogjava.net/toby/" style="color: #0066aa; text-decoration: none;">tobyxiong</a>&nbsp;阅读(958)&nbsp;<a href="http://www.blogjava.net/toby/archive/2011/12/26/367165.html#Post" style="color: #0066aa; text-decoration: none;">评论(0)</a>&nbsp;&nbsp;<a href="http://www.blogjava.net/toby/admin/EditPosts.aspx?postid=367165" style="color: #0066aa; text-decoration: none;">编辑</a>&nbsp;&nbsp;<a href="http://www.blogjava.net/toby/AddToFavorite.aspx?id=367165" style="color: #0066aa; text-decoration: none;">收藏</a>&nbsp;所属分类:&nbsp;<a href="http://www.blogjava.net/toby/category/38380.html" style="color: #0066aa; text-decoration: none;">java</a></p></div><img src="http://www.blogjava.net/toby/aggbug/367165.html?webview=1" width="1" height="1" style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; line-height: normal;"  alt="" /><img src ="http://www.blogjava.net/xiaomage234/aggbug/403948.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-09-11 12:08 <a href="http://www.blogjava.net/xiaomage234/archive/2013/09/11/403948.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xsplit A PHP extension for Chinese segmentation using MMSEG algorithm[zz]</title><link>http://www.blogjava.net/xiaomage234/archive/2013/08/13/402755.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Tue, 13 Aug 2013 09:35:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/08/13/402755.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/402755.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/08/13/402755.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/402755.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/402755.html</trackback:ping><description><![CDATA[<div>from:<a href="https://code.google.com/p/xsplit/">https://code.google.com/p/xsplit/</a><br />一点历史</div><div>这个project大约是09年初开始做的，很快就形成了现在版本的样子，后陆续做了一些小修改和修复了一些小bug，现整理了一下决定发布。把它open source的主要原因，就是希望这个小工具能对大家有用，并且能够参与进来一起把它做的更好</div><div></div><div>20101025</div><div></div><div>Change Log</div><div></div><div>20130509 0.0.9 released fixed an issue when compiler uses strict type checking</div><div></div><div>20101108 0.0.8 beta，加入xs_simhash和xs_hdist函数，分别计算simhash和汉明距离。</div><div></div><div>关于xsplit的交流，请到xsplit贴吧： http://tieba.baidu.com/f?kw=xsplit 参与讨论。</div><div></div><div>xsplit是一个PHP扩展，提供基于MMSEG算法的分词功能。目前只在linux下测试并部署过，希望有朋友可以帮忙编译提供windows下的dll。</div><div></div><div>xsplit只处理UTF8编码格式，如果是其他编码格式，请在使用前自行转换</div><div></div><div>xsplit主要有以下几个函数：</div><div></div><div>bool xs_build ( array $words, string $dict_file )</div><div></div><div>resource xs_open (string $dict_file [, bool $persistent])</div><div></div><div>array xs_split ( string $text [, int $split_method = 1 ［, resource $dictionary_identifier ］ ] )</div><div></div><div>mixed xs_search ( string $text ［, int $search_method [, resource $dictionary_identifer ] ］ )</div><div></div><div>string xs_simhash( string $text [, bool $isBinary] )&nbsp;</div><div></div><div>int xs_hdist( string $simhash1, string $simhash2 )</div><div>安装过程与一般的PHP扩展安装一样</div><div></div><div>$phpize</div><div>$./configure --with-php-config=/path/to/php-config</div><div>$make</div><div>$make install</div><div>php.ini中可以设置以下参数：</div><div></div><div>xsplit.allow_persisten = On</div><div>xsplit.max_dicts = 5</div><div>xsplit.max_persistent = 3</div><div>xsplit.default_dict_file = /home/xdict</div><div>xsplit.allow_persistent 是否允许加载持久词典</div><div></div><div>xsplit.max_dicts 允许同时打开的最大词典数目</div><div></div><div>xsplit.max_persistent 允许同时打开的最大持久词典数目</div><div></div><div>xsplit.default_dict_file 默认的词典，没有指定词典时会调用此词典</div><div></div><div>源码中有一个utils目录，包含</div><div></div><div>make_dict.php 提供命令行方式创建词典</div><div>xsplit.php 一个简单的示例文件</div><div>xdict_example.txt 一个文本词库的格式示例</div><div>make_dict.php的使用例子如下：</div><div></div><div>$php make_dict.php ./xdict_example.txt ./xdict.db</div><div>文本词库的格式请参考xdict_example.txt</div><div></div><div>bool xs_build (array $words, string $dict_file)</div><div></div><div>从$words数组建立名称为$dict_file的词典，若成功则返回true。$words数组的格式请参考示例，key为词语，value为词频。</div><div></div><div>例子如下：</div><div></div><div>&lt;?php</div><div>$dict_file='dict.db';</div><div></div><div>$dwords['美丽']=100;</div><div>$dwords['蝴蝶']=100;</div><div>$dwords['永远']=100;</div><div>$dwords['心中']=100;</div><div>$dwords['翩翩']=100;</div><div>$dwords['飞舞']=100;</div><div>$dwords['翩翩飞舞']=10;</div><div></div><div>if(!xs_build($dwords, $dict_file)) {</div><div>&nbsp; &nbsp; die('建立词典失败！');</div><div>}</div><div>resource xs_open (string $dict_file [, bool $persistent])</div><div></div><div>打开一个词典文件，并返回一个resource类型的identifier。$persistent可以指定是否是持久化词典，持久化词典在这里可以理解为词典资源生命周期的不同，一般情况下$persistent=true或者默认缺省即可。在进行分词的时候，可以指定不同的词典。</div><div></div><div>$dict_file_1 = 'xdcit.db';</div><div>$dict_file_2 = 'mydict.db';</div><div></div><div>$dict1 = xs_open($dict_file);</div><div></div><div>xs_open($dict_file);&nbsp;</div><div>array xs_split ( string $text [, int $split_method = 1 ［, resource $dictionary_identifier ］ ] )</div><div></div><div>对文本进行分词，可以指定分词方法和词典。分词方法目前有两种，一个是MMSEG算法（默认），一个是正向最大匹配，分别用常量XS_SPLIT_MMSEG和XS_SPLIT_MMFWD表示。返回值是一个数组，包含所有切分好的词语。如果不指定词典，最后一次打开的词典将被使用。</div><div></div><div>&lt;?php</div><div>$text="那只美丽的蝴蝶永远在我心中翩翩飞舞着。";</div><div>$dict_file = 'xdict.db';</div><div>$dict_res = xs_open($dict_file);</div><div>$words = xs_split($text); &nbsp;/* 此处没有指定词典资源，默认使用最后一次打开的词典 */</div><div></div><div>$words1 = xs_split($text, XS_SPLIT_MMSEG, $dict_res);</div><div>mixed xs_search ( string $text ［, int $search_method [, $dictionary_identifer ] ］ ) 基于双数组trie树提供的一些功能，$search_method有四个常量表示：</div><div></div><div>XS_SEARCH_CP : darts的commonPrefixSearch封装，如果没有找到，返回false。</div><div></div><div>XS_SEARCH_EM : darts的exactMatchSearch封装，如果没有找到，返回false。</div><div></div><div>XS_SEARCH_ALL_SIMPLE : 按照词典返回所有词语词频总和，一个INT型数值。</div><div></div><div>XS_SEARCH_ALL_DETAIL : 按照词典返回所有词典的词频，并以数组形式返回每一个词语的详细统计。</div><div></div><div>如果不指定词典，最后一次打开的词典将被使用。</div><div></div><div>&lt;?php</div><div>xs_open($dict_file);</div><div>$text="那只美丽的蝴蝶永远在我心中翩翩飞舞着。";</div><div>$word='翩翩飞舞';</div><div>$result=xs_search($word, XS_SEARCH_CP); /* common prefix search */</div><div>var_dump($result);</div><div>$result=xs_search($word, XS_SEARCH_EM); /* exact match search */</div><div>var_dump($result);</div><div>$result=xs_search($text, XS_SEARCH_ALL_SIMPLE);</div><div>var_dump($result);</div><div>$result=xs_search($text, XS_SEARCH_ALL_DETAIL);</div><div>var_dump($result);</div><div>string xs_simhash( array $tokens [, bool $rawoutput] )</div><div></div><div>计算simhash。这里所有token权重都是1，$tokens的例子如array('在', '这个', '世界')。$rawoput默认为0，即返回simhash的hex string形式，如md5， sha1函数一样；如过$rawoput为真，返回一个8字节的字符串，这个字符串实际上是一个64 bits的整型数，uint64_t，在一些特殊情况下可以用到。</div><div></div><div>int xs_hdist（ string $simhash1, $string $simhash2)</div><div></div><div>计算汉明距离。</div><div></div><div>&lt;?php</div><div>xs_open('xdict');</div><div>$text1="那只美丽的蝴蝶永远在我心中翩翩飞舞着。";</div><div>$text2="那只美丽的蝴蝶永远在我心中翩翩飞舞。";</div><div>$tokens1=xs_search($text1, XS_SEARCH_ALL_INDICT); /* 去掉标点等特殊符号，经过实验，计算simhash时，一些标点、换行、特殊符号等对效果影响较大 */</div><div>$tokens2=xs_search($text2, XS_SEARCH_ALL_INDICT);</div><div></div><div>$simhash1=xs_simhash($tokens1);</div><div>$simhash2=xs_simhash($tokens2);</div><div></div><div>echo "simhash1 is {$simhash1}\n";</div><div>echo "simhash2 is {$simhash2}\n";</div><div></div><div>$hamming_dist=xs_hdist($simhash1, $simhash2);</div><div></div><div>echo "bit-wise format:\n";</div><div>echo decbin(hexdec($simhash1)), "\n";</div><div>echo decbin(hexdec($simhash2)), "\n";</div><div></div><div>echo "hamming distance is {$hamming_dist}\n";</div><div>Terms - Privacy</div><img src ="http://www.blogjava.net/xiaomage234/aggbug/402755.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-08-13 17:35 <a href="http://www.blogjava.net/xiaomage234/archive/2013/08/13/402755.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Nginx优化配置(转)</title><link>http://www.blogjava.net/xiaomage234/archive/2013/08/01/402273.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 01 Aug 2013 14:18:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/08/01/402273.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/402273.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/08/01/402273.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/402273.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/402273.html</trackback:ping><description><![CDATA[<article id="post-6213" post="" type-post="" status-publish="" format-standard="" hentry="" category-servers="" tag-nginx=""  tag-nginx"="" style="border-bottom-style: none; margin: 0px 0px 1.625em; padding: 4.875em 0px 0px; position: relative; color: #373737; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; line-height: 24px; background-color: #ffffff;"><div style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px auto; outline: 0px; padding-top: 1.625em; vertical-align: baseline; width: 584.265625px;"><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">这里主要讲的是Nginx的优化方法，同时还需要优化php-fpm配置，方法请参考：<a href="http://blog.haohtml.com/archives/11162" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://blog.haohtml.com/archives/11162</a>.</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">优化前：</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/wp-content/uploads/2010/10/nginx-fpm-youhua1.jpg" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;"><img size-full=""  wp-image-11174"="" title="nginx-fpm-youhua1" src="http://blog.haohtml.com/wp-content/uploads/2010/10/nginx-fpm-youhua1.jpg" alt="" width="814" height="214" style="border: 1px solid #dddddd; margin: 0.4em auto 1.625em; clear: both; display: block; max-width: 97.5%; height: auto; width: auto; padding: 6px;" /></a></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">优化后:</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/wp-content/uploads/2010/10/nginx-fpm-youhua2.jpg" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;"><img size-full=""  wp-image-11177"="" title="nginx-fpm-youhua2" src="http://blog.haohtml.com/wp-content/uploads/2010/10/nginx-fpm-youhua2.jpg" alt="" width="762" height="211" style="border: 1px solid #dddddd; margin: 0.4em auto 1.625em; clear: both; display: block; max-width: 97.5%; height: auto; width: auto; padding: 6px;" /></a></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">看得出差距还是特别的大的．</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">/etc/sysctl.conf</strong></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">一般来说nginx配置文件中对优化比较有作用的为以下几项：</strong></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">worker_processes 8;<br /></span>nginx进程数，建议按照cpu数目来指定，一般为它的倍数,平时设置为2倍。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">cpu个数查看方法参考:<a href="http://blog.haohtml.com/archives/11123" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://blog.haohtml.com/archives/11123</a>&nbsp;和&nbsp;<a href="http://blog.haohtml.com/archives/9236" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://blog.haohtml.com/archives/9236</a></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;</span><br />为每个进程分配cpu，上例中将8个进程分配到8个cpu，当然可以写多个，或者将一个进程分配到多个cpu。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">worker_rlimit_nofile 102400;<br /></span>这个指令是指当一个nginx进程打开的最多文件描述符数目，理论值应该是最多打开文件数（<span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">ulimit -n</span>）与nginx进程数相除，但是nginx分配请求并不是那么均匀，所以最好与ulimit -n的值保持一致。ulimit的用法参考：<a href="http://blog.haohtml.com/archives/9883" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://blog.haohtml.com/archives/9883</a></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">use epoll;<br /></span>使用epoll的I/O模型，这个不用说了吧。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">worker_connections 102400;<br /></span>每个进程允许的最多连接数，理论上每台nginx服务器的最大连接数为<strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">worker_processes*worker_connections</strong>。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">keepalive_timeout 60;<br /></span>keepalive超时时间。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">client_header_buffer_size 4k;</span></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">客户端请求头部的缓冲区大小，这个可以根据你的系统分页大小来设置，一般一个请求头的大小不会超过1k，不过由于一般系统分页都要大于1k，所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">open_file_cache max=102400 inactive=20s;<br /></span>这个将为打开文件指定缓存，默认是没有启用的，max指定缓存数量，建议和打开文件数一致，inactive是指经过多长时间文件没被请求后删除缓存。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">open_file_cache_valid 30s;<br /></span>这个是指多长时间检查一次缓存的有效信息。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">open_file_cache_min_uses 1;<br /></span>open_file_cache指令中的inactive参数时间内文件的最少使用次数，如果超过这个数字，文件描述符一直是在缓存中打开的，如上例，如果有一个文件在inactive时间内一次没被使用，它将被移除。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">关于内核参数的优化：</strong></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_max_tw_buckets = 6000<br /></span>timewait的数量，默认是180000。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.ip_local_port_range = 1024&nbsp;&nbsp;&nbsp;&nbsp;65000<br /></span>允许系统打开的端口范围。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_tw_recycle = 1<br /></span>启用timewait快速回收。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_tw_reuse = 1<br /></span>开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_syncookies = 1<br /></span>开启SYN Cookies，当出现SYN等待队列溢出时，启用cookies来处理。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.core.somaxconn = 262144<br /></span>web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128，而nginx定义的NGX_LISTEN_BACKLOG默认为511，所以有必要调整这个值。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.core.netdev_max_backlog = 262144<br /></span>每个网络接口接收数据包的速率比内核处理这些包的速率快时，允许送到队列的数据包的最大数目。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_max_orphans = 262144<br /></span>系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字，孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击，不能过分依靠它或者人为地减小这个值，更应该增加这个值(如果增加了内存之后)。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_max_syn_backlog = 262144<br /></span>记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言，缺省值是1024，小内存的系统则是128。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_timestamps = 0<br /></span>时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种&#8220;异常&#8221;的数据包。这里需要将其关掉。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_synack_retries = 1<br /></span>为了打开对端的连接，内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_syn_retries = 1<br /></span>在内核放弃建立连接之前发送SYN包的数量。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_fin_timeout = 1<br /></span>如果套接字由本端要求关闭，这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接，甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180秒，你可以按这个设置，但要记住的是，即使你的机器是一个轻载的WEB服务器，也有因为大量的死套接字而内存溢出的风险，FIN- WAIT-2的危险性比FIN-WAIT-1要小，因为它最多只能吃掉1.5K内存，但是它们的生存期长些。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">net.ipv4.tcp_keepalive_time = 30<br /></span>当keepalive起用的时候，TCP发送keepalive消息的频度。缺省是2小时。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">下面贴一个完整的内核优化设置：</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">引用</p><blockquote style="border: 0px; font-family: Georgia, 'Bitstream Charter', serif; font-style: italic; margin: 0px 3em; outline: 0px; padding: 0px; vertical-align: baseline; quotes: '';"><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">net.ipv4.ip_forward = 0<br />net.ipv4.conf.default.rp_filter = 1<br />net.ipv4.conf.default.accept_source_route = 0<br />kernel.sysrq = 0<br />kernel.core_uses_pid = 1<br />net.ipv4.tcp_syncookies = 1<br />kernel.msgmnb = 65536<br />kernel.msgmax = 65536<br />kernel.shmmax = 68719476736<br />kernel.shmall = 4294967296<br />net.ipv4.tcp_max_tw_buckets = 6000<br />net.ipv4.tcp_sack = 1<br />net.ipv4.tcp_window_scaling = 1<br />net.ipv4.tcp_rmem = 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;87380&nbsp;&nbsp;&nbsp;4194304<br />net.ipv4.tcp_wmem = 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;16384&nbsp;&nbsp;&nbsp;4194304<br />net.core.wmem_default = 8388608<br />net.core.rmem_default = 8388608<br />net.core.rmem_max = 16777216<br />net.core.wmem_max = 16777216<br />net.core.netdev_max_backlog = 262144<br />net.core.somaxconn = 262144<br />net.ipv4.tcp_max_orphans = 3276800<br />net.ipv4.tcp_max_syn_backlog = 262144<br />net.ipv4.tcp_timestamps = 0<br />net.ipv4.tcp_synack_retries = 1<br />net.ipv4.tcp_syn_retries = 1<br />net.ipv4.tcp_tw_recycle = 1<br />net.ipv4.tcp_tw_reuse = 1<br />net.ipv4.tcp_mem = 94500000 915000000 927000000<br />net.ipv4.tcp_fin_timeout = 1<br />net.ipv4.tcp_keepalive_time = 30<br />net.ipv4.ip_local_port_range = 1024&nbsp;&nbsp;&nbsp;&nbsp;65000</p></blockquote><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">下面是一个简单的nginx配置文件：</strong></p><blockquote style="border: 0px; font-family: Georgia, 'Bitstream Charter', serif; font-style: italic; margin: 0px 3em; outline: 0px; padding: 0px; vertical-align: baseline; quotes: '';"><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">user&nbsp;&nbsp;www www;<br />worker_processes 8;<br />worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000;<br />error_log&nbsp;&nbsp;/www/log/nginx_error.log&nbsp;&nbsp;crit;<br />pid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/usr/local/nginx/nginx.pid;<br />worker_rlimit_nofile 204800;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">events<br />{<br />use epoll;<br />worker_connections 204800;<br />}</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">http<br />{<br />include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mime.types;<br />default_type&nbsp;&nbsp;application/octet-stream;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">charset&nbsp;&nbsp;utf-8;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">server_names_hash_bucket_size 128;<br />client_header_buffer_size 2k;<br />large_client_header_buffers 4 4k;<br />client_max_body_size 8m;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">sendfile on;<br />tcp_nopush&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;on;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">keepalive_timeout 60;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2<br />keys_zone=TEST:10m<br />inactive=5m;<br />fastcgi_connect_timeout 300;<br />fastcgi_send_timeout 300;<br />fastcgi_read_timeout 300;<br />fastcgi_buffer_size 64k;<br />fastcgi_buffers 8 64k;<br />fastcgi_busy_buffers_size 128k;<br />fastcgi_temp_file_write_size 128k;<br />fastcgi_cache TEST;<br />fastcgi_cache_valid 200 302 1h;<br />fastcgi_cache_valid 301 1d;<br />fastcgi_cache_valid any 1m;<br />fastcgi_cache_min_uses 1;<br />fastcgi_cache_use_stale error timeout invalid_header http_500;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">open_file_cache max=204800 inactive=20s;<br />open_file_cache_min_uses 1;<br />open_file_cache_valid 30s;<br />tcp_nodelay on;</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">gzip on;<br />gzip_min_length&nbsp;&nbsp;1k;<br />gzip_buffers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4 16k;<br />gzip_http_version 1.0;<br />gzip_comp_level 2;<br />gzip_types&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;text/plain application/x-javascript text/css application/xml;<br />gzip_vary on;<br />server<br />{<br />listen&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;8080;<br />server_name&nbsp;&nbsp;backup.aiju.com;<br />index index.php index.htm;<br />root&nbsp;&nbsp;/www/html/;&nbsp; #<span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">这里的位置很重要，不要写在其它指令里面，我曾经就调试了好久才发现这个问题的</span></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">location /status<br />{<br />stub_status on;<br />}</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">location ~ .*\.(php|php5)?$<br />{<br />fastcgi_pass 127.0.0.1:9000;<br />fastcgi_index index.php;<br />include fcgi.conf;<br />}</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$<br />{<br />expires&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;30d;<br />}</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">log_format&nbsp;&nbsp;access&nbsp;&nbsp;'$remote_addr - $remote_user [$time_local] "$request" '<br />'$status $body_bytes_sent "$http_referer" '<br />'"$http_user_agent" $http_x_forwarded_for';<br />access_log&nbsp;&nbsp;/www/log/access.log&nbsp;&nbsp;access;<br />}<br />}</p></blockquote><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">关于FastCGI的几个指令(<a href="http://wiki.nginx.org/NginxChsHttpFcgiModule" style="border: 0px; font-family: inherit; font-style: inherit; font-weight: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://wiki.nginx.org/NginxChsHttpFcgiModule</a>)：</strong></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;<br /></span>这个指令为FastCGI缓存指定一个路径，目录结构等级，关键字区域存储时间和非活动删除时间。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_connect_timeout 300;<br /></span>指定连接到后端FastCGI的超时时间。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_send_timeout 300;<br /></span>向FastCGI传送请求的超时时间，这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_read_timeout 300;<br /></span>接收FastCGI应答的超时时间，这个值是指已经完成两次握手后接收FastCGI应答的超时时间。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_buffer_size 64k;<br /></span>指定读取FastCGI应答第一部分需要用多大的缓冲区，一般第一部分应答不会超过1k，由于页面大小为4k，所以这里设置为4k。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_buffers 8 64k;<br /></span>指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_busy_buffers_size 128k;<br /></span>这个指令我也不知道是做什么用，只知道默认值是fastcgi_buffers的两倍。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_temp_file_write_size 128k;<br /></span>在写入fastcgi_temp_path时将用多大的数据块，默认值是fastcgi_buffers的两倍。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_cache TEST<br /></span>开启FastCGI缓存并且为其制定一个名称。个人感觉开启缓存非常有用，可以有效降低CPU负载，并且防止502错误。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_cache_valid 200 302 1h;<br />fastcgi_cache_valid 301 1d;<br />fastcgi_cache_valid any 1m;<br /></span>为指定的应答代码指定缓存时间，如上例中将200，302应答缓存一小时，301应答缓存1天，其他为1分钟。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_cache_min_uses 1;<br /></span>缓存在fastcgi_cache_path指令inactive参数值时间内的最少使用次数，如上例，如果在5分钟内某文件1次也没有被使用，那么这个文件将被移除。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">fastcgi_cache_use_stale error timeout invalid_header http_500;<br /></span>不知道这个参数的作用，猜想应该是让nginx知道哪些类型的缓存是没用的。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">以上为nginx中FastCGI相关参数，另外，FastCGI自身也有一些配置需要进行优化，如果你使用php-fpm来管理FastCGI，可以修改配置文件中的以下值：<br /><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">&lt;value name="max_children"&gt;60&lt;/value&gt;<br /></span>同时处理的并发请求数，即它将开启最多60个子线程来处理并发连接。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">&lt;value name="rlimit_files"&gt;102400&lt;/value&gt;<br /></span>最多打开文件数。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #0000ff;">&lt;value name="max_requests"&gt;204800&lt;/value&gt;<br /></span>每个进程在重置之前能够执行的最多请求数。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">下面贴几张测试结果图。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">静态页面为我在squid配置4W并发那篇文章中提到的测试文件，下图为同时在6台机器运行webbench -c 30000 -t 600&nbsp;<a href="http://backup.aiju.com:8080/index.html" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://backup.aiju.com:8080/index.html</a>命令后的测试结果：<br />使用netstat过滤后的连接数：<br />php页面在status中的结果（php页面为调用phpinfo）：<br />php页面在netstat过滤后的连接数：<br />未使用FastCGI缓存之前的服务器负载：<br />此时打开php页面已经有些困难，需要进行多次刷新才能打开。上图中cpu0负载偏低是因为测试时将网卡中断请求全部分配到cpu0上，并且在nginx中开启7个进程分别制定到cpu1-7。<br />使用FastCGI缓存之后：<br />此时可以很轻松的打开php页面。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;">这个测试并没有连接到任何数据库，所以并没有什么参考价值，不过不知道上述测试是否已经到达极限，根据内存和cpu的使用情况来看似乎没有，但是已经没有多余的机子来让我运行webbench了。</p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><strong style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">参考资料：</strong></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://hi.baidu.com/myus/blog/item/f37d05d1b1d1ad399a5027ff.html" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://hi.baidu.com/myus/blog/item/f37d05d1b1d1ad399a5027ff.html</a></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://kenwublog.com/docs/linux-kernel-2-6-36-optimization.htm" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://kenwublog.com/docs/linux-kernel-2-6-36-optimization.htm</a></p><p style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.sina.com.cn/s/blog_50a736440100j023.html" target="_blank" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">http://blog.sina.com.cn/s/blog_50a736440100j023.html</a></p><div wp_rp_plain"="" id="wp_rp_first" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; vertical-align: baseline;"><div style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; vertical-align: baseline;"><h3>相关文章</h3><ul wp_rp"="" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 1.625em 2.5em; outline: 0px; padding: 0px; vertical-align: baseline; list-style: square; visibility: visible;"><li data-position="0" data-poid="in-1220" data-post-type="none" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/archives/1220" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">Nginx虚拟主机多server_name的顺序问题</a></li><li data-position="1" data-poid="in-5953" data-post-type="none" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/archives/5953" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">Nginx 0.8.x + PHP 5.2.13（FastCGI）搭建胜过Apache十倍的Web服务器（第6版）[原创]</a></li><li data-position="2" data-poid="in-1125" data-post-type="none" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/archives/1125" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">Nginx+PHP(FastCGI)搭建胜过Apache 10倍的Web服务器</a></li><li data-position="3" data-poid="in-3213" data-post-type="none" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/archives/3213" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">使用Nginx轻松实现开源负载均衡&#9472;&#9472;9 月20日在ChinaUnix技术沙龙上的演讲PPT[原创]</a></li><li data-position="4" data-poid="in-6283" data-post-type="none" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;"><a href="http://blog.haohtml.com/archives/6283" style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">nginx源代码分析</a></li></ul></div></div></div><div style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px 0px 0px 130px; outline: 0px; vertical-align: baseline;"></div><footer style="color: #666666; clear: both; font-size: 12px; line-height: 18px; margin: 0px auto; width: 584.265625px;">This entry was posted in&nbsp;<a href="http://blog.haohtml.com/archives/category/servers" title="View all posts in 服务器类" rel="category tag" style="border: 0px; font-family: inherit; font-style: inherit; font-weight: bold; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">服务器类</a>&nbsp;and tagged&nbsp;<a href="http://blog.haohtml.com/tag/nginx" rel="tag" style="border: 0px; font-family: inherit; font-style: inherit; font-weight: bold; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">nginx</a>,&nbsp;<a href="http://blog.haohtml.com/tag/nginx%e4%bc%98%e5%8c%96" rel="tag" style="border: 0px; font-family: inherit; font-style: inherit; font-weight: bold; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">nginx优化</a>&nbsp;by&nbsp;<a href="http://blog.haohtml.com/archives/author/admin" style="border: 0px; font-family: inherit; font-style: inherit; font-weight: bold; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">admin</a>. Bookmark the&nbsp;<a href="http://blog.haohtml.com/archives/6213" title="Permalink to Nginx优化配置(转)" rel="bookmark" style="border: 0px; font-family: inherit; font-style: inherit; font-weight: bold; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline; color: #1982d1; text-decoration: none;">permalink</a>.</footer></article><div id="comments" style="border: 0px; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 15px; margin: 0px; outline: 0px; vertical-align: baseline; color: #373737; line-height: 24px; background-color: #ffffff;"><h2>2 THOUGHTS ON &#8220;<span style="border: 0px; font-family: inherit; font-style: inherit; margin: 0px; outline: 0px; padding: 0px; vertical-align: baseline;">NGINX优化配置(转)</span>&#8221;</h2></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/402273.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-08-01 22:18 <a href="http://www.blogjava.net/xiaomage234/archive/2013/08/01/402273.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web前端 HTTPS 缓存加速squid 3.3.8 实战【原创】</title><link>http://www.blogjava.net/xiaomage234/archive/2013/07/31/402195.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Wed, 31 Jul 2013 05:58:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/07/31/402195.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/402195.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/07/31/402195.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/402195.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/402195.html</trackback:ping><description><![CDATA[都知道 http加速器 现在 varnish 比 squid 名声大，所以 先整了一把varnish，但是研究之后，发现不支持SSL，只得作罢，开始换上squid.<br /><br />到网上下了一个最新版 3.3.8，开始搜索配置资料，发现都是以前的旧的，不适用，后来发现了一个 针对3.0的配置:&nbsp;<a href="http://linux008.blog.51cto.com/2837805/618731">http://linux008.blog.51cto.com/2837805/618731<br />&nbsp;</a>&nbsp; 按照提示安装完成了，启用了 --enable-ssl选项。<br /><br />后来又参考官方文档 加上了https支持，参考：<a href="http://wiki.squid-cache.org/ConfigExamples/Reverse/SslWithWildcardCertifiate">http://wiki.squid-cache.org/ConfigExamples/Reverse/SslWithWildcardCertifiate<br /><br />&nbsp;</a>&nbsp;但是很不辛，居然报错：&#8220;FATAL: http(s)_port: defaultsite option requires Acceleration mode flag.&#8221;<br /><br />然后根据提示 去 查找https_port用法，参考资料：<a href="http://www.squid-cache.org/Doc/config/https_port/">http://www.squid-cache.org/Doc/config/https_port/<br /><br /></a>原来 是 缺少[mode]选项，根据我的需要，加了&#8220;accel&#8221;，问题解决.<br /><br />具体业务的完整配置参考附件。<br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->https_port&nbsp;443&nbsp;cert=/usr/local/squid/cert.pem&nbsp;key=/usr/local/squid/cert.key&nbsp;accel&nbsp;defaultsite=img0-yoursite.yourdomain.com&nbsp;vhost<br />cache_peer&nbsp;1.2.3.4&nbsp;parent&nbsp;80&nbsp;0&nbsp;no-query&nbsp;originserver&nbsp;ssl&nbsp;sslflags=DONT_VERIFY_PEER&nbsp;name=img0<br />acl&nbsp;sites_server_img0&nbsp;dstdomain&nbsp;img0-yoursite.yourdomain.com<br />cache_peer_access&nbsp;img0&nbsp;allow&nbsp;sites_server_img0<br />http_access&nbsp;allow&nbsp;sites_server_img0<br /><br />https_port&nbsp;443&nbsp;cert=/usr/local/squid/cert.pem&nbsp;key=/usr/local/squid/cert.key&nbsp;accel&nbsp;defaultsite=img1-yoursite.yourdomain.com&nbsp;vhost<br />cache_peer&nbsp;1.2.3.4&nbsp;parent&nbsp;80&nbsp;0&nbsp;no-query&nbsp;originserver&nbsp;ssl&nbsp;sslflags=DONT_VERIFY_PEER&nbsp;name=img1<br />acl&nbsp;sites_server_img1&nbsp;dstdomain&nbsp;img1-yoursite.yourdomain.com<br />cache_peer_access&nbsp;img1&nbsp;allow&nbsp;sites_server_img1<br />http_access&nbsp;allow&nbsp;sites_server_img1<br /><br />####base######<br />visible_hostname&nbsp;localhost<br />cache_mgr&nbsp;xiaomage234@163.com<br />cache_effective_user&nbsp;nobody<br />cache_effective_group&nbsp;nobody<br />####cache#####<br />cache_mem&nbsp;600&nbsp;MB<br />cache_swap_low&nbsp;90<br />cache_swap_high&nbsp;95<br />maximum_object_size&nbsp;12000&nbsp;KB<br />maximum_object_size_in_memory&nbsp;1024&nbsp;KB<br />cache_dir&nbsp;ufs&nbsp;/usr/local/squid/var/cache&nbsp;10000&nbsp;16&nbsp;256<br />cache_access_log&nbsp;/usr/local/squid/var/logs/access.log<br />cache_log&nbsp;/usr/local/squid/var/logs/cache.log<br />cache_store_log&nbsp;/usr/local/squid/var/logs/store.log<br />#####no-cache##########<br />hierarchy_stoplist&nbsp;cgi-bin&nbsp;?/.php<br />acl&nbsp;QUERY&nbsp;urlpath_regex&nbsp;cgi-bin&nbsp;/?/.php<br />#acl&nbsp;DIRECT&nbsp;url_regex&nbsp;-i&nbsp;^http:<span style="color: #008000; ">//</span><span style="color: #008000; ">192.168.0.201</span><span style="color: #008000; "><br /></span>cache&nbsp;deny&nbsp;QUERY<br />#cache&nbsp;deny&nbsp;DIRECT<br />#####refresh_pattern####<br />refresh_pattern&nbsp;^ftp:&nbsp;60&nbsp;20%&nbsp;10080<br />refresh_pattern&nbsp;^gopher:&nbsp;60&nbsp;0%&nbsp;1440<br /><br />refresh_pattern&nbsp;^gopher:&nbsp;60&nbsp;0%&nbsp;1440<br />refresh_pattern&nbsp;.&nbsp;0&nbsp;20%&nbsp;1440<br />refresh_pattern&nbsp;-i&nbsp;/.css$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;360&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reload-into-ims<br />refresh_pattern&nbsp;-i&nbsp;/.js$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reload-into-ims<br />refresh_pattern&nbsp;-i&nbsp;/.html$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;720&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reload-into-ims<br />refresh_pattern&nbsp;-i&nbsp;/.jpg$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;90%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.gif$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;90%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.swf$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;90%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.jpg$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.png$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.bmp$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.doc$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.ppt$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.xls$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.pdf$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.rar$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.zip$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />refresh_pattern&nbsp;-i&nbsp;/.txt$&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1440&nbsp;&nbsp;&nbsp;&nbsp;50%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2880&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ignore-reload<br />######proxy&nbsp;agent###&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />http_port&nbsp;80&nbsp;accel&nbsp;vhost&nbsp;vport<br />cache_peer&nbsp;1.2.3.4&nbsp;parent&nbsp;80&nbsp;0&nbsp;no-query&nbsp;originserver&nbsp;name=img00<br />cache_peer_domain&nbsp;img00&nbsp;img0-yoursite.yourdomain.com<br /><br />cache_peer&nbsp;1.2.3.4&nbsp;parent&nbsp;80&nbsp;0&nbsp;no-query&nbsp;originserver&nbsp;name=img01<br />cache_peer_domain&nbsp;img01&nbsp;img1-yoursite.yourdomain.com<br />######alc#####<br />acl&nbsp;manager2&nbsp;proto&nbsp;cache_object<br />acl&nbsp;localhost&nbsp;src&nbsp;127.0.0.1/32<br />acl&nbsp;to_localhost&nbsp;dst&nbsp;127.0.0.0/8<br />acl&nbsp;localnet&nbsp;src&nbsp;10.0.0.0/8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;RFC1918&nbsp;possible&nbsp;internal&nbsp;network<br />acl&nbsp;localnet&nbsp;src&nbsp;172.16.0.0/12&nbsp;&nbsp;#&nbsp;RFC1918&nbsp;possible&nbsp;internal&nbsp;network<br />acl&nbsp;localnet&nbsp;src&nbsp;192.168.0.0/16&nbsp;#&nbsp;RFC1918&nbsp;possible&nbsp;internal&nbsp;network<br />acl&nbsp;LanSrc&nbsp;src&nbsp;all<br />acl&nbsp;LanDst&nbsp;dst&nbsp;all<br />acl&nbsp;SSL_ports&nbsp;port&nbsp;443<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;http<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;ftp<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;443&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;https<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;gopher<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;210&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;wais<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;1025-65535&nbsp;&nbsp;#&nbsp;unregistered&nbsp;ports<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;280&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;http-mgmt<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;488&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;gss-http<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;591&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;filemaker<br />acl&nbsp;Safe_ports&nbsp;port&nbsp;777&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;multiling&nbsp;http<br />acl&nbsp;CONNECT&nbsp;method&nbsp;CONNECT<br />acl&nbsp;LanDstDM&nbsp;dstdomain&nbsp;.kanbox.com<br /><br />http_access&nbsp;allow&nbsp;manager2&nbsp;localhost<br />http_access&nbsp;deny&nbsp;manager2<br />http_access&nbsp;deny&nbsp;!Safe_ports<br />http_access&nbsp;deny&nbsp;CONNECT&nbsp;!SSL_ports<br />http_access&nbsp;allow&nbsp;LanDstDM<br />http_access&nbsp;allow&nbsp;LanSrc<br />http_access&nbsp;allow&nbsp;LanDst<br />http_access&nbsp;allow&nbsp;localnet<br />http_access&nbsp;deny&nbsp;all<br /><br />下载附件:<br /><a href="/Files/xiaomage234/squid.conf.txt">/Files/xiaomage234/squid.conf.txt<br /><br />v</a>arnish的配置，不支持https:<br /><a href="/Files/xiaomage234/default.vcl.txt">/Files/xiaomage234/default.vcl.txt</a></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/402195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-07-31 13:58 <a href="http://www.blogjava.net/xiaomage234/archive/2013/07/31/402195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>google的开源项目总结</title><link>http://www.blogjava.net/xiaomage234/archive/2013/03/14/396448.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 14 Mar 2013 09:35:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/03/14/396448.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/396448.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/03/14/396448.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/396448.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/396448.html</trackback:ping><description><![CDATA[<p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="line-height: 1.5;">google的开源项目总结<a href="http://www.feng5166.com/blog/?tag=google" target="_blank" style="color: navy; text-decoration: none;"><br /></a></span></p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><span style="line-height: 1.5;"><a href="http://www.feng5166.com/blog/?tag=google" target="_blank" style="color: navy; text-decoration: none;">google</a></span>的<span style="line-height: 1.5;"><a href="http://www.feng5166.com/blog/?tag=%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE" target="_blank" style="color: navy; text-decoration: none;">开源项目</a></span>值得我们一用的，这些项目很有意义，甚至可以直接用在我们自己的工作上！学习编程的的一个比较好的方式就是阅读优秀项目的源代码，从而能够了解作者的方法、思路、技巧，另外阅读源代码对于一些朋友是枯燥乏味的，这是就可以看看项目的readme，找到项目的闪光点，我们不做开拓者那我们就做实践者和使用者，呵呵，下面是这些项目的列表，在这里存档，已备今后查阅之用&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><h4>文本文件处理：</h4><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/crush-tools/" target="_blank" style="color: navy; text-decoration: none;">Google CRUSH (Custom Reporting Utilities for SHell)</a>&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">CRUSH是为命令行或shell scripts处理特定文字数据而制作的一系列工具，<a href="http://code.google.com/p/crush-tools/wiki/CrushTutorial" target="_blank" style="color: navy; text-decoration: none;">这里有指南</a>。</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">C++库和源代码：</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-breakpad/" style="color: navy; text-decoration: none;">Google Breakpad</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">一个开源的多平台崩溃报告系统。&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-gflags/" style="color: navy; text-decoration: none;">Google GFlags</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Gflags是一个命令行标记的处理库，它可以替代&#8220;getopt()&#8221;，其内置对C++的支持比如string。<a href="http://google-gflags.googlecode.com/svn/trunk/doc/gflags.html" target="_blank" style="color: navy; text-decoration: none;">指南在此</a>。&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-glog/" target="_blank" style="color: navy; text-decoration: none;">Google Glog</a>&nbsp;Glog库可执行应用级的登陆，提供基于C++式的登陆API，可用于Linux、BSD和Windows。<a href="http://google-glog.googlecode.com/svn/trunk/doc/glog.html" target="_blank" style="color: navy; text-decoration: none;">指南见此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-perftools/" target="_blank" style="color: navy; text-decoration: none;">Google PerfTools</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">这个工具可让开发创建更强大的应用程序，特别是那些用C++模版开发的多线程应用程序，包括TCMalloc, heap-checker, heap-profiler 和cpu-profiler。指南<a href="http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools" target="_blank" style="color: navy; text-decoration: none;">见此</a>还有<a href="http://google-perftools.googlecode.com/svn/trunk/doc/index.html" target="_blank" style="color: navy; text-decoration: none;">这里</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-sparsehash/" target="_blank" style="color: navy; text-decoration: none;">Google Sparse Hash</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">非常节省内存的hash-map。<a href="http://google-sparsehash.googlecode.com/svn/trunk/doc/index.html" target="_blank" style="color: navy; text-decoration: none;">指南见此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/omaha/" target="_blank" style="color: navy; text-decoration: none;">Omaha &#8211; Google Update</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Omaha，也就是Google Update，它可以保证你的软件随时升级到最新版本，目前很多Windows下的Google软件都是用Omaha升级的，包括Google Chrome和Google Earth，当然你也可以用于自己的应用程序。指南<a href="http://omaha.googlecode.com/svn/wiki/OmahaOverview.html" target="_blank" style="color: navy; text-decoration: none;">看这里</a>还有<a href="http://code.google.com/p/omaha/wiki/DeveloperSetupGuide" target="_blank" style="color: navy; text-decoration: none;">这里</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/protobuf/" target="_blank" style="color: navy; text-decoration: none;">Protocol Buffers</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Protocol Buffers是一种可扩展编码序列数据的方式，Google在几乎所有内部RPC协议和文件格式都使用了Protocol Buffers。<a href="http://code.google.com/intl/pl/apis/protocolbuffers/docs/overview.html" target="_blank" style="color: navy; text-decoration: none;">指南见此</a>。<a href="http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns" target="_blank" style="color: navy; text-decoration: none;">它可以用于很多语言而且被一些IDE所支持，比如NetBeans</a>。&nbsp;</p><h4>互联网：</h4><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-code-prettify/" target="_blank" style="color: navy; text-decoration: none;">Google Code Pretiffy</a>&nbsp;这是一个Javascript模块和CSS文件，它可以让HTML页面里的部分源码高亮显示，支持C/C++, Java, Python, Ruby, PHP, VisualBasic, AWK, Bash, SQL, HTML, XML, CSS, JavaScript, Makefiles和部分Perl，不支持Smalltalk和所有的CAML。<a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html" target="_blank" style="color: navy; text-decoration: none;">例子见此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/spriteme/" target="_blank" style="color: navy; text-decoration: none;">SpriteMe &#8211; easy &#8220;CSS spirtes&#8221;</a>&nbsp;SpriteMe使你可以更轻松的创造CSS Sprites（俗称雪碧&#8230;&#8230;）就是把网站要用到的图片都堆在一张图片里，用CSS控制调用哪个区域。<a href="http://spriteme.org/" target="_blank" style="color: navy; text-decoration: none;">它有一个自己的官网在这里</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/reducisaurus/" target="_blank" style="color: navy; text-decoration: none;">Redacisaurus</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Reducisaurus是一个压缩CSS和JS文件的网络服务，基于YUI压缩算法，运行于App Engine。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/jaikuengine/" target="_blank" style="color: navy; text-decoration: none;">JaikuEngine</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">JaikuEngine是一个运行于App Engine的微博系统，由<a href="http://www.jaiku.com/" target="_blank" style="color: navy; text-decoration: none;">jaiku.com</a>运营。要查看移动客户端的源码可以<a href="http://code.google.com/p/jaikuengine-mobile-client/" target="_blank" style="color: navy; text-decoration: none;">看这里</a>，<a href="http://code.google.com/p/jaikuengine/source/browse/trunk/doc/README.txt" target="_blank" style="color: navy; text-decoration: none;">这里还有介绍</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/selector-shell/" target="_blank" style="color: navy; text-decoration: none;">Selector Shell</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Selector Shell是一个基于浏览器的测试工具，它可以让你看到CSS在不同浏览器里的样式，用Javascript写的，<a href="http://selector-shell.appspot.com/" target="_blank" style="color: navy; text-decoration: none;">你可以在这里测试</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-feedserver/" target="_blank" style="color: navy; text-decoration: none;">Google Feed Server</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Google Feed Server是一个开源Atom发布协议服务，基于Apache Abdera框架，允许开发者快速为当前数据源（比如数据库）配置feed。指南<a href="http://code.google.com/p/google-feedserver/wiki/SettingUpADevelopmentEnvironment" target="_blank" style="color: navy; text-decoration: none;">见这里</a>和<a href="http://code.google.com/p/google-feedserver/wiki/DatabaseConfigurationForAFeed" target="_blank" style="color: navy; text-decoration: none;">这里</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/soc/" target="_blank" style="color: navy; text-decoration: none;">Melange, the Spice of Creation</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">这个项目的目标是创建出一个适合开源贡献流程的框架，比如Google Summer of Code TM (GSoC)项目。使用这个框架你就可以用Google App Engine来运行Google Summer of Code项目，和其它类似项目比如Google Highly Open Participation TM Contest和GHOP。<a href="http://code.google.com/p/soc/wiki/GettingStarted" target="_blank" style="color: navy; text-decoration: none;">指南见此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/namebench/" target="_blank" style="color: navy; text-decoration: none;">NameBench</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">它可以查找最快的DNS服务器给你的电脑用，在Mac OS X、Windows和UNIX系统下都有命令行也有用户界面可以帮你测试，这是Google工程师用20%自由时间写出来的。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/ratproxy/" target="_blank" style="color: navy; text-decoration: none;">Rat Proxy</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">一个半自动化的大型被动网络应用安全审查工具，专为精确的探测而优化，<a href="http://code.google.com/p/ratproxy/wiki/RatproxyDoc" target="_blank" style="color: navy; text-decoration: none;">文档在此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/topdraw/" target="_blank" style="color: navy; text-decoration: none;">TopDraw</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Top Draw是一个图形生成程序，使用简单的文字脚本，基于JavaScript编程语言，Top Draw可以创造出非常复杂和有趣的图形。支持Mac OS 10.5以上系统，使用XCode开发。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/etherpad/" style="color: navy; text-decoration: none;">etherpad</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">开源的EtherPad，这是一个基于网络的实时合作文档编辑器，这个项目主要是为了演示代码而开发，帮助那些想在自己服务器部署Etherpad的人使用，<a href="http://code.google.com/p/etherpad/wiki/Instructions" target="_blank" style="color: navy; text-decoration: none;">这里有如何安装的指南</a>。EtherPad使用JavaScript、Java和Comet服务器来建造实时协作服务。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/chromium/" target="_blank" style="color: navy; text-decoration: none;">Chromium</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Chromium是开源版的Chrome浏览器，Chromium的目标是建立一个新一代的强大网络应用程序，它与Chrome有很多不同之处。<a href="http://code.google.com/p/chromium/wiki/LinuxBuildInstructions" target="_blank" style="color: navy; text-decoration: none;">这里有指导如何在Linux上编译Chromium</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/v8/" target="_blank" style="color: navy; text-decoration: none;">V8 Google&#8217;s open source JavaScript engine</a>&nbsp;V8是Google的开源JavaScript引擎，用C++写成，用于Chrome浏览器之上。V8使用ECMAScript的ECMA-262第三版可运行于Windows XP、Vista、Mac OS 10.5和使用IA-32或ARM处理器的Linux。V8可独立运行也可嵌入到任何C++程序里使用，<a href="http://code.google.com/intl/pl/apis/v8/build.html" target="_blank" style="color: navy; text-decoration: none;">这里有指南</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://www.chromium.org/chromium-os" target="_blank" style="color: navy; text-decoration: none;">Chromium OS</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Chromium OS是开源版的Chrome OS操作系统，提供快速、简单而安全的网络体验，<a href="http://git.chromium.org/" target="_blank" style="color: navy; text-decoration: none;">源码在此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://source.android.com/download" target="_blank" style="color: navy; text-decoration: none;">Android</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Android是第一个免费、开源而且可完全自定义的移动平台，提供完整的堆栈：一个操作系统、中间件和重要的一用应用，它包含丰富的API可以让第三方开发者开发出强大的应用程序。&nbsp;</p><h4>MySQL工具：</h4><h4><a href="http://code.google.com/p/google-mysql-tools/" target="_blank" style="color: navy; text-decoration: none;">Google MySQL Tools</a>&nbsp;&nbsp;</h4><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">各种管理、维护和改进MySQL数据库性能的工具，由Google编写，包括：&nbsp;</p><ul style="margin-left: 45px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li style="list-style: inherit;">mypgrep.py：一个类似pgrep的工具来管理MySQL连接</li><li style="list-style: inherit;">compact_innodb.py：可导出和重载所有表格的密集型innodb数据文件</li></ul><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-mmaim/" target="_blank" style="color: navy; text-decoration: none;">Google mMAIM</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">mMAIM的目标是对MySQL的监控和分析更简单，且可以和任何环境整合使用。它可显示主/从同步状态，一些性能状态，可以返回大量&#8220;show&#8221;命令的状态等等。&nbsp;&nbsp;&nbsp;</p><h4>其它：</h4><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/stressapptest/" target="_blank" style="color: navy; text-decoration: none;">Stressful Application Test (stressapptest)</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Stressful Application Test试图让来自处理器和I/O到内存的数据尽量随机化，以创造出模拟现实的环境来测试现在的硬件设备是否稳定，Google就在使用它，现在是Apache 2.0许可，这里有<a href="http://code.google.com/p/stressapptest/wiki/Introduction" target="_blank" style="color: navy; text-decoration: none;">介绍</a>、<a href="http://code.google.com/p/stressapptest/wiki/InstallationGuide" target="_blank" style="color: navy; text-decoration: none;">安装向导</a>和<a href="http://code.google.com/p/stressapptest/wiki/UserGuide" target="_blank" style="color: navy; text-decoration: none;">指南</a>。&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/pop-imap-troubleshooter/" target="_blank" style="color: navy; text-decoration: none;">Pop and IMAP Troubleshooter</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">它用于诊断并解决客户端到邮件服务器的连接问题。&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/openduckbill/" target="_blank" style="color: navy; text-decoration: none;">OpenDuckBill</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Openduckbill是一个Linux下简单的命令行备份工具，可用于监视文件/目录在有变化后是否标记为备份，并传输这些变化到本地备份目录、远程NFS导出分卷或是用rsync命令导出到远程SSH服务器。<a href="http://code.google.com/p/openduckbill/wiki/OpenduckbillReadme" target="_blank" style="color: navy;">见安装向导</a>。&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/zxing/" target="_blank" style="color: navy; text-decoration: none;">ZXing</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">ZXing（发音类似Zebra crossing）是Java的开源多格式1D/2D条码图像处理库，目的是使用内置在手机上的摄像头拍照并对条码进行解码，而不必与服务器通讯，它被用于Android系统。这里有<a href="http://code.google.com/p/zxing/wiki/GettingStarted" target="_blank" style="color: navy; text-decoration: none;">向导</a>和<a href="http://code.google.com/p/zxing/wiki/GetTheReader" target="_blank" style="color: navy; text-decoration: none;">支持的设备列表</a>。&nbsp;<a href="http://code.google.com/p/tesseract-ocr/" target="_blank" style="color: navy; text-decoration: none;">Tesseract OCR Engine</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Tesseract OCR引擎是1995年UNLV Accuracy测试的前三名之一，在1995和2006年之间它的进展不大，但依然是当前精度最高的OCR引擎。这个源码可读取二进制、灰阶或彩色图片并输出文字，内置一个TIFF阅读器可读取非压缩的TIFF文件，增加libtiff后也可读取压缩图片。<a href="http://code.google.com/p/tesseract-ocr/wiki/ReadMe" target="_blank" style="color: navy; text-decoration: none;">指南</a>和<a href="http://code.google.com/p/tesseract-ocr/wiki/FAQ" target="_blank" style="color: navy; text-decoration: none;">问答</a>。&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/neatx/" target="_blank" style="color: navy; text-decoration: none;">Neatx &#8211; Open Source NX server</a>&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Neatx是一个开源NX服务，类似NoMachine公司商业的NX服务。NX协议比VNX更强大，它们的区别主要在：&nbsp;&nbsp;&nbsp;</p><ul style="margin-left: 45px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li style="list-style: inherit;">NX是X11客户端所以不会发送位图</li><li style="list-style: inherit;">NX可兼容X、VNC和Windows版的Remote Desktop</li><li style="list-style: inherit;">NX可缓存数据</li><li style="list-style: inherit;">NX<a href="http://notatnik.mekk.waw.pl/archives/159-Neatx_-_instrukcja_instalacji.html" target="_blank" style="color: navy; text-decoration: none;">安装简单</a></li></ul><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">另外一个可选的项目可以看看Google的<a href="http://freenx.berlios.de/" target="_blank" style="color: navy; text-decoration: none;">FreeNx</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/psvm/" target="_blank" style="color: navy; text-decoration: none;">PSVM</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">它是<a href="http://books.nips.cc/papers/files/nips20/NIPS2007_0435.pdf" target="_blank" style="color: navy; text-decoration: none;">这个文件</a>的代码，这是一个SVM的&#8220;支持所有核心&#8221;的版本，可多机并行运行，<a href="http://code.google.com/p/psvm/wiki/PSVMUsage" target="_blank" style="color: navy; text-decoration: none;">实例见此</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://golang.org/" target="_blank" style="color: navy; text-decoration: none;">GO</a>&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">Google开发的新编程语言，<a href="http://www.google.org.cn/posts/google-new-language-go.html" target="_blank" style="color: navy; text-decoration: none;">谷奥有报道</a>。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-collections/" target="_blank" style="color: navy; text-decoration: none;">The Google Collections Library for Java</a>&nbsp;&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">这是一系列与Java 5以及更高版本有关的库，Google花钱给买过来了。&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;"><a href="http://code.google.com/p/google-styleguide/" target="_blank" style="color: navy; text-decoration: none;">Google styleguide</a>&nbsp;&nbsp;</p><p style="font-size: 13px; line-height: 1.4; margin-top: 10px; margin-bottom: 10px; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; background-color: #ffffff;">每个主流的<span style="line-height: 1.5;"><a href="http://www.feng5166.com/blog/?tag=%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE" target="_blank" style="color: navy; text-decoration: none;">开源项目</a></span>都有它自己的向导形式，比如一系列的演示代码。如果这些代码都按照&#8220;Style&#8221;的形式来演示，会更友好。</p><img src ="http://www.blogjava.net/xiaomage234/aggbug/396448.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-03-14 17:35 <a href="http://www.blogjava.net/xiaomage234/archive/2013/03/14/396448.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>十个免费的Web压力测试工具</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395536.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 21 Feb 2013 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395536.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395536.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395536.html</trackback:ping><description><![CDATA[<p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">本文列举了是十个免费工具，可以用来进行Web的负载/压力测试的。这样你就可以知道你的服务器以及你的WEB应用能够扛得住多少的并发量，以及网站性能。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">1.&nbsp;<a href="http://grinder.sourceforge.net/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">Grinder</a>&nbsp;&#8211; &nbsp;Grinder是一个开源的JVM负载测试框架，它通过很多负载注射器来为分布式测试提供了便利。 支持用于执行测试脚本的Jython脚本引擎HTTP测试可通过HTTP代理进行管理。根据项目网站的说法，Grinder的 主要目标用户是&#8220;理解他们所测代码的人&#8212;&#8212;Grinder不仅仅是带有一组相关响应时间的&#8216;黑盒&#8217;测试。由于测试过程可以进行编码&#8212;&#8212;而不是简单地脚本 化，所以<a href="http://www.admin10000.com/" target="_blank" title="程序员的本质" style="color: #0d4ac6; text-decoration: initial;">程序员</a>能测试应用中内部的各个层次，而不仅仅是通过用户界面测试响应时间。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><img alt="The Grinder" src="http://www.admin10000.com/UploadFiles/Document/201207/09/20120709101820098881.PNG" title="The Grinder" style="border: none;" /></p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">2.&nbsp;<a href="http://www.pylot.org/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">Pylot</a>&nbsp;-Pylot是一款开源的测试web service性能和扩展性的工具，它运行HTTP 负载测试，这对容量计划，确定基准点，分析以及系统调优都很有用处。Pylot产生并发负载（HTTP Requests），检验服务器响应，以及产生带有metrics的报表。通过GUI或者shell/console来执行和监视test suites。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><img alt="Pylot Main Logo" src="http://www.admin10000.com/UploadFiles/Document/201207/09/20120709101820214302.GIF" style="border: none;" /></p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">2.&nbsp;<a href="http://www.iis.net/community/default.aspx?tabid=34&amp;i=1466&amp;g=6" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">Web Capacity Analysis Tool (WCAT)</a>&nbsp;&#8211; 这是一种轻量级负载生成实用工具，不仅能够重现对 Web 服务器（或负载平衡服务器场）的脚本 HTTP 请求，同时还可以收集性能统计数据供日后分析之用。WCAT 是多线程应用程序，并且支持从单个源控制多个负载测试客户端，因此您可以模拟数千个并发用户。该实用工具利用您的旧机器作为测试客户端，其中每个测试客户端又可以产生多个虚拟客户端（最大数量取决于客户端机器的网络适配器和其他硬件）。您可以选择使用 HTTP 1.0 还是 HTTP 1.1 请求，以及是否使用 SSL。并且，如果测试方案需要，您还可以使用脚本执行的基本或 NTLM 身份验证来访问站点的受限部分。（如果您的站点使用 cookie、表单或基于会话的身份验证，那您可以创建正确的 GET 或 POST 请求来对测试用户进行身份验证。）WCAT 还可管理您站点可能设置的任何 cookie，所以配置文件和会话信息将永久保存。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">3.&nbsp;<a href="http://fwptt.sourceforge.net/index.html" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">fwptt</a>&nbsp;&#8211; fwptt 也是一个用来进行WEB应用负载测试的工具。它可以记录一般的请求，也可以记录Ajax请求。它可以用来测试&nbsp;asp.net， jsp， php 或是其它的Web应用。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">4.&nbsp;<a href="http://jcrawler.sourceforge.net/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">JCrawler</a>&nbsp;&#8211; JCrawler是一个开源(<a href="http://www.opensource.org/licenses/cpl.php" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">&nbsp;CPL</a>) 的WEB应用压力测试工具。通过其名字，你就可以知道这是一个用Java写的像网页爬虫一样的工具。只要你给其几个URL，它就可以开始爬过去了，它用一种特殊的方式来产生你WEB应用的负载。这个工具可以用来测试搜索引擎对你站点产生的负载。当然，其还有另一功能，你可以建立你的网站地图和再点击一下，将自动提交Sitemap给前5名的搜索引擎！</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">5.&nbsp;<a href="http://jakarta.apache.org/jmeter/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">Apache JMeter</a>&nbsp;&#8211; Apache JMeter是一个专门为运行和服务器装载测试而设计的、100％的纯Java桌面运行程序。原先它是为Web/HTTP测试而设计的，但是它已经扩展以支持各种各样的测试模块。它和用于HTTP和SQL数据库（使用JDBC）的模块一起运送。它可以用来测试静止资料库或者活动资料库中的服务器的运行情况，可以用来模拟对服务器或者网络系统加以重负荷以测试它的抵抗力，或者用来分析不同负荷类型下的所有运行情况。它也提供了一个可替换的界面用来定制数据显示，测试同步及测试的创建和执行。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">6.&nbsp;<a href="http://www.joedog.org/index/siege-home" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">Siege</a>&nbsp;-Siege（英文意思是围攻）是一个压力测试和评测工具，设计用于WEB开发这评估应用在压力下的承受能力：可以根据配置对一个WEB站点进行多用户的并发访问，记录每个用户所有请求过程的相应时间，并在一定数量的并发访问下重复进行。&nbsp;Siege 支持基本的认证，cookies， HTTP 和 HTTPS 协议。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">7.&nbsp;<a href="http://www.acme.com/software/http_load/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">http_load</a>&nbsp;&#8211; http_load 以并行复用的方式运行，用以测试web服务器的吞吐量与负载。但是它不同于大多数压力测试工具，它可以以一个单一的进程运行，一般不会把客户机搞死。可以可以测试HTTPS类的网站请求。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">8.&nbsp;<a href="http://www.web-polygraph.org/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">Web Polygraph</a>&nbsp;&#8211; Web Polygraph这个软件也是一个用于测试WEB性能的工具，这个工具是很多公司的标准测试工具，包括微软在分析其软件性能的时候，也是使用这个工具做为基准工具的。很多招聘测试员的广告中都注明需要熟练掌握这个测试工具。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">9.&nbsp;<a href="http://opensta.org/" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">OpenSTA</a>&nbsp;&#8211; OpenSTA是一个免费的、开放源代码的web性能测试工具，能录制功能非常强大的脚本过程，执行性能测试。例如虚拟多个不同的用户同时登陆被测试网站。其还能对录制的测试脚本进行,按指定的语法进行编辑。在录制完测试脚本后，可以对测试脚本进行编辑，以便进行特定的性能指标分析。其较为丰富的图形化测试结果大大提高了测试报告的可阅读性。OpenSTA&nbsp;基于CORBA&nbsp;的结构体系，它通过虚拟一个proxy，使用其专用的脚本控制语言，记录通过proxy&nbsp;的一切HTTP/S traffic。通过分析OpenSTA的性能指标收集器收集的各项性能指标，以及HTTP&nbsp;数据，对系统的性能进行分析。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">来源：<a href="http://www.devcurry.com/2010/07/10-free-tools-to-loadstress-test-your.html" rel="nofollow" target="_blank" style="color: #0d4ac6; text-decoration: initial;">10 Free Tools to Load/Stress Test Your Web Applications</a></p><img src ="http://www.blogjava.net/xiaomage234/aggbug/395536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-21 16:27 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/21/395536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>20个初学者实用的CSS技巧</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395535.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 21 Feb 2013 08:12:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395535.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395535.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395535.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395535.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395535.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 过去就连一个镜像站点，我们都依靠大量的开发人员和程序员进行维护。得益于CSS和它的灵活性使得样式能够从代码中被独立抽离出来，从而让一个只具备基本CSS理论的初学者都能够轻易地改变网站的样式。　　不论你是对用CSS建站感兴趣还是仅仅拿它让你的博客更有feel，打好基础才能盖高楼。下面让我们来看看一些对于初学者实用的CSS常识：　1、使用reset.css　　火狐和IE这两种不同的浏览器，在绘制CSS...&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaomage234/archive/2013/02/21/395535.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaomage234/aggbug/395535.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-21 16:12 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/21/395535.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>20个很有用的PHP类库</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395532.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 21 Feb 2013 08:09:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395532.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395532.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395532.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395532.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395532.html</trackback:ping><description><![CDATA[<p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">介绍20个非常有用的PHP类库，相信一定可以为你的WEB开发提供更好和更为快速的方法。</p><h3>图表库</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">下面的类库可以让你很简的创建复杂的图表和图片。当然，它们需要GD库的支持。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://pchart.sourceforge.net/" target="_blank" title="pChart" style="color: #0d4ac6; text-decoration: initial;">pChart</a>&nbsp;&#8211; 一个可以创建统计图的库。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://naku.dohcrew.com/libchart/pages/introduction/" target="_blank" title="Libchart" style="color: #0d4ac6; text-decoration: initial;">Libchart</a>&nbsp;&#8211; 这也是一个简单的统计图库。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.aditus.nu/jpgraph/" target="_blank" title="JpGraph" style="color: #0d4ac6; text-decoration: initial;">JpGraph</a>&nbsp;&#8211; 一个面向对象的图片创建类。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://teethgrinder.co.uk/open-flash-chart/" target="_blank" title="Open Flash Chart" style="color: #0d4ac6; text-decoration: initial;">Open Flash Chart</a>&nbsp;&#8211; 这是一个基于Flash的统计图。</p><h3>缩略图生成</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://phpthumb.sourceforge.net/" target="_blank" title=" phpThumb" style="color: #0d4ac6; text-decoration: initial;">phpThumb</a>&nbsp;&#8211; 功能很强大，如何强大还是自己去体会吧。</p><h3>支付</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">你的网站需要处理支付方面的事情？需要一个和支付网关的程序？下面这个程序可以帮到你。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.phpfour.com/blog/2009/02/php-payment-gateway-library-for-paypal-authorizenet-and-2checkout/" target="_blank" title="PHP Payment Library" style="color: #0d4ac6; text-decoration: initial;">PHP Payment Library</a>&nbsp;&#8211; 支持Paypal, Authorize.net&nbsp;和2Checkout (2CO)</p><h3>RSS 解析</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">解释RSS并是一件很单调的事情，不过幸好你有下面的类库可以帮助你方便地读取RSS的Feed。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://magpierss.sourceforge.net/" target="_blank" title="MagpieRSS" style="color: #0d4ac6; text-decoration: initial;">MagpieRSS</a>&nbsp;&#8211; 开源的PHP版RSS解析器，据说功能强大，未验证。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://simplepie.org/" target="_blank" title="SimplePie" style="color: #0d4ac6; text-decoration: initial;">SimplePie</a>&nbsp;&#8211; 这是一个非常快速，而且易用的RSS和Atom 解析库。</p><h3>OpenID</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.openidenabled.com/php-openid/" target="_blank" title="PHP-OpenID" style="color: #0d4ac6; text-decoration: initial;">PHP-OpenID</a>&nbsp;&#8211; 支持OpenID的一个PHP库。OpenID是帮助你使用相同的用户名和口令登录不同的网站的一种解决方案。如果你对OpenID不熟悉的话，你可以到这里看看：<a href="http://openid.net.cn/" style="color: #0d4ac6; text-decoration: initial;">http://openid.net.cn/</a></p><h3>PDF 生成器</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.fpdf.org/" target="_blank" title="FPDF" style="color: #0d4ac6; text-decoration: initial;">FPDF</a>&nbsp;&#8211; 这量一个可以让你生成PDF的纯PHP类库。</p><h3>Excel 相关</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">你的站点需要生成Excel？没有问题，下面这两个类库可以让你轻松做到这一点。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://code.google.com/p/php-excel/" target="_blank" title="php-excel" style="color: #0d4ac6; text-decoration: initial;">php-excel</a>&nbsp;&#8211; 这是一个非常简单的Excel文件生成类。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://code.google.com/p/php-excel-reader/" target="_blank" title="PHP Excel Reader" style="color: #0d4ac6; text-decoration: initial;">PHP Excel Reader</a>&nbsp;&#8211; 可以解析并读取XLS文件中的数据。</p><h3>E-Mail 相关</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">不喜欢PHP的mail函数？觉得不够强大？下面的PHP邮件相关的库绝对不会让你失望。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://swiftmailer.org/" target="_blank" title="Swift Mailer" style="color: #0d4ac6; text-decoration: initial;">Swift Mailer</a>&nbsp;&#8211; 免费的超多功能的PHP邮件库。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://phpmailer.codeworxtech.com/" target="_blank" title="PHPMailer" style="color: #0d4ac6; text-decoration: initial;">PHPMailer&nbsp;</a>- 超强大的邮件发送类。</p><h3>数据为抽象/对象关系映射ORM</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://adodb.sourceforge.net/" target="_blank" title="ADOdb" style="color: #0d4ac6; text-decoration: initial;">ADOdb</a>&nbsp;&#8211; 数据库抽象</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.doctrine-project.org/" target="_blank" title="Doctrine" style="color: #0d4ac6; text-decoration: initial;">Doctrine</a>&nbsp;&#8211; 对象关系映射Object relational mapper (ORM)&nbsp;，需要 PHP 5.2.3+ 版本，一个非常强大的database abstraction layer (DBAL).</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://propel.phpdb.org/trac/" target="_blank" title="Propel" style="color: #0d4ac6; text-decoration: initial;">Propel</a>&nbsp;&#8211; 对象关系映射框架- PHP5</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.outlet-orm.org/site/" target="_blank" title="Outlet" style="color: #0d4ac6; text-decoration: initial;">Outlet</a>&nbsp;&#8211; 也是关于对象关系映射的一个工具。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">注：对象关系映射（Object Relational Mapping，简称ORM）是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说，ORM是通过使用描述对象和数据库之间映射的元数据，将程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示者额外的执行开销；然而，如果ORM作为一种中间件实现，则会有很多机会做优化，而这些在手写的持久层并不存在。 更重要的是用于控制转换的元数据需要提供和管理；但是同样，这些花费要比维护手写的方案要少；而且就算是遵守ODMG规范的对象数据库依然需要类级别的元数据。</p><h3>单元测试</h3><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;">如果你在使用测试驱动的方法开发你的程序，下面的类库和框架绝你能帮助你的开发。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.simpletest.org/" target="_blank" title="SimpleTest" style="color: #0d4ac6; text-decoration: initial;">SimpleTest</a>&nbsp;&#8211; 一个PHP的单元测试和网页测试的框架。</p><p style="margin: 10px 0px; padding: 0px; color: #555555; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 23px; background-color: #f9f9f9;"><a href="http://www.phpunit.de/" target="_blank" title="PHPUnit" style="color: #0d4ac6; text-decoration: initial;">PHPUnit</a>&nbsp;&#8211; 来自xUnit 家族，提供一个框架可以让你方便地进行单元测试的案例开发。并可非常容易地分析其测试结果。</p><img src ="http://www.blogjava.net/xiaomage234/aggbug/395532.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-21 16:09 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/21/395532.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>支付宝手机应用内支付官方文档</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395531.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 21 Feb 2013 08:08:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395531.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395531.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/21/395531.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395531.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395531.html</trackback:ping><description><![CDATA[<div>&nbsp;手机应用内支付包支付文档<br /><br />https://b.alipay.com/order/productDetail.htm?productId=2012120700377310&amp;tabId=4#ps-tabinfo-hash<br /><br />下载地址：<br />http://download.alipay.com/public/api/base/WS_SECURE_PAY.zip&nbsp;</div><img src ="http://www.blogjava.net/xiaomage234/aggbug/395531.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-21 16:08 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/21/395531.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转载]js arguments</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395021.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 01 Feb 2013 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395021.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395021.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395021.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395021.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395021.html</trackback:ping><description><![CDATA[<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">js进行函数调用时，除了指定的参数外，还创建一个隐含的对象&#8212;&#8212;arguments。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">一、arguments可以用arguments[index]这样的语法取值，拥有长度属性length。arguments对象存储的是实际传递给函数的参数，而不局限于函数声明所定义的参数列表，例如：</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">&nbsp;<wbr>&nbsp;&lt;script&gt;<br />&nbsp;<wbr>&nbsp;function func(a,b){<br />　　alert(a);<br />　　alert(b);<br />　　for(var i=0;i&lt;arguments.length;i++){<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;alert(arguments[i]);<br />　　}<br />&nbsp;<wbr>&nbsp;}<br />　func(1,2,3,4);<br />&nbsp;<wbr>&nbsp;&lt;/script&gt;</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">代码运行时会依次显示：1，2，1，2，3，4。函数定义了两个参数，但是在调用的时候传递了4个参数。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">&nbsp;<wbr></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">二、arguments的callee属性</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">它表示对函数对象本身的引用，这有利于实现无名函数的递归或者保证函数的封装性。例如：用递归来计算1到n的自然数之和：</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #323e32; font-family: simsun; background-color: #e8e8e8;">&lt;script&gt;<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;var sum=function(n){<br />　&nbsp;<wbr>&nbsp;<wbr>&nbsp;if(1==n) {<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;return 1;<br />　&nbsp;<wbr>&nbsp;<wbr>&nbsp;} else {<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;return n + arguments.callee(n-1);<br />&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;}<br />　 }<br />　 alert(sum(100));<br />&lt;/script&gt;<br /><br /><br /><br /><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">在javascript函数体内，标识符arguments具有特殊含义。它是调用对象的一个特殊属性，用来引用Arguments对象。 Arugments对象就像数组，注意这里只是像并不是哈。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">javascript函数体内，arguments像数组(<span style="word-wrap: normal; word-break: normal; color: red;">并不是真的数组，是一个Arguments对象， 再次强调</span>)一样，有length属性，可以代表传给函数的参数的个数。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">引用一个形式参数可以用参数名，也可以用arguments[]数组形式，其中arguments[0]表示第一个参数。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">所以，javascript中Arguments对象是函数的实际参数，下面，我们一起来进入这神奇的国度，一窥究竟。<br /><br /><strong>arguments.length属性：</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">js不会主动为你判断你到底给函数传了多少个参数，如果你多传了，多余的部分就没有被使用，如果你少传了，那么没传的参数值就是undefined</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">所以我们可以借助arguments的length属性来检测调用函数时是否使用了正确数目的实际参数，因为javascript是不会为你做这些 事的</p><div style="overflow: auto; white-space: nowrap; width: 600px;"><span style="word-wrap: normal; word-break: normal;">function</span>&nbsp;f<span style="word-wrap: normal; word-break: normal;">(</span>x<span style="word-wrap: normal; word-break: normal;">,</span>y<span style="word-wrap: normal; word-break: normal;">,</span>z<span style="word-wrap: normal; word-break: normal;">)</span><br /><span style="word-wrap: normal; word-break: normal;">{</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//首先检查传递的参数数量是否正确</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">if</span><span style="word-wrap: normal; word-break: normal;">(</span>arguments.<span style="word-wrap: normal; word-break: normal;">length</span><span style="word-wrap: normal; word-break: normal;">!=</span><span style="word-wrap: normal; word-break: normal;">3</span><span style="word-wrap: normal; word-break: normal;">)</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">{</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">throw</span><span style="word-wrap: normal; word-break: normal;">new</span>&nbsp;Error<span style="word-wrap: normal; word-break: normal;">(</span><span style="word-wrap: normal; word-break: normal;">"function f called with "</span><span style="word-wrap: normal; word-break: normal;">+</span>&nbsp;arguments.<span style="word-wrap: normal; word-break: normal;">length</span><span style="word-wrap: normal; word-break: normal;">+</span><span style="word-wrap: normal; word-break: normal;">"arguments ,but it not 3 arguments."</span><span style="word-wrap: normal; word-break: normal;">)</span><span style="word-wrap: normal; word-break: normal;">;</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">}</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//下面运行真正的函数</span><br /><span style="word-wrap: normal; word-break: normal;">}</span></div><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;"><strong>arguments还为我们提供了这样一种可能，就是为一个函数传任意数目的实际参数：</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">比如说，我想判断你传给我的一些数字的大小，取出最大的那个，对，没错，你传多少参数都行，但是前提是你要传数字，因为我在函数内部懒得判断了。 呵。</p><div style="overflow: auto; white-space: nowrap; width: 600px;"><span style="word-wrap: normal; word-break: normal;">function</span>&nbsp;max<span style="word-wrap: normal; word-break: normal;">(</span><span style="word-wrap: normal; word-break: normal;">)</span><br /><span style="word-wrap: normal; word-break: normal;">{</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//根据我上一篇日志，这已经是JavaScript内最小的数字了</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">var</span>&nbsp;m&nbsp;<span style="word-wrap: normal; word-break: normal;">=</span>&nbsp;Number.<span style="word-wrap: normal; word-break: normal;">NEGATIVE_INFINITY</span><span style="word-wrap: normal; word-break: normal;">;</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">for</span><span style="word-wrap: normal; word-break: normal;">(</span><span style="word-wrap: normal; word-break: normal;">var</span>&nbsp;i&nbsp;<span style="word-wrap: normal; word-break: normal;">=</span><span style="word-wrap: normal; word-break: normal;">0</span><span style="word-wrap: normal; word-break: normal;">;</span>&nbsp;i&nbsp;<span style="word-wrap: normal; word-break: normal;">&lt;</span>&nbsp;arguments.<span style="word-wrap: normal; word-break: normal;">length</span><span style="word-wrap: normal; word-break: normal;">;</span>&nbsp;i<span style="word-wrap: normal; word-break: normal;">++</span><span style="word-wrap: normal; word-break: normal;">)</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">{</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//只要有任何一个参数比m大，那么m就变成了这个参数的值</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">if</span><span style="word-wrap: normal; word-break: normal;">(</span>arguments<span style="word-wrap: normal; word-break: normal;">[</span>i<span style="word-wrap: normal; word-break: normal;">]</span><span style="word-wrap: normal; word-break: normal;">&gt;</span>&nbsp;m<span style="word-wrap: normal; word-break: normal;">)</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;m&nbsp;<span style="word-wrap: normal; word-break: normal;">=</span>&nbsp;arguments<span style="word-wrap: normal; word-break: normal;">[</span>i<span style="word-wrap: normal; word-break: normal;">]</span><span style="word-wrap: normal; word-break: normal;">;</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">}</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">return</span>&nbsp;m<span style="word-wrap: normal; word-break: normal;">;</span><br /><span style="word-wrap: normal; word-break: normal;">}</span></div><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">怎么样？这个方法很巧妙吧？呵呵。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;"><strong>说明一下arguments与真正传的形式参数是一致的：</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">比如，你给函数传了一个叫param的参数，并且只有这一个参数，那么param与arguments[0]都是对这个参数值的引用，</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">改变其中一个值，即改变了二者所有的值</p><div style="overflow: auto; white-space: nowrap; width: 600px;"><span style="word-wrap: normal; word-break: normal;">function</span>&nbsp;change<span style="word-wrap: normal; word-break: normal;">(</span>param<span style="word-wrap: normal; word-break: normal;">)</span><br /><span style="word-wrap: normal; word-break: normal;">{</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//比如我传的param为simaopig，那么alert就是simaopig，</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//如果啥也没传就会alert　undefined</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">alert</span><span style="word-wrap: normal; word-break: normal;">(</span>param<span style="word-wrap: normal; word-break: normal;">)</span><span style="word-wrap: normal; word-break: normal;">;</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//用arguments[0]改变了这个参数的值</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr>&nbsp;arguments<span style="word-wrap: normal; word-break: normal;">[</span><span style="word-wrap: normal; word-break: normal;">0</span><span style="word-wrap: normal; word-break: normal;">]</span><span style="word-wrap: normal; word-break: normal;">=</span><span style="word-wrap: normal; word-break: normal;">'xiaoxiaozi'</span><span style="word-wrap: normal; word-break: normal;">;</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">//没错，这个值变成了xiaoxiaozi</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">alert</span><span style="word-wrap: normal; word-break: normal;">(</span>param<span style="word-wrap: normal; word-break: normal;">)</span><span style="word-wrap: normal; word-break: normal;">;</span><br /><span style="word-wrap: normal; word-break: normal;">}</span></div><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;"><strong>arguments的callee属性：</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">arguments的callee属性是用来引用当前正在执行的函数，这对未命名的函数调用自身非常有好处。</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">现在用arguments的这个callee同样可以简单的实现</p><div style="overflow: auto; white-space: nowrap; width: 600px;"><span style="word-wrap: normal; word-break: normal;">//用函数直接量，采用arguments.callee属性实现递归函数</span><br /><span style="word-wrap: normal; word-break: normal;">var</span>&nbsp;result&nbsp;<span style="word-wrap: normal; word-break: normal;">=</span><span style="word-wrap: normal; word-break: normal;">function</span><span style="word-wrap: normal; word-break: normal;">(</span>x<span style="word-wrap: normal; word-break: normal;">)</span><span style="word-wrap: normal; word-break: normal;">{</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">if</span><span style="word-wrap: normal; word-break: normal;">(</span>x<span style="word-wrap: normal; word-break: normal;">&lt;=</span><span style="word-wrap: normal; word-break: normal;">1</span><span style="word-wrap: normal; word-break: normal;">)</span><span style="word-wrap: normal; word-break: normal;">return</span><span style="word-wrap: normal; word-break: normal;">1</span><span style="word-wrap: normal; word-break: normal;">;</span><br />&nbsp;<wbr>&nbsp;&nbsp;<wbr><span style="word-wrap: normal; word-break: normal;">return</span>&nbsp;x<span style="word-wrap: normal; word-break: normal;">*</span>arguments.<span style="word-wrap: normal; word-break: normal;">callee</span><span style="word-wrap: normal; word-break: normal;">(</span>x<span style="word-wrap: normal; word-break: normal;">-</span><span style="word-wrap: normal; word-break: normal;">1</span><span style="word-wrap: normal; word-break: normal;">)</span><span style="word-wrap: normal; word-break: normal;">;</span><br /><span style="word-wrap: normal; word-break: normal;">}</span><span style="word-wrap: normal; word-break: normal;">;</span></div><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">在最后提醒大家一点，<span style="word-wrap: normal; word-break: normal; color: red;">既然这个arguments这么厉害，那么我们就不要为变量命名为arguments 了，事实上arguments是javascript的保留字之一</span>。嗯。</p></p><img src ="http://www.blogjava.net/xiaomage234/aggbug/395021.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-01 14:45 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/01/395021.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaScript(js) 单元测试工具 -- JsUnit(转载)</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395013.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 01 Feb 2013 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395013.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395013.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395013.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395013.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395013.html</trackback:ping><description><![CDATA[<span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">Jsunit 就是 Junit 的javascript 版本，下载并解压Jsunit zip，大部分的核心文件都在 jsunit/app 目录下，</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">两个最基本的文件：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">. jsUnitCore.js -- 每个测试文件都要引用它</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">. testRunner.html -- 用来运行具体的jsunit 测试</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">(1) 起步例子：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">在Jsunit解压后的同级目录下建立两个文件，目录结构：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">|-- jsunit</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">|-- simple.js</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">|-- simple_test.html</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">写完后运行 jsunit/testRunner.html，在页面中选择simple_test.html, 点击run，可以看到测试结果信息。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">// simple.js 被测试的javascript文件</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function addTwoNumbers(value1, value2){</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; return parseInt(value1) + parseInt(value2);</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">// simple_test.html 测试文件</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;!DOCTYPE HTML PUBLIC&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">"-//W3C//DTD HTML 4.0 Transitional//EN"&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;HTML&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;HEAD&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;TITLE&gt; New Document &lt;/TITLE&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;script language="JavaScript"&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">src="jsunit/app/jsUnitCore.js"&gt;&lt;/script&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;script language="JavaScript"&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">src="simple.js"&gt;&lt;/script&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;script language="JavaScript"&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function testValidArgs()</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">{</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; assertEquals("2 + 2 is 4",&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; 4, addTwoNumbers(2, 2));</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function testWithNegativeNumbers()</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">{</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; assertEquals("-2 + -2 is -4",&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; -4, addTwoNumbers(-2, -2));</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function exposeTestFunctionNames()</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">{</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; var tests = new Array(2);</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; tests[0] = "testValidArgs";</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; tests[1] = "testWithNegativeNumbers";</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; return tests;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/script&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/HEAD&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;BODY&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">test page for addTwoNumbers(value1, value2);</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/BODY&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/HTML&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">通常以"test"开头的测试函数会被自动发现，但如果没有发现，就需要我们用exposeTestFunctionNames 函数来显示指定测试函数。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">(2) setUpPage()</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">jsunit 包含了一次性启动方法，setUpPage() 只对每个测试页调用一次，即在所有测试函数调用之前调用，适于做预处理，但要注意在setUpPage()最后一行要把 setUpPageStatus 变量设置为 &#8220;complete&#8221;, 如：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">var arg1;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">var arg2;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function setUpPage(){</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; arg1 = 2;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; arg2 = 2;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; setUpPageStatus = "complete";</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">(3) 测试集</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">测试集把不同的测试页分组组织，其中包含测试页或其他测试集，他们会按照顺序执行。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">注意点：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">. 测试集中不能包含任何测试函数</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">. 必须包含一个返回 jsUnitTestSuite 对象的 suite 函数</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">. 有两个方法添加测试页：addTestPage(testPage) addTestSuite(testSuite), 在添加测试页时要注意路径，应是相对于testRunner.html 的</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">例子：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;HTML&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;HEAD&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;TITLE&gt; New Document &lt;/TITLE&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;script language="JavaScript"&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">src="jsunit/app/jsUnitCore.js"&gt;&lt;/script&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;script language="JavaScript"&nbsp;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">src="simple.js"&gt;&lt;/script&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;script language="JavaScript"&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function sampleSuite()</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">{</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">var sampleSuite = new top.jsUnitTestSuite();</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">sampleSuite.addTestPage("../simple_test.html");</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">return sampleSuite;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">function suite()</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">{</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">var testSuite = new top.jsUnitTestSuite();</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">testSuite.addTestSuite(sampleSuite());</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">testSuite.addTestPage("../simple_test.html");</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">return testSuite;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">}</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/script&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/HEAD&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;BODY&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/BODY&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">&lt;/HTML&gt;</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">(4) 日志和跟踪</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">运行testRunner.html时会发现他有 Trace level 项，用于现实我们在测试方法中的日志信息，包含3个函数：</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">warn(message, [value])</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">inform(message, [value])</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">debug(message, [value])</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">原文出处：http://www.zhuoda.org/irini/83098.html</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;" /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff;">JsUnit下载地址：http://sourceforge.net/projects/jsunit/</span><img src ="http://www.blogjava.net/xiaomage234/aggbug/395013.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-01 11:24 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/01/395013.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JS测试工具 Google JS Test</title><link>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395014.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 01 Feb 2013 03:24:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395014.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/395014.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/02/01/395014.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/395014.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/395014.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Google JS Test是一个运行于V8 JavaScript引擎下的Javascript单元测试框架，其在Google内部负责对Chrome的快速JS执行速度进行测试，现在Google以开源工程开放大家使用。Google JS Test主要特性：超快的启动速度和执行时间，不需要在浏览器里运行清爽而具有可读性的输出内容也有一个可选的基于浏览器的测试器，可在JS修改的时候刷新其样式和语义跟Goo...&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaomage234/archive/2013/02/01/395014.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaomage234/aggbug/395014.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-02-01 11:24 <a href="http://www.blogjava.net/xiaomage234/archive/2013/02/01/395014.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaScript 项目优化总结【转】</title><link>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394701.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 24 Jan 2013 06:17:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394701.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/394701.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394701.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/394701.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/394701.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 前端时间对公司已有项目JavaScript代码进行优化，本文的是对优化工作的一个总结，拿出来与大家分享。当然我的优化方式可能并不是最优的，或者说有些不对的地方，请指教。　　JavaScript优化总结分为以下几点优化前后对比优化前优化后代码混乱，同样功能的函数重复出现在多个地方。如果需要修改实现，需要找到所有的地方。牵一发而动全身模块化，提取公共接口组织为库、结构清晰、方便代码重用、并且能够游戏防...&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaomage234/archive/2013/01/24/394701.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaomage234/aggbug/394701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-01-24 14:17 <a href="http://www.blogjava.net/xiaomage234/archive/2013/01/24/394701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Best Practices for Speeding Up Your Web Site</title><link>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394700.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 24 Jan 2013 06:16:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394700.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/394700.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394700.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/394700.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/394700.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: from:http://developer.yahoo.com/performance/rules.htmlMinimize HTTP Requeststag: content80% of the end-user response time is spent on the front-end. Most of this time is tied up in downloading all the...&nbsp;&nbsp;<a href='http://www.blogjava.net/xiaomage234/archive/2013/01/24/394700.html'>阅读全文</a><img src ="http://www.blogjava.net/xiaomage234/aggbug/394700.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-01-24 14:16 <a href="http://www.blogjava.net/xiaomage234/archive/2013/01/24/394700.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>undefined与null的区别</title><link>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394697.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 24 Jan 2013 05:02:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394697.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/394697.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2013/01/24/394697.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/394697.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/394697.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body" style="margin: 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 24px; background-color: #ffffff; word-break: normal !important;"><div id="blog_content" style="margin: 0px;"><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">在JavaScript开发中，被人问到：null与undefined到底有啥区别？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; 一时间不好回答，特别是undefined，因为这涉及到undefined的实现原理。于是，细想之后，写下本文，请各位大侠拍砖。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; 总所周知：null == undefined</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; 但是：null !== undefined</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; 那么这两者到底有啥区别呢？</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; 请听俺娓娓道来...</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">null</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; 这是一个对象，但是为空。因为是对象，所以 typeof null&nbsp; 返回 'object' 。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; null 是 JavaScript 保留关键字。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; null 参与数值运算时其值会自动转换为 0 ，因此，下列表达式计算后会得到正确的数值：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　　　表达式：123 + null　　　　结果值：123</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　　　表达式：123 * null　　　　结果值：0</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">undefined</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　undefined是全局对象（window）的一个特殊属性，其值是未定义的。但 typeof undefined 返回 'undefined' 。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然undefined是有特殊含义的，但它确实是一个属性，而且是全局对象（window）的属性。请看下面的代码：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; alert('undefined' in window);&nbsp;&nbsp; //输出：true</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp; var anObj = {};<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp; alert('undefined' in anObj);&nbsp;&nbsp;&nbsp; //输出：false</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;<br style="margin: 0px; padding: 0px;" />从中可以看出，undefined是window对象的一个属性，但却不是anObj对象的一个属性。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　注意：尽管undefined是有特殊含义的属性，但却不是JavaScript的保留关键字。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　undefined参与任何数值计算时，其结果一定是NaN。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　随便说一下，NaN是全局对象（window）的另一个特殊属性，Infinity也是。这些特殊属性都不是JavaScript的保留关键字！</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">提高undefined性能</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　当我们在程序中使用undefined值时，实际上使用的是window对象的undefined属性。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　同样，当我们定义一个变量但未赋予其初始值，例如：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　　　var aValue;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　这时，JavaScript在所谓的预编译时会将其初始值设置为对window.undefined属性的引用，</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　于是，当我们将一个变量或值与undefined比较时，实际上是与window对象的undefined属性比较。这个比较过程中，JavaScript会搜索window对象名叫&#8216;undefined'的属性，然后再比较两个操作数的引用指针是否相同。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　由于window对象的属性值是非常多的，在每一次与undefined的比较中，搜索window对象的undefined属性都会花费时 间。在需要频繁与undefined进行比较的函数中，这可能会是一个性能问题点。因此，在这种情况下，我们可以自行定义一个局部的undefined变 量，来加快对undefined的比较速度。例如：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;&nbsp;&nbsp; function anyFunc()<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp; {<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var undefined;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //自定义局部undefined变量<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(x == undefined)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //作用域上的引用比较<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(y != undefined)&nbsp;&nbsp; //作用域上的引用比较<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp; };<br style="margin: 0px; padding: 0px;" />&nbsp; 　　其中，定义undefined局部变量时，其初始值会是对window.undefined属性值的引用。新定义的局部undefined变量存在与 该函数的作用域上。在随后的比较操作中，JavaScript代码的书写方式没有任何的改变，但比较速度却很快。因为作用域上的变量数量会远远少于 window对象的属性，搜索变量的速度会极大提高。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">　　这就是许多前端JS框架为什么常常要自己定义一个局部undefined变量的原因！</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/leadzen/archive/2009/02/17/3899392.aspx" style="margin: 0px; padding: 0px; text-decoration: initial; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;">http://blog.csdn.net/leadzen/archive/2009/02/17/3899392.aspx</a></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-size: small;"><strong style="margin: 0px; padding: 0px;">第二篇 区别Javascript中的Null与Undefined</strong></span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">在JavaScript中存在这样两种原始类型:Null与Undefined。这两种类型常常会使JavaScript的开发人员产生疑惑，在什么时候是Null，什么时候又是Undefined?</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><strong style="margin: 0px; padding: 0px;">Undefined</strong>类型只有一个值，即undefined。当声明的变量还未被初始化时，变量的默认值为undefined。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><strong style="margin: 0px; padding: 0px;">Null</strong>类型也只有一个值，即null。null用来表示尚未存在的对象，常用来表示函数企图返回一个不存在的对象。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">js 代码</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px;">var&nbsp;oValue;&nbsp;<br style="margin: 0px; padding: 0px;" />alert(oValue&nbsp;==&nbsp;undefined);&nbsp;//output&nbsp;"true"</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">这段代码显示为true,代表oVlaue的值即为undefined，因为我们没有初始化它。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">js 代码</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px;">alert(null&nbsp;==&nbsp;document.getElementById('notExistElement'));</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">当页面上不存在id为&#8221;notExistElement&#8221;的DOM节点时，这段代码显示为&#8221;true&#8221;，因为我们尝试获取一个不存在的对象。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">js 代码</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px;">alert(typeof&nbsp;undefined);&nbsp;//output&nbsp;"undefined"&nbsp;<br style="margin: 0px; padding: 0px;" />alert(typeof&nbsp;null);&nbsp;//output&nbsp;"object"</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">第一行代码很容易理解，undefined的类型为Undefined；第二行代码却让人疑惑，为什么null的类型又是Object了呢？其实这 是 JavaScript最初实现的一个错误，后来被ECMAScript沿用下来。在今天我们可以解释为，null即是一个不存在的对象的占位符，但是在实 际编码时还是要注意这一特性。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">js 代码</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px;">alert(null&nbsp;==&nbsp;undefined);&nbsp;//output&nbsp;"true"</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">ECMAScript认为undefined是从null派生出来的，所以把它们定义为相等的。但是，如果在一些情况下，我们一定要区分这两个值，那应该怎么办呢？可以使用下面的两种方法。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">js 代码</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"><br style="margin: 0px; padding: 0px;" /><span style="margin: 0px; padding: 0px;">alert(null&nbsp;===&nbsp;undefined);&nbsp;//output&nbsp;"false"&nbsp;<br style="margin: 0px; padding: 0px;" />alert(typeof&nbsp;null&nbsp;==&nbsp;typeof&nbsp;undefined);&nbsp;//output&nbsp;"false"</span></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">使用typeof方法在前面已经讲过，null与undefined的类型是不一样的，所以输出&#8221;false&#8221;。而===代表绝对等于，在这里null === undefined输出false。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">以上是转载内容：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">document.getElementById('不存在的元素')返回的是null</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">document.getElementById('不存在的元素').value返回的是undefined</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;">jqury--&gt;ajax(post,getJSON)函数中如果{id:undefined}的话，则此参数id不会提交到服务器中,{id:null}会提交到服务器中，如果是将参数直接写到url中则也会提交到服务器上</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px;"></p></div></div><div id="MySignature" style="margin: 10px 0px 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 24px; background-color: #ffffff;"></div><div style="margin: 0px; clear: both; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 24px; background-color: #ffffff;"></div><div id="blog_post_info_block" style="margin: 20px 0px 0px; color: #333333; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 24px; background-color: #ffffff;"><div id="blog_post_info" style="margin: 0px;"><div id="BlogPostCategory" style="margin: 0px;">分类:&nbsp;<a href="http://www.cnblogs.com/xiaohui108/category/271151.html" style="margin: 0px; padding: 0px; text-decoration: initial; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;">JS</a></div></div></div><img src ="http://www.blogjava.net/xiaomage234/aggbug/394697.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2013-01-24 13:02 <a href="http://www.blogjava.net/xiaomage234/archive/2013/01/24/394697.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>淘宝数据魔方技术架构解析【转】</title><link>http://www.blogjava.net/xiaomage234/archive/2012/12/13/392923.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 13 Dec 2012 02:16:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2012/12/13/392923.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/392923.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2012/12/13/392923.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/392923.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/392923.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">from:<a href="http://blog.jobbole.com/1194/">http://blog.jobbole.com/1194/</a>&nbsp;<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;淘宝网拥有国内最具商业价值的海量数据。截至当前，每天有超过30亿的店铺、商品浏览记录，10亿在线商品数，上千万的成交、收藏和评价数据。如何从这些数据中挖掘出真正的商业价值，进而帮助淘宝、商家进行企业的数据化运营，帮助消费者进行理性的购物决策，是淘宝数据平台与产品部的使命。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">为此，我们进行了一系列数据产品的研发，比如为大家所熟知的量子统计、数据魔方和淘宝指数等。尽管从业务层面来讲，数据产品的研发难度并不高；但在 &#8220;海量&#8221;的限定下，数据产品的计算、存储和检索难度陡然上升。本文将以数据魔方为例，向大家介绍淘宝在海量数据产品技术架构方面的探索。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; "><strong style="margin: 0px; padding: 0px; ">淘宝海量数据产品技术架构</strong></p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">数据产品的一个最大特点是数据的非实时写入，正因为如此，我们可以认为，在一定的时间段内，整个系统的数据是只读的。这为我们设计缓存奠定了非常重要的基础。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3861"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/1-taobao-shuju-mofan.jpg" rel="lightbox[1194]" title="淘宝海量数据产品技术架构" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3861"="" title="淘宝海量数据产品技术架构" src="http://blog.jobbole.com/wp-content/uploads/2011/08/1-taobao-shuju-mofan.jpg" alt="淘宝海量数据产品技术架构" width="500" height="273" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图1 淘宝海量数据产品技术架构</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">按照数据的流向来划分，我们把淘宝数据产品的技术架构分为五层（如图1所示），分别是数据源、计算层、存储层、查询层和产品层。位于架构顶端的是我们的数据来源层，这里有淘宝主站的用户、店铺、商品和交易等数据库，还有用户的浏览、搜索等行为日志等。这一系列的数据是数据产品最原始的生命力所在。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">在数据源层实时产生的数据，通过淘宝自主研发的数据传输组件DataX、DbSync和Timetunnel准实时地传输到一个有1500个节点的 Hadoop集群上，这个集群我们称之为&#8220;云梯&#8221;，是计算层的主要组成部分。在&#8220;云梯&#8221;上，我们每天有大约40000个作业对1.5PB的原始数据按照产品需求进行不同的MapReduce计算。这一计算过程通常都能在凌晨两点之前完成。相对于前端产品看到的数据，这里的计算结果很可能是一个处于中间状态的结果，这往往是在数据冗余与前端计算之间做了适当平衡的结果。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">不得不提的是，一些对实效性要求很高的数据，例如针对搜索词的统计数据，我们希望能尽快推送到数据产品前端。这种需求再采用&#8220;云梯&#8221;来计算效率将是比较低的，为此我们做了流式数据的实时计算平台，称之为&#8220;银河&#8221;。&#8220;银河&#8221;也是一个分布式系统，它接收来自TimeTunnel的实时消息，在内存中做实时计算，并把计算结果在尽可能短的时间内刷新到<span style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/1344/" title="8种Nosql数据库系统对比" target="_blank" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; ">NoSQL</a></span>存储设备中，供前端产品调用。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">容易理解，&#8220;云梯&#8221;或者&#8220;银河&#8221;并不适合直接向产品提供实时的数据查询服务。这是因为，对于&#8220;云梯&#8221;来说，它的定位只是做离线计算的，无法支持较高的性能和并发需求；而对于&#8220;银河&#8221;而言，尽管所有的代码都掌握在我们手中，但要完整地将数据接收、实时计算、存储和查询等功能集成在一个分布式系统中，避免不了分层，最终仍然落到了目前的架构上。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">为此，我们针对前端产品设计了专门的存储层。在这一层，我们有基于MySQL的分布式关系型数据库集群MyFOX和基于HBase的NoSQL存储集群Prom，在后面的文字中，我将重点介绍这两个集群的实现原理。除此之外，其他第三方的模块也被我们纳入存储层的范畴。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">存储层异构模块的增多，对前端产品的使用带来了挑战。为此，我们设计了通用的数据中间层&#8212;&#8212;glider&#8212;&#8212;来屏蔽这个影响。glider以HTTP协议对外提供restful方式的接口。数据产品可以通过一个唯一的URL获取到它想要的数据。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">以上是淘宝海量数据产品在技术架构方面的一个概括性的介绍，接下来我将重点从四个方面阐述数据魔方设计上的特点。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; "><strong style="margin: 0px; padding: 0px; ">关系型数据库仍然是王道</strong></p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">关系型数据库（RDBMS）自20世纪70年代提出以来，在工业生产中得到了广泛的使用。经过三十多年的长足发展，诞生了一批优秀的数据库软件，例如Oracle、MySQL、DB2、Sybase和SQL Server等。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3862"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/2-curve-of-myfox.jpg" rel="lightbox[1194]" title="图2 MyFOX中的数据增长曲线" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3862"="" title="图2 MyFOX中的数据增长曲线" src="http://blog.jobbole.com/wp-content/uploads/2011/08/2-curve-of-myfox.jpg" alt="图2 MyFOX中的数据增长曲线" width="500" height="208" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图2 MyFOX中的数据增长曲线</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">尽管相对于非关系型数据库而言，关系型数据库在分区容忍性（Tolerance to Network Partitions）方面存在劣势，但由于它强大的语义表达能力以及数据之间的关系表达能力，在数据产品中仍然占据着不可替代的作用。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">淘宝数据产品选择MySQL的MyISAM引擎作为底层的数据存储引擎。在此基础上，为了应对海量数据，我们设计了分布式MySQL集群的查询代理层&#8212;&#8212;MyFOX，使得分区对前端应用透明。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3863"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/3-data-searche-process-of-taobao.jpg" rel="lightbox[1194]" title="图3 MyFOX的数据查询过程" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3863"="" title="图3 MyFOX的数据查询过程" src="http://blog.jobbole.com/wp-content/uploads/2011/08/3-data-searche-process-of-taobao.jpg" alt="图3 MyFOX的数据查询过程" width="500" height="282" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图3 MyFOX的数据查询过程</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">目前，存储在MyFOX中的统计结果数据已经达到10TB，占据着数据魔方总数据量的95%以上，并且正在以每天超过6亿的增量增长着（如图2所示）。这些数据被我们近似均匀地分布到20个MySQL节点上，在查询时，经由MyFOX透明地对外服务（如图3所示）。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3864"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/4-node-of-taobao-mofang.jpg" rel="lightbox[1194]" title="图4 MyFOX节点结构" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3864"="" title="图4 MyFOX节点结构" src="http://blog.jobbole.com/wp-content/uploads/2011/08/4-node-of-taobao-mofang.jpg" alt="图4 MyFOX节点结构" width="500" height="289" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图4 MyFOX节点结构</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">值得一提的是，在MyFOX现有的20个节点中，并不是所有节点都是&#8220;平等&#8221;的。一般而言，数据产品的用户更多地只关心&#8220;最近几天&#8221;的数据，越早的数据，越容易被冷落。为此，出于硬件成本考虑，我们在这20个节点中分出了&#8220;热节点&#8221;和&#8220;冷节点&#8221;（如图4所示）。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">顾名思义，&#8220;热节点&#8221;存放最新的、被访问频率较高的数据。对于这部分数据，我们希望能给用户提供尽可能快的查询速度，所以在硬盘方面，我们选择了每分钟15000转的SAS硬盘，按照一个节点两台机器来计算，单位数据的存储成本约为4.5W/TB。相对应地，&#8220;冷数据&#8221;我们选择了每分钟7500转的 SATA硬盘，单碟上能够存放更多的数据，存储成本约为1.6W/TB。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">将冷热数据进行分离的另外一个好处是可以有效降低内存磁盘比。从图4可以看出，&#8220;热节点&#8221;上单机只有24GB内存，而磁盘装满大约有 1.8TB（300 * 12 * 0.5 / 1024），内存磁盘比约为4:300，远远低于MySQL服务器的一个合理值。内存磁盘比过低导致的后果是，总有一天，即使所有内存用完也存不下数据的索引了&#8212;&#8212;这个时候，大量的查询请求都需要从磁盘中读取索引，效率大打折扣。<br style="margin: 0px; padding: 0px; " /><strong style="margin: 0px; padding: 0px; ">NoSQL是SQL的有益补充</strong></p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">在MyFOX出现之后，一切都看起来那么完美，开发人员甚至不会意识到MyFOX的存在，一条不用任何特殊修饰的SQL语句就可以满足需求。这个状态持续了很长一段时间，直到有一天，我们碰到了传统的关系型数据库无法解决的问题&#8212;&#8212;全属性选择器（如图5所示）。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3865"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/5-selector-of-taobao-mofang.jpg" rel="lightbox[1194]" title="图5 全属性选择器" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3865"="" title="图5 全属性选择器" src="http://blog.jobbole.com/wp-content/uploads/2011/08/5-selector-of-taobao-mofang.jpg" alt="图5 全属性选择器" width="500" height="262" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图5 全属性选择器</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">这是一个非常典型的例子。为了说明问题，我们仍然以关系型数据库的思路来描述。对于笔记本电脑这个类目，用户某一次查询所选择的过滤条件可能包括 &#8220;笔记本尺寸&#8221;、&#8220;笔记本定位&#8221;、&#8220;硬盘容量&#8221;等一系列属性（字段），并且在每个可能用在过滤条件的属性上，属性值的分布是极不均匀的。在图5中我们可以看到，笔记本电脑的尺寸这一属性有着10个枚举值，而&#8220;蓝牙功能&#8221;这个属性值是个布尔值，数据的筛选性非常差。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">在用户所选择的过滤条件不确定的情况下，解决全属性问题的思路有两个：一个是穷举所有可能的过滤条件组合，在&#8220;云梯&#8221;上进行预先计算，存入数据库供查询；另一个是存储原始数据，在用户查询时根据过滤条件筛选出相应的记录进行现场计算。很明显，由于过滤条件的排列组合几乎是无法穷举的，第一种方案在现实中是不可取的；而第二种方案中，原始数据存储在什么地方？如果仍然用关系型数据库，那么你打算怎样为这个表建立索引？</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">这一系列问题把我们引到了&#8220;创建定制化的存储、现场计算并提供查询服务的引擎&#8221;的思路上来，这就是Prometheus（如图6所示）。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3867"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/6-structure-of-taobao-mofang.jpg" rel="lightbox[1194]" title="图6 Prom的存储结构" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3867"="" title="图6 Prom的存储结构" src="http://blog.jobbole.com/wp-content/uploads/2011/08/6-structure-of-taobao-mofang.jpg" alt="图6 Prom的存储结构" width="500" height="265" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图6 Prom的存储结构</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">从图6可以看出，我们选择了HBase作为Prom的底层存储引擎。之所以选择HBase，主要是因为它是建立在HDFS之上的，并且对于 MapReduce有良好的编程接口。尽管Prom是一个通用的、解决共性问题的服务框架，但在这里，我们仍然以全属性选择为例，来说明Prom的工作原理。这里的原始数据是前一天在淘宝上的交易明细，在HBase集群中，我们以属性对（属性与属性值的组合）作为row-key进行存储。而row-key 对应的值，我们设计了两个column-family，即存放交易ID列表的index字段和原始交易明细的data字段。在存储的时候，我们有意识地让每个字段中的每一个元素都是定长的，这是为了支持通过偏移量快速地找到相应记录，避免复杂的查找算法和磁盘的大量随机读取请求。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3868"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/7-query-of-porm.jpg" rel="lightbox[1194]" title="图7 Prom查询过程" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3868"="" title="图7 Prom查询过程" src="http://blog.jobbole.com/wp-content/uploads/2011/08/7-query-of-porm.jpg" alt="图7 Prom查询过程" width="500" height="268" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图7 Prom查询过程</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">图7用一个典型的例子描述的Prom在提供查询服务时的工作原理，限于篇幅，这里不做详细描述。值得一提的是，Prom支持的计算并不仅限于求和 SUM运算，统计意义上的常用计算都是支持的。在现场计算方面，我们对Hbase进行了扩展，Prom要求每个节点返回的数据是已经经过&#8220;本地计算&#8221;的局部最优解，最终的全局最优解只是各个节点返回的局部最优解的一个简单汇总。很显然，这样的设计思路是要充分利用各个节点的并行计算能力，并且避免大量明细数据的网络传输开销。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; "><strong style="margin: 0px; padding: 0px; ">用中间层隔离前后端</strong></p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">上文提到过，MyFOX和Prom为数据产品的不同需求提供了数据存储和底层查询的解决方案，但随之而来的问题是，各种异构的存储模块给前端产品的使用带来了很大的挑战。并且，前端产品的一个请求所需要的数据往往不可能只从一个模块获取。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">举个例子，我们要在数据魔方中看昨天做热销的商品，首先从MyFOX中拿到一个热销排行榜的数据，但这里的&#8220;商品&#8221;只是一个ID，并没有ID所对应的商品描述、图片等数据。这个时候我们要从淘宝主站提供的接口中去获取这些数据，然后一一对应到热销排行榜中，最终呈现给用户。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3869"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/8-architecture-of-glider.jpg" rel="lightbox[1194]" title="图8 glider的技术架构" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3869"="" title="图8 glider的技术架构" src="http://blog.jobbole.com/wp-content/uploads/2011/08/8-architecture-of-glider.jpg" alt="图8 glider的技术架构" width="500" height="284" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图8 glider的技术架构</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">有经验的读者一定可以想到，从本质上来讲，这就是广义上的异构&#8220;表&#8221;之间的JOIN操作。那么，谁来负责这个事情呢？很容易想到，在存储层与前端产品之间增加一个中间层，它负责各个异构&#8220;表&#8221;之间的数据JOIN和UNION等计算，并且隔离前端产品和后端存储，提供统一的数据查询服务。这个中间层就是glider（如图8所示）。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; "><strong style="margin: 0px; padding: 0px; ">缓存是系统化的工程</strong></p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">除了起到隔离前后端以及异构&#8220;表&#8221;之间的数据整合的作用之外，glider的另外一个不容忽视的作用便是缓存管理。上文提到过，在特定的时间段内，我们认为数据产品中的数据是只读的，这是利用缓存来提高性能的理论基础。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">在图8中我们看到，glider中存在两层缓存，分别是基于各个异构&#8220;表&#8221;（datasource）的二级缓存和整合之后基于独立请求的一级缓存。除此之外，各个异构&#8220;表&#8221;内部可能还存在自己的缓存机制。细心的读者一定注意到了图3中MyFOX的缓存设计，我们没有选择对汇总计算后的最终结果进行缓存，而是针对每个分片进行缓存，其目的在于提高缓存的命中率，并且降低数据的冗余度。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">大量使用缓存的最大问题就是数据一致性问题。如何保证底层数据的变化在尽可能短的时间内体现给最终用户呢？这一定是一个系统化的工程，尤其对于分层较多的系统来说。</p><div mceiecenter"="" style="margin: 0px; color: #383838; font-family: Arial, Helvetica, sans-serif; line-height: normal; text-align: center; "><dl id="attachment_3870"  aligncenter"="" style="margin: 0px auto; padding: 0px; clear: both; width: 510px; "><dt style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/wp-content/uploads/2011/08/9-system-of-cache.jpg" rel="lightbox[1194]" title="图9 缓存控制体系" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; "><img wp-image-3870"="" title="图9 缓存控制体系" src="http://blog.jobbole.com/wp-content/uploads/2011/08/9-system-of-cache.jpg" alt="图9 缓存控制体系" width="500" height="288" style="margin-top: 5px !important; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding: 5px; border: 1px solid #d4d4d4; background-color: #ffffff; border-top-left-radius: 6px; border-top-right-radius: 6px; border-bottom-right-radius: 6px; border-bottom-left-radius: 6px; background-position: initial initial; background-repeat: initial initial; " /></a></dt><dd style="margin: 0px; padding: 0px; ">图9 缓存控制体系</dd></dl></div><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">&nbsp;</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">图9向我们展示了数据魔方在缓存控制方面的设计思路。用户的请求中一定是带了缓存控制的&#8220;命令&#8221;的，这包括URL中的query string，和 HTTP头中的&#8220;If-None-Match&#8221;信息。并且，这个缓存控制&#8220;命令&#8221;一定会经过层层传递，最终传递到底层存储的异构&#8220;表&#8221;模块。各异构&#8220;表&#8221; 除了返回各自的数据之外，还会返回各自的数据缓存过期时间（ttl），而glider最终输出的过期时间是各个异构&#8220;表&#8221;过期时间的最小值。这一过期时间也一定是从底层存储层层传递，最终通过HTTP头返回给用户<span style="margin: 0px; padding: 0px; "><a href="http://blog.jobbole.com/12749/" title="浏览器" style="margin: 0px; padding: 0px; color: #0b5c77; outline: none; border: none; text-decoration: none; ">浏览器</a></span>的。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">缓存系统不得不考虑的另一个问题是缓存穿透与失效时的雪崩效应。缓存穿透是指查询一个一定不存在的数据，由于缓存是不命中时被动写的，并且出于容错考虑，如果从存储层查不到数据则不写入缓存，这将导致这个存在的数据每次请求都要到存储层去查询，失去了缓存的意义。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">有很多种方法可以有效地解决缓存穿透问题，最常见的则是采用布隆过滤器，将所有可能存在的数据哈希到一个足够大的bitmap中，一个一定不存在的数据会被这个bitmap拦截掉，从而避免了对底层存储系统的查询压力。在数据魔方里，我们采用了一个更为简单粗暴的方法，如果一个查询返回的数据为空（不管是数据不存在，还是系统故障），我们仍然把这个空结果进行缓存，但它的过期时间会很短，最长不超过五分钟。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">缓存失效时的雪崩效应对底层系统的冲击非常可怕。遗憾的是，这个问题目前并没有很完美的解决方案。大多数系统设计者考虑用加锁或者队列的方式保证缓存的单线程（进程）写，从而避免失效时大量的并发请求落到底层存储系统上。在数据魔方中，我们设计的缓存过期机制理论上能够将各个客户端的数据失效时间均匀地分布在时间轴上，一定程度上能够避免缓存同时失效带来的雪崩效应。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; "><strong style="margin: 0px; padding: 0px; ">结束语</strong></p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">正是基于本文所描述的架构特点，数据魔方目前已经能够提供压缩前80TB的数据存储空间，数据中间层glider支持每天4000万的查询请求，平均响应时间在28毫秒（6月1日数据），足以满足未来一段时间内的业务增长需求。</p><p style="margin: 0px; padding: 0px 0px 10px; text-indent: 2em; line-height: 22px; color: #383838; font-family: Arial, Helvetica, sans-serif; ">尽管如此，整个系统中仍然存在很多不完善的地方。一个典型的例子莫过于各个分层之间使用短连接模式的HTTP协议进行通信。这样的策略直接导致在流量高峰期单机的TCP连接数非常高。所以说，一个良好的架构固然能够在很大程度上降低开发和维护的成本，但它自身一定是随着数据量和流量的变化而不断变化的。我相信，过不了几年，淘宝数据产品的技术架构一定会是另外的样子。</p><img src ="http://www.blogjava.net/xiaomage234/aggbug/392923.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2012-12-13 10:16 <a href="http://www.blogjava.net/xiaomage234/archive/2012/12/13/392923.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Makefile.am详解</title><link>http://www.blogjava.net/xiaomage234/archive/2012/11/30/392286.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Fri, 30 Nov 2012 08:19:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2012/11/30/392286.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/392286.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2012/11/30/392286.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/392286.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/392286.html</trackback:ping><description><![CDATA[<span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">实战Makefile.am</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">Makefile.am是一种比Makefile更高层次的规则。只需指定要生成什么目标，它由什么源文件生成，要安装到什么目录等构成。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">表一列出了可执行文件、静态库、头文件和数据文件，四种书写Makefile.am文件个一般格式。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><img src="http://121.img.pp.sohu.com/images/blog/2007/10/29/17/29/116867af784.jpg" border="0" alt="" style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">表 1Makefile.am一般格式</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">对于可执行文件和静态库类型，如果只想编译，不想安装到系统中，可以用noinst_PROGRAMS代替bin_PROGRAMS，noinst_LIBRARIES代替lib_LIBRARIES。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">Makefile.am还提供了一些全局变量供所有的目标体使用：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><img src="http://121.img.pp.sohu.com/images/blog/2007/10/29/17/0/116867b39c1.jpg" border="0" alt="" style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">表 2 Makefile.am中可用的全局变量</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">在Makefile.am中尽量使用相对路径，系统预定义了两个基本路径：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><img src="http://119.img.pp.sohu.com/images/blog/2007/10/29/17/0/11686839bab.jpg" border="0" alt="" style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">表 3Makefile.am中可用的路径变量</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">在上文中我们提到过安装路径，automake设置了默认的安装路径：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">1)标准安装路径</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">默认安装路径为：$(prefix) = /usr/local，可以通过./configure --prefix=的方法来覆盖。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">其它的预定义目录还包括：bindir = $(prefix)/bin, libdir = $(prefix)/lib, datadir = $(prefix)/share, sysconfdir = $(prefix)/etc等等。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">2) 定义一个新的安装路径</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">比如test, 可定义testdir = $(prefix)/test, 然后test_DATA =test1 test2，则test1，test2会作为数据文件安装到$(prefix)/ /test目录下。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">我们首先需要在工程顶层目录下（即project/）创建一个Makefile.am来指明包含的子目录：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">SUBDIRS=src/lib src/ModuleA/apple/shell src/ModuleA/apple/core&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">CURRENTPATH=$(shell /bin/pwd)</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">INCLUDES=-I$(CURRENTPATH)/src/include -I$(CURRENTPATH)/src/ModuleA/apple/include&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">export INCLUDES</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">由于每个源文件都会用到相同的头文件，所以我们在最顶层的Makefile.am中包含了编译源文件时所用到的头文件，并导出，见蓝色部分代码。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">我们将lib目录下的swap.c文件编译成libswap.a文件，被apple/shell/apple.c文件调用，那么lib目录下的Makefile.am如下所示：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">noinst_LIBRARIES=libswap.a</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">libswap_a_SOURCES=swap.c</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">INCLUDES=-I$(top_srcdir)/src/includ</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">细心的读者可能就会问：怎么表1中给出的是bin_LIBRARIES，而这里是noinst_LIBRARIES？这</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">是因为如果只想编译，而不想安装到系统中，就用noinst_LIBRARIES代替bin_LIBRARIES，对于可执行文件就用</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">noinst_PROGRAMS代替bin_PROGRAMS。对于安装的情况，库将会安装到$(prefix)/lib目录下，可执行文件将会安装</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">到${prefix}/bin。如果想安装该库，则Makefile.am示例如下：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">bin_LIBRARIES=libswap.a</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">libswap_a_SOURCES=swap.c</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">INCLUDES=-I$(top_srcdir)/src/include</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">swapincludedir=$(includedir)/swap</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">swapinclude_HEADERS=$(top_srcdir)/src/include/swap.h</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">最后两行的意思是将swap.h安装到${prefix}/include /swap目录下。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">接下来，对于可执行文件类型的情况，我们将讨论如何写Makefile.am？对于编译apple/core目录下的文件，我们写成的Makefile.am如下所示：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">noinst_PROGRAMS=test</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">test_SOURCES=test.c&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">test_LDADD=$(top_srcdir)/src/ModuleA/apple/shell/apple.o $(top_srcdir)/src/lib/libswap.a&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">test_LDFLAGS=-D_GNU_SOURCE</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">DEFS+=-D_GNU_SOURCE</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">#LIBS=-lpthread</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">由于我们的test.c文件在链接时，需要apple.o和libswap.a文件，所以我们需要在</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">test_LDADD中包含这两个文件。对于Linux下的信号量/读写锁文件进行编译，需要在编译选项中指明-D_GNU_SOURCE。所以在</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">test_LDFLAGS中指明。而test_LDFLAGS只是链接时的选项，编译时同样需要指明该选项，所以需要DEFS来指明编译选项，由于</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">DEFS已经有初始值，所以这里用+=的形式指明。从这里可以看出，Makefile.am中的语法与Makefile的语法一致，也可以采用条件表达</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">式。如果你的程序还包含其他的库，除了用AC_CHECK_LIB宏来指明外，还可以用LIBS来指明。</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">如果你只想编译某一个文件，那么Makefile.am如何写呢？这个文件也很简单，写法跟可执行文件的差不多，如下例所示：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">noinst_PROGRAMS=apple</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">apple_SOURCES=apple.c</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">DEFS+=-D_GNU_SOURCE</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">我们这里只是欺骗automake，假装要生成apple文件，让它为我们生成依赖关系和执行命令。所以当你运行完automake命令后，然后修改apple/shell/下的Makefile.in文件，直接将LINK语句删除，即：</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">&#8230;&#8230;.</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">clean-noinstPROGRAMS:</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">&nbsp; &nbsp; -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">apple$(EXEEXT): $(apple_OBJECTS) $(apple_DEPENDENCIES)&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">&nbsp; &nbsp; @rm -f apple$(EXEEXT)</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">#$(LINK) $(apple_LDFLAGS) $(apple_OBJECTS) $(apple_LDADD) $(LIBS)</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><span style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><br style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; " /><strong style="font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">本文来自ChinaUnix博客，如果查看原文请点：</strong><a href="http://blog.chinaunix.net/u2/61254/showart_1821022.html" target="_blank" style="color: #0044b6; text-decoration: none; font-family: Verdana, Arial, Helvetica, sans-serif; line-height: 20px; ">http://blog.chinaunix.net/u2/61254/showart_1821022.html</a>&nbsp;<img src ="http://www.blogjava.net/xiaomage234/aggbug/392286.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2012-11-30 16:19 <a href="http://www.blogjava.net/xiaomage234/archive/2012/11/30/392286.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详解Linux下auto工具制作Makefile源码包（制作篇）</title><link>http://www.blogjava.net/xiaomage234/archive/2012/11/29/392204.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Thu, 29 Nov 2012 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2012/11/29/392204.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/392204.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2012/11/29/392204.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/392204.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/392204.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">一、 概述</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">为了更好的制作configure与Makefile，我先把制作流程给写在这里，好让大伙都有个心理准备。这里只说流程，不做解释。（附图供参考）</p><p align="center" style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; "><br /></p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">1、autosan命令生成configure.scan文件，这只是个模板，我们重新编辑这个文件，并把它保存为configure.in文件。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">2、aclocal命令生成aclocal.m4文件。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">3、autoheader命令生成config.h.in。前提是aclocal.m4和configure.in必须生成。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">4、autoconf命令生成configure文件(这个文件都很熟悉吧，嘎嘎)。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">5、创建并编辑Makefile.am，这个文件在根目录与子目录都应该有的。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">6、automake命令生成Makefile.in。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">7、./configure命令，根据Makefile.in生成Makefile文件，这个再熟悉不过了吧。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">相关阅读： 详解Linux下auto工具制作Makefile源码包（工具安装篇）<a title="详解Linux下auto工具制作Makefile源码包（工具安装篇）" href="http://www.linuxidc.com/Linux/2011-05/36616.htm" target="" style="color: #b32bd5; ">http://www.linuxidc.com/Linux/2011-05/36616.htm</a></p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">二、&nbsp;&nbsp;&nbsp;&nbsp; 制作</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">巧妇难做无米之炊，要想完成这次体验，我们还得按规矩一步一步来，源文件得有。首先建个目录Family用来放我们的东西，它下面的东西就多了。源代码什么阿c，阿h啊，都放在src下面，src这个文件夹命名一般都是约定俗成的，我们也不破坏。当然你也可以起其他名字，别搞忘就好。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">&lt;Family&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　|-configure.in</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　|-Makefile.am　</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　|-&lt;src&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　　　|-wife.c</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　　　|-daughter.c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-main.c</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　　　|-wife.h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-daughter.h</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">　　　　　|-Makefile.am</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">&#8251;说明:</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">1. configure.in　这是最重要的文档，整个安装过程都靠它来主导。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">2. Makefile.am　automake会根据它来生成Makefile.in，再由./configure Makefile.in变成最终的Makefile，一般来说在顶级目录和各个子目录都应该有一个Makefile.am</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">3. wife.c daughter.c main.c wife.h daughter.h　这是我们的源程序。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">不用细看，这些文件除了configure.in是用模板创建手动编辑外，其他都是手动创建并编辑的，如果你还木有，动手吧。其实这里边有个小小的经验，也不一定是对的，只是个人的经验，也就是后缀名为in的文件是生成的模板。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ mkdir &#8211;p Family/src</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ touch Makefile.am</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ cd src</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ touch wife.c daughter.c main.c wife.h daughter.h Makefile.am</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ cd ..&nbsp; 进入刚创建的Family目录</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ autoscan 该命令产生 configure.scan 和 configure.log两个文件，然后</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">$ mv configure.scan configure.i n这样configure.in就创建成了。</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">&#8251;源代码内容：</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; "><strong>main.c:</strong>&nbsp;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include &lt;stdio.h&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include "wife.h"</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include "daughter.h"</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#ifdef HAVE_CONFIG_H</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include &lt;config.h&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#endif</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">int main(void)</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">{</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">printf( "These are my girls\n");</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">daughter_say();</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">wife_say();</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">return 0;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">}</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; "><strong>daughter.c</strong></p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include &lt;stdio.h&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include "daughter.h"</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#ifdef HAVE_CONFIG_H</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include &lt;config.h&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#endif</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">void daughter_say(void)</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">{</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">printf("My Dad ,are you call me ?\n");</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">}</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; "><strong>daughter.h</strong></p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#ifndef _DAUGHTER_</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#define _DAUGHTER_</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">void daughter_say(void);</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#endif</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; "><strong>wife.c</strong></p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include &lt;stdio.h&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include "wife.h"</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#ifdef HAVE_CONFIG_H</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#include &lt;config.h&gt;</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#endif</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">void wife_say(void)</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">{</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">printf("My darling ,are you call me ?\n");</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">}</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; "><strong>wife.h</strong></p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#ifndef _WIFE_</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#define _WIFE_</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">void wife_say(void);</p><p style="color: #333333; font-family: tahoma, 宋体; line-height: 22px; background-color: #efefef; ">#endif<br /><p>&#8251;制作流程：</p><p>第1步：编辑configure.in文件。</p><p>上面用autoscan生成的scan后缀的文件改名而成的configure.in文件，我的用autoconf版本是2.66，貌似autoscan自动生成的模板2.61之前与之后的不大一样，这点可以自己参照自己的版本修改，2.61以后的版本这个文件更简单了。</p><p>打开看看：&nbsp; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -*- Autoconf -*-</p><p># Process this file with autoconf to produce a configure script.</p><p>AC_PREREQ([2.66])</p><p>AC_INIT([family], [1.0], [804927399@qq.com])</p><p>AM_INIT_AUTOMAKE(family,1.0)</p><p>AC_CONFIG_SRCDIR([src/wife.c])</p><p>AC_CONFIG_HEADERS([config.h])</p><p># Checks for programs.</p><p>AC_PROG_CC</p><p># Checks for libraries.</p><p># Checks for header files.</p><p># Checks for typedefs, structures, and compiler characteristics.</p><p># Checks for library functions.</p><p>AC_CONFIG_FILES([Makefile</p><p>src/Makefile])</p><p>AC_OUTPUT</p><p>configure.in 未修改版，简单对上面进行说明：</p><p>AC_PREREQ([2.66])这个宏是用来检测autoconf的版本的。</p><p>AC_INIT（）是个初始化宏，括号中内容分别为：要生成的软件名称，版本号，bug报告邮箱</p><p>AM_INIT_AUTOMAKE(family,1.0)这个宏是新添加的，不过好像1.8的automake不用添加这个也可以，但是我没有添加的时候在后面make的时候会有&#8220;Makefile:15: *** 遗漏分隔符 。 停止。&#8221;的问题，而加上则有警告。现在还真有点晕呼呼滴。</p><p>AC_CONFIG_SRCDIR([src/wife.c])这个宏是用来检测源码目录的有效性，srcdir就可以看出来，括号里边的文件不一定非得是wife.c，也可以改成其他的。</p><p>AC_CONFIG_HEADERS([config.h])这个宏用来生成标准的config.h文件。</p><p>接下来的内容就是众多的check了</p><p>AC_PROG_CC这个是检测编译器的宏。</p><p>我们用的版本不用AC_OUTPUT输出了，还是比较省力的。</p><p>第2步：aclocal命令生成aclocal.m4文件</p><p>不知为何，我直接用命令：</p><p>$aclocal 命令总是出错：aclocal</p><p>aclocal: couldn't open directory `/usr/local/share/aclocal-': 没有那个文件或目录。</p><p>最后还是加上绝对路径/usr/bin/aclocal总算是没这个错误，生成aclocal.m4了。</p><p>第3步：autoconf命令生成 configure文件</p><p>这一步没什么难度，输入命令：</p><p>$ autoconf 就ok了，autoconf可以根据configure.in和aclocal.m4生成大名鼎鼎的configure，这时候已经可以运行它了，但是会报错，因为Makefile.in还没出现。</p><p>那么何为M4呢，M4的名称取自Macro（M后面跟4个字母&#8230;）。它和C预处理器里的宏是一个概念（其实，M4和C预处理器都K&amp;R操刀设计的！！），用来处理文本替换。也就是说，M4是bash里的预处理器。</p><p>第4步：autoheader命令生成config.h.in</p><p>$ autoheader通过autoheader命令，我们就可以得到config.h.in这个东东了。有了它，./configure才会生成config.h这个东东，所以不可大意。</p><p>autoheader这个工具通常会从&#8220;acconfig.h&#8221;文件中复制用户附加的符号定义，因此此处没有附加符号定义，所以不需要创建&#8220;acconfig.h&#8221;文件。</p><p>第5步：编辑Makefile.am文件</p><p>我们再编译安装源码包的时候都知道./configure可以生成Makefile，殊不知要生成Makefile还全仰仗Makefile.in这个老东西，而这个东西是以in结尾的 ，也是个模板，是由Makefile.am生成的，好了，知道这个来龙去脉了，就着手编写Makefile.am，我们这里Family顶级目录与子目录各有一个，如果还有其他的子目录，理论上也是需要Makefile.am的。我们这就来编辑它：</p><p>Family/Makefile.am内容如下：</p><p>AUTOMAKE_OPTIONS = foreign</p><p>SUBDIRS = src</p><p>Family/src/Makefile.am内容如下：</p><p>AUTOMAKE_OPTIONS = foreign</p><p>bin_PROGRAMS = family</p><p>family_SOURCES = main.c wife.c daughter.c wife.h daughter.h</p><p>其中的AUTOMAKE_OPTIONS为设置automake的选项。由于GNU对自己发布的软件有严格的规范，比如必须附带许可证声明文件COPYING等，否则automake执行时会报错。automake提供了三种软件等级：foreign、gnu和gnits，让用 户选择采用，默认等级为gnu。在本例使用foreign等级，它只检测必须的文件，而不用检查README啊什么的。</p><p>bin_PROGRAMS定义要产生的执行文件名。如果要产生多个执行文件，每个文件名用空格隔开。</p><p>family_SOURCES定义&#8220;family&#8221;这个执行程序所需要的原始文件。如果&#8221;family&#8221;这个程序是由多个原始文件所产生的，则必须把它所用到的所有原 始文件都列出来，并用空格隔开。如果源文件名字太长，可以加上&#8221;\&#8221;行连接符换行书写。</p><p>第6步：automake --add-missing命令生成config.h.in</p><p>$ automake &#8211;a或者 automake -&#8211;add-missing，大功告成！</p><p>注意运行automake命令时一定要加参数，否则不会自动生成install.sh，missing等脚本，这样会出乱子滴。</p><p>这样，源码安装包就制作成了，用tar打包就可以了，使用的时候用三部曲./configure,make ， make install安装即可，帅吧！</p></p><img src ="http://www.blogjava.net/xiaomage234/aggbug/392204.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2012-11-29 15:48 <a href="http://www.blogjava.net/xiaomage234/archive/2012/11/29/392204.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RabbitMQ 管理指南(添加虚拟host)</title><link>http://www.blogjava.net/xiaomage234/archive/2012/11/28/392141.html</link><dc:creator>小马歌</dc:creator><author>小马歌</author><pubDate>Wed, 28 Nov 2012 07:43:00 GMT</pubDate><guid>http://www.blogjava.net/xiaomage234/archive/2012/11/28/392141.html</guid><wfw:comment>http://www.blogjava.net/xiaomage234/comments/392141.html</wfw:comment><comments>http://www.blogjava.net/xiaomage234/archive/2012/11/28/392141.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xiaomage234/comments/commentRss/392141.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xiaomage234/services/trackbacks/392141.html</trackback:ping><description><![CDATA[<span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">翻译: bobning</span><strong style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">编译和安装</strong><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">ubuntu或debian下的安装非常简单</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># apt-get install rabbitmq-server</span><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong>默认的数据库内容<br /></strong>当第一次启动服务，检测数据库是否未初始化或者被删除，它会用下面的资源初始化一个新的数据库:</p><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">一个命名为 / 的虚拟宿主一个名为guest密码也为guest的用户，他拥有/虚拟宿主的所有权限如果你的中间件是公开访问的，最好修改guest用户的密码。</span><strong style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">管理概观</strong><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">rabbitmqctl 是RabbitMQ中间件的一个命令行管理工具。它通过连接一个中间件节点执行所有的动作。本地节点默认被命名为&#8221;rabbit&#8221;。可以通过这个命令前使 用&#8221;-n&#8221;标志明确的指定节点名称, 例如:# rabbitmqctl -n rabbit@shortstop add_user tonyg changeit</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">这个命令指示RabbitMQ中间件在rabbit@shortstop 节点创建一个tonyg/changeit的用户。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在一个名为&#8221;server.example.com&#8221;的主机，RabbitMQ Erlang节点的名称通常是rabbit@server(除非</span><strong style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">RABBITMQ_NODENAM</strong><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">在 中间件启动时候被设置)。hostnam -s 的输出通常是&#8221;@&#8221;符号正确的后缀。rabbitmqctl 默认产生详细输出。通过&#8221;-q&#8221;标示可选择安静模式。rabbitmqctl -q status</span><strong style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">应用和集群管理</strong><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">1.停止RabbitMQ应用，关闭节点</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl stop</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">2.停止RabbitMQ应用</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl stop_app</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">3.启动RabbitMQ应用</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl start_app</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">4.显示RabbitMQ中间件各种信息</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl status</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">5.重置RabbitMQ节点</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl reset</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl force_reset</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">从它属于的任何集群中移除，从管理数据库中移除所有数据，例如配置过的用户和虚拟宿主, 删除所有持久化的消息。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">force_reset命令和reset的区别是无条件重置节点，不管当前管理数据库状态以及集群的配置。如果数据库或者集群配置发生错误才使用这个最后 的手段。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">注意：只有在停止RabbitMQ应用后，reset和force_reset才能成功。</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">6.循环日志文件</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">#&nbsp;rabbitmqctl rotate_logs</span><em style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">[suffix]</em><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">7.集群管理</span><br style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; " /><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "># rabbitmqctl cluster&nbsp;</span><em style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">clusternode</em><em style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&#8230;</em><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong>用户管理</strong><br />1.添加用户<br /># rabbitmqctl add_user username password<br />2.删除用户<br /># rabbitmqctl delete_user username<br />3.修改密码<br /># rabbitmqctl change_password username newpassword<br />4.列出所有用户<br /># rabbitmqctl list_users</p><strong style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">权限控制</strong><strong style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">1.创建虚拟主机<br /># rabbitmqctl add_vhost vhostpath<br />2.删除虚拟主机<br /># rabbitmqctl delete_vhost vhostpath<br />3.列出所有虚拟主机<br /># rabbitmqctl list_vhosts<br />4.设置用户权限<br /># rabbitmqctl set_permissions [-p vhostpath] username regexp regexp regexp<br />5.清除用户权限<br /># rabbitmqctl clear_permissions [-p vhostpath] username<br />6.列出虚拟主机上的所有权限<br /># rabbitmqctl list_permissions [-p vhostpath]<br />7.列出用户权限<br /></strong><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; "><strong># rabbitmqctl list_user_permissions username</strong></p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">&nbsp;</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">例子：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">添加&nbsp; rabbitmqctl add_vhost az</p><span style="color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; background-color: #ffffff; ">rabbitmqctl set_permissions -p az guest ".*" ".*" ".*"</span>&nbsp;<img src ="http://www.blogjava.net/xiaomage234/aggbug/392141.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xiaomage234/" target="_blank">小马歌</a> 2012-11-28 15:43 <a href="http://www.blogjava.net/xiaomage234/archive/2012/11/28/392141.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>