<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<channel>
<title>成刚网志 &amp;amp;&amp;amp; CBolg Application</title>
<link>http://www.chenggang.net</link>
<description><![CDATA[记录我的网事历程，架起沟通的桥梁！欢迎留言！
]]></description>
<lastBuildDate>Sun, 05 Feb 2012 11:14:25 +0800</lastBuildDate>
<copyright>Copyright &amp;copy; 2012 by CBolg Application.</copyright>
<language>zh-cn</language>
<pubDate>Thu, 23 Feb 2012 03:17:59 +0800</pubDate>
<item>
<title>土豆泥的11种做法</title>
<summary><![CDATA[土豆泥的做法一： 1、选6到8个样子还算可爱的小土豆，削皮洗净，放入水里煮半小时左右，水里放少许盐。 差不多时用筷子试探，能很轻松的戳到内部就说明可以了。 2、把土豆捞出，沥干水，放入一个大碗中，用合适的工具（偶是用的*子，不算合适，不 过勉强来用）搅阿搅，把土豆搅碎。 3、放入适量的牛奶和黄油或者奶酪，（注意牛奶不要放的太冲动，容易把土豆泥弄稀）再继续的搅，直到搅匀并且成泥状为之。嘿嘿，然后就可以吃啦。 土豆泥的做法二： 1、同做法一的第一个步骤。 2、同做法一第二个步骤。 3、准备好肉丁，香菇丁，黄…]]></summary>
<description><![CDATA[<p>
	<strong>土豆泥的做法一：</strong><br />
	1、选6到8个样子还算可爱的小土豆，削皮洗净，放入水里煮半小时左右，水里放少许盐。<br />
	差不多时用筷子试探，能很轻松的戳到内部就说明可以了。<br />
	2、把土豆捞出，沥干水，放入一个大碗中，用合适的工具（偶是用的*子，不算合适，不<br />
	过勉强来用）搅阿搅，把土豆搅碎。<br />
	3、放入适量的牛奶和黄油或者奶酪，（注意牛奶不要放的太冲动，容易把土豆泥弄稀）再继续的搅，直到搅匀并且成泥状为之。嘿嘿，然后就可以吃啦。</p>
<p>
	<strong>土豆泥的做法二：</strong></p>
<p>
	1、同做法一的第一个步骤。<br />
	2、同做法一第二个步骤。<br />
	3、准备好肉丁，香菇丁，黄瓜丁，西红柿丁。<br />
	4、倒油入锅，油热后倒入肉丁和香菇丁，翻炒一下，然后将搅拌好的土豆泥倒进去炒，炒的时候放少量酱油，5分钟以后倒入黄瓜丁和西红柿丁，继续翻炒，直到调料搅拌匀了，就ok了。</p>
<p>
	<strong>土豆泥的做法三：</strong><br />
	把土豆削皮切块，放开水里加点盐用中火煮到软透，沥干水分后放入大碗或汤锅里。加少许黑胡椒粉。加牛奶（可先加一点儿，等搅拌时如觉得太干再多加点儿）。加融化的黄油（如怕胆固醇高，可用MARGARINE代替。加多少跟据个人喜好。多一点香一些。我一般4，5个中型土豆加1/2 cup 黄油。市售的黄油通常每盒四块，每块1/2 cup）。 接下来搅拌。最好是用FOOD MIXER。最简单的那种手提电熨斗状的就行。便宜的10美元就能买到。实在没有，人工搅也行，只是既辛苦又不一定搅得细腻。搅到土豆完全成泥状就行了。 吃土豆泥一定要浇GRAVY才好吃。超市里有卖GRAVY MIX。美国人吃土豆泥都是配肉类。家里不论是烤火鸡，还是烧牛肉，鸡翅，都会有汤汁。把汤汁加盐勾浓芡，就是美味的自制GRAVY。喜欢吃绿色蔬菜的，可以把冻豌豆（SWEET PEA）加少许白糖煮熟，加在土豆泥上再浇GRAVY吃。</p>
<p>
	<strong>土豆泥的做法四：&nbsp;</strong></p>
<p>
	1、先将土豆洗净，煮熟后剥皮(可用微波高火)，放在容器里弄碎成泥(可用牛排捶压碎)。<br />
	2、准备肉末若干（5个鸡蛋大小的土豆需要1-2两肉末），胡萝卜、黄瓜适量，切成末末。<br />
	3、将少量油烧热，先将肉末炒熟，然后依次放入胡萝卜、黄瓜末，炒一分钟后，再将土豆泥毛坯放入拌匀，并放入适量的盐（要少放）。<br />
	4、趁热吃。吃不完可以冷藏，下次吃前放微波炉加热。</p>
<p>
	<strong>土豆泥的做法五：</strong><br />
	土豆两个（小一点，个头圆一些）；鸡蛋一个;少许胡萝卜，芹菜，洋葱；牛奶；色拉酱<br />
	为了节约火，可以将土豆和鸡蛋一起煮，当鸡蛋煮熟后，先取出，土豆煮得非常烂时，取出，去皮，弄成泥状。<br />
	将胡萝卜，芹菜，洋葱，鸡蛋切碎，很碎的那种，放入土豆泥中，因为土豆泥比较干，就倒入一些牛奶起到滋润作用，接着拌入色拉酱（不要甜味的），再洒一下黑胡椒粉即可。如果个人口味喜欢还可以自己再放点东东啦。只要自己喜欢就好。</p>
<p>
	<strong>土豆泥的做法六：</strong><br />
	1、先用水把土豆洗干净。<br />
	2、用清水将土豆煮熟。然后剥皮。(注意水要沥干喽)<br />
	3、把青椒切成碎末。<br />
	4、先把油烧得半热，将青椒和肉末炒熟然后再把土豆放进去，用锅铲将土豆踏成泥(煮熟的土豆很容易成泥状)。<br />
	5、多炒一会，然后加盐、鸡精。看到土豆泥呈金黄色就可以起锅啦。<br />
	啧啧，香香的，大家试一下吧。</p>
<p>
	<strong>土豆泥的做法七：</strong><br />
	韩式做法是土豆擦细丝/加少许面粉和水混合，放盐糖拌匀/然后在平底锅里煎/当然这是我凭口感想象的/总之韩式的做法绝对是擦细丝，而不是压成土豆泥</p>
<p>
	<strong>土豆泥的做法八：</strong><br />
	原料：土豆一斤左右。<br />
	配料：花生油100克、盐5克、香葱100克、鲜奶少许<br />
	做法：<br />
	1、土豆蒸熟后切成豆土丝，越细越好哦，与鲜奶盐拌匀腌20分钟。香葱切成葱花。<br />
	2、平底锅烧旺（最好是不沾锅）加油转中火，将100克左右的土豆丝到入锅中用平铲压成5mm的圆饼，要压实。一面煎黄后小心翻到另一面，两面煎黄后又面撒入葱花，一这要把葱花压入饼内才好吃，待两面焦黄色即可。上桌后可依各人的口味加入椒盐或番茄酱，其实什么都不加更好吃。</p>
<p>
	<strong>土豆泥的做法九：</strong><br />
	没有研究正规的做法，想到什么放什么<br />
	材料：<br />
	600g土豆；250g肉末；50芝士；20g牛油；蛋黄一个；生粉、盐、糖、牛奶少许<br />
	做法：<br />
	土豆煮熟后捣成泥，拌入肉末芝士牛油蛋黄生粉盐糖及牛奶搅拌均匀，弄成小圆块（不能太硬太干，不然口感不好），放入平底锅小火煎熟即可一口下去，满嘴喷香啊！呵呵～～～</p>
<p>
	<strong>土豆泥的做法十：</strong></p>
<p>
	1、先将土豆洗净，去皮，切成丝状.然后撒盐拌均匀.<br />
	2、洗几根小香葱，切成碎茉.<br />
	3、将油烧热后，将土豆丝到入锅里，立即均匀铺开.（油要多一点，不然就会巴锅了）<br />
	4、可以用锅铲轻轻的铲一下，看看有没有糊，有没有粘在一起.<br />
	5、等土豆已经成饼状并可以转动时，就将土豆翻面，直到2边都炕成金黄色时，可以随意的翻面时，便将香葱撒在正反2面，小火炕一会儿<br />
	6、等香葱粘在土豆饼上时就大功告成了！~ 如果还想颜色更加诱人，还可以加上胡罗卜丁！</p>
<p>
	<strong>土豆泥的做法十一：</strong><br />
	西餐做法，可加洋葱丝，火腿丝，培根丝，蛋黄，生粉，面粉盐，李派林，黑椒碎，调味，土豆是切丝，原料全部抓匀，用手略成型煎熟，也可以最简单的是用雀巢薯粉加煮开的牛奶，牛油，白胡椒粉，盐，凉一点加蛋黄，搅匀，做法多样，也有人加番茜碎等等。</p>
]]></description>
<link>http://www.chenggang.net/posts/114</link>
<pubDate>Wed, 04 Jan 2012 22:35:52 +0800</pubDate>
<author>admin</author>
<category>默认分类</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/114</guid>
</item>
<item>
<title>Yii中优化ActiveRecord的relation model取值</title>
<summary><![CDATA[AcivRcd的lin定义相关的类，可以很方便的取到相应的值。 比如： cl U xnd CAcivRcd{ublic funcin lin(){un y(gu = y(lf::BELONGS_TO, Gu, gu_id),);}} 可以很通过$u-gu获取Gu的实例化类，但是问题随之而来，如果gu这个表很大，对应的字段很多，CAcivRcd在取值的时候会…]]></summary>
<description><![CDATA[<p>
	ActiveRecord的relations定义相关的类，可以很方便的取到相应的值。</p>
<p>
	比如：</p>
<pre class="brush:php;" title="code">
class User extends CActiveRecord
{
	public function relations()
	{
		return array(
			&#39;group&#39; =&gt; array(self::BELONGS_TO, &#39;Group&#39;, &#39;group_id&#39;),
		);
	}
}
</pre>
<p>
	可以很通过$user-&gt;group获取Group的实例化类，但是问题随之而来，如果group这个表很大，对应的字段很多，CActiveRecord在取值的时候会把这些值都取出来，可是往往我们需要的仅仅是其中的一两个字段而已，这就需要在with的时候设置select信息。</p>
<p>
	如果这样设置：</p>
<pre class="brush:php;" title="code">
$criteria = new CDbCriteria();
$criteria-&gt;distinct     = true;
$criteria-&gt;select = &quot; t.* &quot;;
$criteria-&gt;condition = &quot; 1=1 &quot;;
$criteria-&gt;with         = array(&#39;teacher&#39;=&gt;
array(&#39;select&#39;=&gt;&#39;username,company_id&#39;,
 &#39;order&#39;=&gt;&#39;teacher.username ASC&#39;)
);
</pre>
<p>
	这样才能减少载入的字段。</p>
<p>
	试想，如果通过方法实例化本类的时候通过defaultScope()方法获取字段，with相关类的时候只取我们需要的字段就好多了，Yii可以！</p>
]]></description>
<link>http://www.chenggang.net/posts/112</link>
<pubDate>Wed, 21 Dec 2011 18:13:09 +0800</pubDate>
<author>admin</author>
<category>Web进阶</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/112</guid>
</item>
<item>
<title>8种Nosql数据库系统对比 </title>
<summary><![CDATA[导读：Kif Kvc 是一位软件架构师和咨询顾问，他最近发布了一片对比各种类型NSQL数据库的 文章 。 虽然SQL数据库是非常有用的工具，但经历了15年的一支独秀之后垄断即将被打破。这只是时间问题：被迫使用关系数据库，但最终发现不能适应需求的情况不胜枚举。 但是NSQL数据库之间的不同，远超过两 SQL数据库之间的差别。这意味着软件架构师更应该在项目开始时就选择好一个适合的 NSQL数据库。针对这种情况，这里对 Cnd 、 Mngdb 、 CuchDB 、 Rdi…]]></summary>
<description><![CDATA[<p>
	导读：Krist&oacute;f Kov&aacute;cs 是一位软件架构师和咨询顾问，他最近发布了一片对比各种类型NoSQL数据库的<a href="http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis" rel="nofollow" target="_blank">文章</a>。<br />
	<br />
	　　虽然SQL数据库是非常有用的工具，但经历了15年的一支独秀之后垄断即将被打破。这只是时间问题：被迫使用关系数据库，但最终发现不能适应需求的情况不胜枚举。<br />
	<br />
	　　但是NoSQL数据库之间的不同，远超过两 SQL数据库之间的差别。这意味着软件架构师更应该在项目开始时就选择好一个适合的 NoSQL数据库。针对这种情况，这里对 <a href="http://cassandra.apache.org/" rel="nofollow" target="_blank">Cassandra</a>、 <a href="http://www.mongodb.org/" rel="nofollow" target="_blank">Mongodb</a>、<a href="http://couchdb.apache.org/" rel="nofollow" target="_blank">CouchDB</a>、<a href="http://redis.io/" rel="nofollow" target="_blank">Redis</a>、 <a href="http://www.basho.com/Riak.html" rel="nofollow" target="_blank">Riak</a>、 <a href="http://www.couchbase.org/membase" rel="nofollow" target="_blank">Membase</a>、<a href="http://neo4j.org/" rel="nofollow" target="_blank">Neo4j</a>和<a href="http://hbase.apache.org/" rel="nofollow" target="_blank">HBase</a>进行了比较：<br />
	<br />
	　　（编注1：NoSQL：是一项全新的数据库革命性运动，NoSQL的拥护者们提倡运用非关系型的数据存储。现今的计算机体系结构在数据存储方面要求具 备庞大的水平扩 展性，而NoSQL致力于改变这一现状。目前Google的 BigTable 和Amazon 的Dynamo使用的就是NoSQL型数据库。 参见<a href="http://zh.wikipedia.org/zh/NoSQL" rel="nofollow" target="_blank">NoSQL词条</a>。）<br />
	<br />
	　　<b>1. CouchDB</b></p>
<ul>
	<li>
		所用语言： Erlang</li>
	<li>
		特点：DB一致性，易于使用</li>
	<li>
		使用许可： Apache</li>
	<li>
		协议： HTTP/REST</li>
	<li>
		双向数据复制，</li>
	<li>
		持续进行或临时处理，</li>
	<li>
		处理时带冲突检查，</li>
	<li>
		因此，采用的是master-master复制（见编注2）</li>
	<li>
		MVCC - 写操作不阻塞读操作</li>
	<li>
		可保存文件之前的版本</li>
	<li>
		Crash-only（可靠的）设计</li>
	<li>
		需要不时地进行数据压缩</li>
	<li>
		视图：嵌入式 映射/减少</li>
	<li>
		格式化视图：列表显示</li>
	<li>
		支持进行服务器端文档验证</li>
	<li>
		支持认证</li>
	<li>
		根据变化实时更新</li>
	<li>
		支持附件处理</li>
	<li>
		因此， CouchApps（独立的 js应用程序）</li>
	<li>
		需要 jQuery程序库</li>
</ul>
<br />
<p>
	　　<b>最佳应用场景：</b>适用于数据变化较少，执行预定义查询，进行数据统计的应用程序。适用于需要提供数据版本支持的应用程序。<br />
	<br />
	　　<b>例如：</b> CRM、CMS系统。 master-master复制对于多站点部署是非常有用的。<br />
	<br />
	　　（编注2：master-master复制：是一种数据库同步方法，允许数据在一组计算机之间共享数据，并且可以通过小组中任意成员在组内进行数据更新。）<br />
	<br />
	　　<b>2. Redis</b></p>
<ul>
	<li>
		所用语言：C/C++</li>
	<li>
		特点：运行异常快</li>
	<li>
		使用许可： BSD</li>
	<li>
		协议：类 Telnet</li>
	<li>
		有硬盘存储支持的内存数据库，</li>
	<li>
		但自2.0版本以后可以将数据交换到硬盘（注意， 2.4以后版本不支持该特性！）</li>
	<li>
		Master-slave复制（见编注3）</li>
	<li>
		虽然采用简单数据或以键值索引的哈希表，但也支持复杂操作，例如 ZREVRANGEBYSCORE。</li>
	<li>
		INCR &amp; co （适合计算极限值或统计数据）</li>
	<li>
		支持 sets（同时也支持 union/diff/inter）</li>
	<li>
		支持列表（同时也支持队列；阻塞式 pop操作）</li>
	<li>
		支持哈希表（带有多个域的对象）</li>
	<li>
		支持排序 sets（高得分表，适用于范围查询）</li>
	<li>
		Redis支持事务</li>
	<li>
		支持将数据设置成过期数据（类似快速缓冲区设计）</li>
	<li>
		Pub/Sub允许用户实现消息机制</li>
</ul>
<p>
	　　<b>最佳应用场景：</b>适用于数据变化快且数据库大小可遇见（适合内存容量）的应用程序。<br />
	<br />
	　　<b>例如：</b>股票价格、数据分析、实时数据搜集、实时通讯。<br />
	<br />
	　　（编注3：Master-slave复制：如果同一时刻只有一台服务器处理所有的复制请求，这被称为 Master-slave复制，通常应用在需要提供高可用性的服务器集群。）<br />
	<br />
	　　<b>3. MongoDB</b></p>
<ul>
	<li>
		所用语言：C++</li>
	<li>
		特点：保留了SQL一些友好的特性（查询，索引）。</li>
	<li>
		使用许可： AGPL（发起者： Apache）</li>
	<li>
		协议： Custom, binary（ BSON）</li>
	<li>
		Master/slave复制（支持自动错误恢复，使用 sets 复制）</li>
	<li>
		内建分片机制</li>
	<li>
		支持 javascript表达式查询</li>
	<li>
		可在服务器端执行任意的 javascript函数</li>
	<li>
		update-in-place支持比CouchDB更好</li>
	<li>
		在数据存储时采用内存到文件映射</li>
	<li>
		对性能的关注超过对功能的要求</li>
	<li>
		建议最好打开日志功能（参数 --journal）</li>
	<li>
		在32位操作系统上，数据库大小限制在约2.5Gb</li>
	<li>
		空数据库大约占 192Mb</li>
	<li>
		采用 GridFS存储大数据或元数据（不是真正的文件系统）</li>
</ul>
<p>
	　　<b>最佳应用场景：</b>适用于需要动态查询支持；需要使用索引而不是 map/reduce功能；需要对大数据库有性能要求；需要使用 CouchDB但因为数据改变太频繁而占满内存的应用程序。<br />
	<br />
	　　<b>例如：</b>你本打算采用 MySQL或 PostgreSQL，但因为它们本身自带的预定义栏让你望而却步。</p>
<p>
	<b>4. Riak</b></p>
<br />
<ul>
	<li>
		所用语言：Erlang和C，以及一些Javascript</li>
	<li>
		特点：具备容错能力</li>
	<li>
		使用许可： Apache</li>
	<li>
		协议： HTTP/REST或者 custom binary</li>
	<li>
		可调节的分发及复制(N, R, W)</li>
	<li>
		用 JavaScript or Erlang在操作前或操作后进行验证和安全支持。</li>
	<li>
		使用JavaScript或Erlang进行 Map/reduce</li>
	<li>
		连接及连接遍历：可作为图形数据库使用</li>
	<li>
		索引：输入元数据进行搜索（1.0版本即将支持）</li>
	<li>
		大数据对象支持（ Luwak）</li>
	<li>
		提供&ldquo;开源&rdquo;和&ldquo;企业&rdquo;两个版本</li>
	<li>
		全文本搜索，索引，通过 Riak搜索服务器查询（ beta版）</li>
	<li>
		支持Masterless多站点复制及商业许可的 SNMP监控</li>
</ul>
<p>
	　　最佳应用场景：适用于想使用类似 Cassandra（类似Dynamo）数据库但无法处理 bloat及复杂性的情况。适用于你打算做多站点复制，但又需要对单个站点的扩展性，可用性及出错处理有要求的情况。<br />
	<br />
	　　例如：销售数据搜集，工厂控制系统；对宕机时间有严格要求；可以作为易于更新的 web服务器使用。<br />
	<br />
	　　<b>5. Membase</b></p>
<ul>
	<li>
		所用语言： Erlang和C</li>
	<li>
		特点：兼容 Memcache，但同时兼具持久化和支持集群</li>
	<li>
		使用许可： Apache 2.0</li>
	<li>
		协议：分布式缓存及扩展</li>
	<li>
		非常快速（200k+/秒），通过键值索引数据</li>
	<li>
		可持久化存储到硬盘</li>
	<li>
		所有节点都是唯一的（ master-master复制）</li>
	<li>
		在内存中同样支持类似分布式缓存的缓存单元</li>
	<li>
		写数据时通过去除重复数据来减少 IO</li>
	<li>
		提供非常好的集群管理 web界面</li>
	<li>
		更新软件时软无需停止数据库服务</li>
	<li>
		支持连接池和多路复用的连接代理</li>
</ul>
<br />
<p>
	　　<b>最佳应用场景：</b>适用于需要低延迟数据访问，高并发支持以及高可用性的应用程序<br />
	<br />
	　　例如：低延迟数据访问比如以广告为目标的应用，高并发的 web 应用比如网络游戏（例如 Zynga）<br />
	<br />
	　　<b>6. Neo4j</b><br />
	&nbsp;</p>
<ul>
	<li>
		所用语言： Java</li>
	<li>
		特点：基于关系的图形数据库</li>
	<li>
		使用许可： GPL，其中一些特性使用 AGPL/商业许可</li>
	<li>
		协议： HTTP/REST（或嵌入在 Java中）</li>
	<li>
		可独立使用或嵌入到 Java应用程序</li>
	<li>
		图形的节点和边都可以带有元数据</li>
	<li>
		很好的自带web管理功能</li>
	<li>
		使用多种算法支持路径搜索</li>
	<li>
		使用键值和关系进行索引</li>
	<li>
		为读操作进行优化</li>
	<li>
		支持事务（用 Java api）</li>
	<li>
		使用 Gremlin图形遍历语言</li>
	<li>
		支持 Groovy脚本</li>
	<li>
		支持在线备份，高级监控及高可靠性支持使用 AGPL/商业许可</li>
</ul>
<br />
<p>
	　　<b>最佳应用场景：</b>适用于图形一类数据。这是 Neo4j与其他nosql数据库的最显著区别<br />
	<br />
	　　例如：社会关系，公共交通网络，地图及网络拓谱<br />
	<br />
	　　<b>7. Cassandra</b><br />
	&nbsp;</p>
<ul>
	<li>
		所用语言： Java</li>
	<li>
		特点：对大型表格和 Dynamo支持得最好</li>
	<li>
		使用许可： Apache</li>
	<li>
		协议： Custom, binary (节约型)</li>
	<li>
		可调节的分发及复制(N, R, W)</li>
	<li>
		支持以某个范围的键值通过列查询</li>
	<li>
		类似大表格的功能：列，某个特性的列集合</li>
	<li>
		写操作比读操作更快</li>
	<li>
		基于 Apache分布式平台尽可能地 Map/reduce</li>
	<li>
		我承认对 Cassandra有偏见，一部分是因为它本身的臃肿和复杂性，也因为 Java的问题（配置，出现异常，等等）</li>
</ul>
<p>
	　　<b>最佳应用场景：</b>当使用写操作多过读操作（记录日志）如果每个系统组建都必须用 Java编写（没有人因为选用 Apache的软件被解雇）<br />
	<br />
	　　例如：银行业，金融业（虽然对于金融交易不是必须的，但这些产业对数据库的要求会比它们更大）写比读更快，所以一个自然的特性就是实时数据分析</p>
<p>
	<b>8. HBase</b><br />
	<br />
	　　（配合 ghshephard使用）</p>
<br />
<ul>
	<li>
		所用语言： Java</li>
	<li>
		特点：支持数十亿行X上百万列</li>
	<li>
		使用许可： Apache</li>
	<li>
		协议：HTTP/REST （支持 <a href="http://www.jobbole.com/entry.php/73" target="_blank">Thrift</a>，见编注4）</li>
	<li>
		在 BigTable之后建模</li>
	<li>
		采用分布式架构 Map/reduce</li>
	<li>
		对实时查询进行优化</li>
	<li>
		高性能 Thrift网关</li>
	<li>
		通过在server端扫描及过滤实现对查询操作预判</li>
	<li>
		支持 XML, Protobuf, 和binary的HTTP</li>
	<li>
		Cascading, hive, and pig source and sink modules</li>
	<li>
		基于 Jruby（ JIRB）的shell</li>
	<li>
		对配置改变和较小的升级都会重新回滚</li>
	<li>
		不会出现单点故障</li>
	<li>
		堪比MySQL的随机访问性能</li>
</ul>
<p>
	　　<b>最佳应用场景：</b>适用于偏好BigTable:)并且需要对大数据进行随机、实时访问的场合。<br />
	<br />
	　　例如： Facebook消息数据库（更多通用的用例即将出现）<br />
	<br />
	　　编注4：Thrift 是一种接口定义语言，为多种其他语言提供定义和创建服务，<a href="http://www.jobbole.com/entry.php/73" target="_blank">由Facebook开发并开源</a>。<br />
	<br />
	　　当然，所有的系统都不只具有上面列出的这些特性。这里我仅仅根据自己的观点列出一些我认为的重要特性。与此同时，技术进步是飞速的，所以上述的内容肯定需要不断更新。我会尽我所能地更新这个列表。</p>
<p style="text-align: right; ">
	摘至：http://article.yeeyan.org/view/271351/239915</p>
]]></description>
<link>http://www.chenggang.net/posts/111</link>
<pubDate>Thu, 15 Dec 2011 11:39:21 +0800</pubDate>
<author>admin</author>
<category>NoSQL</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/111</guid>
</item>
<item>
<title>网页布局时常犯的10个CSS和HTML错误</title>
<summary><![CDATA[1. 检查 HTML 元素是否有拼写错误、是否忘记结束标记 即使是老手也经常会弄错div的嵌套关系。可以用 dmwv 的验证功能检查一下有无错误。 2. 检查 CSS 是否书写正确 检查一下有无拼写错误、是否忘记结尾的 } 等。可以利用ClnCSS来检查 CSS的拼写错误。ClnCSS本是为CSS减肥的工具，但也能检查出拼写错误。 3. 用删除法确定错误发生的位置 如果错误影响了整体 布局 ，则可以逐个删除div块，直到删除某个div块后显示恢复正常，即可确定错误发生的位置。 4.…]]></summary>
<description><![CDATA[<p>
	&nbsp; &nbsp; &nbsp; &nbsp;1. 检查<a href="http://webdesign.jzxue.com/html/" target="_blank">HTML</a>元素是否有拼写错误、是否忘记结束标记<br />
	　　即使是老手也经常会弄错div的嵌套关系。可以用<a href="http://websoft.jzxue.com/dreamweaver/" target="_blank">dreamweaver</a>的验证功能检查一下有无错误。<br />
	<br />
	　　2. 检查<a href="http://webdesign.jzxue.com/css/" target="_blank">CSS</a>是否书写正确<br />
	　　检查一下有无拼写错误、是否忘记结尾的 } 等。可以利用CleanCSS来检查 CSS的拼写错误。CleanCSS本是为CSS减肥的工具，但也能检查出拼写错误。<br />
	<br />
	　　3. 用删除法确定错误发生的位置<br />
	　　如果错误影响了整体<a href="http://webdesign.jzxue.com/wangyebuju/" target="_blank">布局</a>，则可以逐个删除div块，直到删除某个div块后显示恢复正常，即可确定错误发生的位置。<br />
	<br />
	　　4. 利用border属性确定出错元素的布局特性<br />
	　　使用float属性布局一不小心就会出错。这时为元素添加border属性确定元素边界，错误原因即水落石出。<br />
	<br />
	　　5. float元素的父元素不能指定clear属性<br />
	　　MacIE下如果对float的元素的父元素使用clear属性，周围的float元素布局就会混乱。这是MacIE的著名的bug，倘若不知道就会走弯路。<br />
	<br />
	　　6. float元素务必指定width属性<br />
	　　很多浏览器在显示未指定width的float元素时会有bug。所以不管float元素的内容如何，一定要为其指定width属性。<br />
	　　另外指定元素时尽量使用em而不是px做单位。<br />
	<br />
	　　7. float元素不能指定margin和padding等属性<br />
	　　IE在显示指定了margin和padding的float元素时有bug。因此不要对float元素指定margin和padding属性（可以在float元素内部嵌套一个div来设置margin和padding）。也可以使用hack方法为IE指定特别的值。<br />
	<br />
	　　8. float元素的宽度之和要小于100%<br />
	　　如果float元素的宽度之和正好是100%，某些古老的浏览器将不能正常显示。因此请保证宽度之和小于99%。<br />
	<br />
	　　9. 是否重设了默认的样式？<br />
	　　某些属性如margin、padding等，不同浏览器会有不同的解释。因此最好在开发前首先将全体的margin、padding设置为0、列表样式设置为none等。<br />
	<br />
	　　10. 是否忘记了写DTD？<br />
	　　如果无论怎样调整不同浏览器显示结果还是不一样，那么可以检查一下页面开头是不是忘了写下DTD声明。</p>
<p style="text-align: right; ">
	摘至：http://www.jzxue.com/wangyesheji/wangyebuju/200909/30-2835.html</p>
]]></description>
<link>http://www.chenggang.net/posts/110</link>
<pubDate>Thu, 15 Dec 2011 10:38:44 +0800</pubDate>
<author>admin</author>
<category>默认分类</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/110</guid>
</item>
<item>
<title>Redis系统性介绍</title>
<summary><![CDATA[虽然 Rdi 已经很火了，相信还是有很多同学对Rdi只是有所听闻或者了解并不全面，下面是一个比较系统的Rdi介绍，对Rdi的特性及各种数据类型及操作进行了介绍。是一个很不错的Rdi入门教程。 1.介绍 1.1 Rdi是什么 RE m DI ciny S v(Rdi) 是一个由Slv Snfili写的ky-vlu存储系统。Rdi提供了一些丰富的数据结构，包括li, , dd  以及hh …]]></summary>
<description><![CDATA[<p>
	虽然<span class="wp_keywordlink_affiliate" style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">Redis</span>已经很火了，相信还是有很多同学对Redis只是有所听闻或者了解并不全面，下面是一个比较系统的Redis介绍，对Redis的特性及各种数据类型及操作进行了介绍。是一个很不错的Redis入门教程。</p>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	1.介绍</h3>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	1.1 Redis是什么</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	<strong style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">RE</strong>mote&nbsp;<strong style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">DI</strong>ctionary&nbsp;<strong style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">S</strong>erver(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis提供了一些丰富的数据结构，包括&nbsp;lists, sets, ordered sets 以及&nbsp;hashes ，当然还有和Memcached一样的&nbsp;strings结构.Redis当然还包括了对这些数据结构的丰富操作。</p>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	1.2 Redis的优点</h4>
<ul style="padding-bottom: 0px; margin: 0px 0px 0px 25px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		性能极高&nbsp;&ndash; Redis能支持超过 100K+ 每秒的读写频率。</li>
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		丰富的数据类型 &ndash; Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。</li>
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		原子 &ndash; Redis的所有操作都是原子性的，同时Redis还支持对几个操作全并后的原子性执行。</li>
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		丰富的特性&nbsp;&ndash; Redis还支持 publish/subscribe, 通知, key 过期等等特性。</li>
</ul>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	2.数据类型</h3>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	2.1 String类型</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis能存储二进制安全的字符串，最大长度为1GB</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; GET name
&quot;John Doe&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	String类型还支持批量的读写操作</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; MSET age 30 sex &quot;male&quot;
OK
redis 127.0.0.1:6379&gt; MGET age sex
1) &quot;30&quot;
2) &quot;male&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	String类型其实也可以用来存储数字，并支持对数字的加减操作。</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; INCR age
(integer) 31
redis 127.0.0.1:6379&gt; INCRBY age 4
(integer) 35
redis 127.0.0.1:6379&gt; GET age
&quot;35&quot;
redis 127.0.0.1:6379&gt; DECR age
(integer) 34
redis 127.0.0.1:6379&gt; DECRBY age 4
(integer) 30
redis 127.0.0.1:6379&gt; GET age
&quot;30&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	String类型还支持对其部分的修改和获取操作</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; APPEND name &quot; Mr.&quot;
(integer) 12
redis 127.0.0.1:6379&gt; GET name
&quot;John Doe Mr.&quot;
redis 127.0.0.1:6379&gt; STRLEN name
(integer) 12
redis 127.0.0.1:6379&gt; SUBSTR name 0 3
&quot;John&quot;</pre>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	2.2 List类型</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis能够将数据存储成一个链表，并能对这个链表进行丰富的操作</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; LPUSH students &quot;John Doe&quot;
(integer) 1
redis 127.0.0.1:6379&gt; LPUSH students &quot;Captain Kirk&quot;
(integer) 2
redis 127.0.0.1:6379&gt; LPUSH students &quot;Sheldon Cooper&quot;
(integer) 3
redis 127.0.0.1:6379&gt; LLEN students
(integer) 3
redis 127.0.0.1:6379&gt; LRANGE students 0 2
1) &quot;Sheldon Cooper&quot;
2) &quot;Captain Kirk&quot;
3) &quot;John Doe&quot;
redis 127.0.0.1:6379&gt; LPOP students
&quot;Sheldon Cooper&quot;
redis 127.0.0.1:6379&gt; LLEN students
(integer) 2
redis 127.0.0.1:6379&gt; LRANGE students 0 1
1) &quot;Captain Kirk&quot;
2) &quot;John Doe&quot;
redis 127.0.0.1:6379&gt; LREM students 1 &quot;John Doe&quot;
(integer) 1
redis 127.0.0.1:6379&gt; LLEN students
(integer) 1
redis 127.0.0.1:6379&gt; LRANGE students 0 0
1) &quot;Captain Kirk&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis也支持很多修改操作</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; LINSERT students BEFORE &quot;Captain Kirk&quot; &quot;Dexter Morgan&quot;
(integer) 3
redis 127.0.0.1:6379&gt; LRANGE students 0 2
1) &quot;Dexter Morgan&quot;
2) &quot;Captain Kirk&quot;
3) &quot;John Doe&quot;
redis 127.0.0.1:6379&gt; LPUSH students &quot;Peter Parker&quot;
(integer) 4
redis 127.0.0.1:6379&gt; LRANGE students 0 3
1) &quot;Peter Parker&quot;
2) &quot;Dexter Morgan&quot;
3) &quot;Captain Kirk&quot;
4) &quot;John Doe&quot;
redis 127.0.0.1:6379&gt; LTRIM students 1 3
OK
redis 127.0.0.1:6379&gt; LLEN students
(integer) 3
redis 127.0.0.1:6379&gt; LRANGE students 0 2
1) &quot;Dexter Morgan&quot;
2) &quot;Captain Kirk&quot;
3) &quot;John Doe&quot;
redis 127.0.0.1:6379&gt; LREM students 1 &quot;John Doe&quot;
(integer) 1
redis 127.0.0.1:6379&gt; LLEN students
(integer) 1
redis 127.0.0.1:6379&gt; LRANGE students 0 1
1) &quot;Captain Kirk&quot;</pre>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	2.3 集合（Sets）类型</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis能够将一系列不重复的值存储成一个集合</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SADD birds crow
(integer) 1
redis 127.0.0.1:6379&gt; SADD birds pigeon
(integer) 1
redis 127.0.0.1:6379&gt; SADD birds bat
(integer) 1
redis 127.0.0.1:6379&gt; SADD mammals dog
(integer) 1
redis 127.0.0.1:6379&gt; SADD mammals cat
(integer) 1
redis 127.0.0.1:6379&gt; SADD mammals bat
(integer) 1
redis 127.0.0.1:6379&gt; SMEMBERS birds
1) &quot;bat&quot;
2) &quot;crow&quot;
3) &quot;pigeon&quot;
redis 127.0.0.1:6379&gt; SMEMBERS mammals
1) &quot;bat&quot;
2) &quot;cat&quot;
3) &quot;dog&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Sets结构也支持相应的修改操作</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SREM mammals cat
(integer) 1
redis 127.0.0.1:6379&gt; SMEMBERS mammals
1) &quot;bat&quot;
2) &quot;dog&quot;
redis 127.0.0.1:6379&gt; SADD mammals human
(integer) 1
redis 127.0.0.1:6379&gt; SMEMBERS mammals
1) &quot;bat&quot;
2) &quot;human&quot;
3) &quot;dog&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis还支持对集合的子交并补等操作</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SINTER birds mammals
1) &quot;bat&quot;
redis 127.0.0.1:6379&gt; SUNION birds mammals
1) &quot;crow&quot;
2) &quot;bat&quot;
3) &quot;human&quot;
4) &quot;pigeon&quot;
5) &quot;dog&quot;
redis 127.0.0.1:6379&gt; SDIFF birds mammals
1) &quot;crow&quot;
2) &quot;pigeon&quot;</pre>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	2.4 有序集合（Sorted Sets）类型</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Sorted Sets和Sets结构相似，不同的是存在Sorted Sets中的数据会有一个score属性，并会在写入时就按这个score排好序。</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; ZADD days 0 mon
(integer) 1
redis 127.0.0.1:6379&gt; ZADD days 1 tue
(integer) 1
redis 127.0.0.1:6379&gt; ZADD days 2 wed
(integer) 1
redis 127.0.0.1:6379&gt; ZADD days 3 thu
(integer) 1
redis 127.0.0.1:6379&gt; ZADD days 4 fri
(integer) 1
redis 127.0.0.1:6379&gt; ZADD days 5 sat
(integer) 1
redis 127.0.0.1:6379&gt; ZADD days 6 sun
(integer) 1
redis 127.0.0.1:6379&gt; ZCARD days
(integer) 7
redis 127.0.0.1:6379&gt; ZRANGE days 0 6
1) &quot;mon&quot;
2) &quot;tue&quot;
3) &quot;wed&quot;
4) &quot;thu&quot;
5) &quot;fri&quot;
6) &quot;sat&quot;
7) &quot;sun&quot;
redis 127.0.0.1:6379&gt; ZSCORE days sat
&quot;5&quot;
redis 127.0.0.1:6379&gt; ZCOUNT days 3 6
(integer) 4
redis 127.0.0.1:6379&gt; ZRANGEBYSCORE days 3 6
1) &quot;thu&quot;
2) &quot;fri&quot;
3) &quot;sat&quot;
4) &quot;sun&quot;</pre>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	2.5 Hash类型</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis能够存储key对多个属性的数据（比如user1.uname user1.passwd）</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; HKEYS student
1) &quot;name&quot;
2) &quot;age&quot;
3) &quot;sex&quot;
redis 127.0.0.1:6379&gt; HVALS student
1) &quot;Ganesh&quot;
2) &quot;30&quot;
3) &quot;Male&quot;
redis 127.0.0.1:6379&gt; HGETALL student
1) &quot;name&quot;
2) &quot;Ganesh&quot;
3) &quot;age&quot;
4) &quot;30&quot;
5) &quot;sex&quot;
6) &quot;Male&quot;
redis 127.0.0.1:6379&gt; HDEL student sex
(integer) 1
redis 127.0.0.1:6379&gt; HGETALL student
1) &quot;name&quot;
2) &quot;Ganesh&quot;
3) &quot;age&quot;
4) &quot;30&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Hash数据结构能够批量修改和获取</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; HMSET kid name Akshi age 2 sex Female
OK
redis 127.0.0.1:6379&gt; HMGET kid name age sex
1) &quot;Akshi&quot;
2) &quot;2&quot;
3) &quot;Female&quot;</pre>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	3.Publish/Subscribe</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis支持这样一种特性，你可以将数据推到某个信息管道中，然后其它人可以通过订阅这些管道来获取推送过来的信息。</p>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	3.1 订阅信息管道</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	用一个客户端订阅管道</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SUBSCRIBE channelone
Reading messages... (press Ctrl-C to quit)
1) &quot;subscribe&quot;
2) &quot;channelone&quot;
3) (integer) 1</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	另一个客户端往这个管道推送信息</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; PUBLISH channelone hello
(integer) 1
redis 127.0.0.1:6379&gt; PUBLISH channelone world
(integer) 1</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	然后第一个客户端就能获取到推送的信息</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SUBSCRIBE channelone
Reading messages... (press Ctrl-C to quit)
1) &quot;subscribe&quot;
2) &quot;channelone&quot;
3) (integer) 1
1) &quot;message&quot;
2) &quot;channelone&quot;
3) &quot;hello&quot;
1) &quot;message&quot;
2) &quot;channelone&quot;
3) &quot;world&quot;</pre>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	3.2 按一定模式批量订阅</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	用下面的命令订阅所有channel开头的信息通道</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; PSUBSCRIBE channel*
Reading messages... (press Ctrl-C to quit)
1) &quot;psubscribe&quot;
2) &quot;channel*&quot;
3) (integer) 1</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	在另一个客户端对两个推送信息</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; PUBLISH channelone hello
(integer) 1
redis 127.0.0.1:6379&gt; PUBLISH channeltwo world
(integer) 1</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	然后在第一个客户端就能收到推送的信息</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; PSUBSCRIBE channel*
Reading messages... (press Ctrl-C to quit)
1) &quot;psubscribe&quot;
2) &quot;channel*&quot;
3) (integer) 1
1) &quot;pmessage&quot;
2) &quot;channel*&quot;
3) &quot;channelone&quot;
4) &quot;hello&quot;
1) &quot;pmessage&quot;
2) &quot;channel*&quot;
3) &quot;channeltwo&quot;
4) &quot;world&quot;</pre>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	4.数据过期设置</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis支持按key设置过期时间，过期后值将被删除（在客户端看来是补删除了的）</p>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	用TTL命令可以获取某个key值的过期时间（-1表示永不过期）</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; TTL name
(integer) -1</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	下面命令先用EXISTS命令查看key值是否存在，然后设置了5秒的过期时间</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; EXISTS name
(integer) 1
redis 127.0.0.1:6379&gt; EXPIRE name 5
(integer) 1</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	5秒后再查看</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; EXISTS name
(integer) 0
redis 127.0.0.1:6379&gt; GET name
(nil)</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	这个值已经没有了。</p>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	上在是直接设置多少秒后过期，你也可以设置在某个时间点过期，下面例子是设置2011-09-24 00:40:00过期。</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; EXPIREAT name 1316805000
(integer) 1
redis 127.0.0.1:6379&gt; EXISTS name
(integer) 0</pre>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	5.事务性</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis本身支持一些简单的组合型的命令，比如以NX结尾命令都是判断在这个值没有时才进行某个命令。</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; SETNX name &quot;Dexter Morgan&quot;
(integer) 0
redis 127.0.0.1:6379&gt; GET name
&quot;John Doe&quot;</pre>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; GETSET name &quot;Dexter Morgan&quot;
&quot;John Doe&quot;
redis 127.0.0.1:6379&gt; GET name
&quot;Dexter Morgan&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	当然，Redis还支持自定义的命令组合，通过MULTI和EXEC，将几个命令组合起来执行</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET counter 0
OK
redis 127.0.0.1:6379&gt; MULTI
OK
redis 127.0.0.1:6379&gt; INCR counter
QUEUED
redis 127.0.0.1:6379&gt; INCR counter
QUEUED
redis 127.0.0.1:6379&gt; INCR counter
QUEUED
redis 127.0.0.1:6379&gt; EXEC
1) (integer) 1
2) (integer) 2
3) (integer) 3
redis 127.0.0.1:6379&gt; GET counter
&quot;3&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	你还可以用DICARD命令来中断执行中的命令序列</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET newcounter 0
OK
redis 127.0.0.1:6379&gt; MULTI
OK
redis 127.0.0.1:6379&gt; INCR newcounter
QUEUED
redis 127.0.0.1:6379&gt; INCR newcounter
QUEUED
redis 127.0.0.1:6379&gt; INCR newcounter
QUEUED
redis 127.0.0.1:6379&gt; DISCARD
OK
redis 127.0.0.1:6379&gt; GET newcounter
&quot;0&quot;</pre>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	6.持久化</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis的所有数据都存储在内存中，但是他也提供对这些数据的持久化。</p>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	6.1 数据快照</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	数据快照的原理是将整个Redis中存的所有数据遍历一遍存到一个扩展名为rdb的数据文件中。通过SAVE命令可以调用这个过程。</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; SAVE
OK
redis 127.0.0.1:6379&gt; SET name &quot;Sheldon Cooper&quot;
OK
redis 127.0.0.1:6379&gt; BGSAVE
Background saving started</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	如果你是使用的brew在Mac OSX上安全的Redis，那么rdb文件会存在如下路径</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
/usr/local/var/db/redis/dump.rdb</pre>
<h4 style="padding-bottom: 5px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); font-size: 14px; font-weight: bold; padding-top: 0px">
	6.2 Append-Only File（追加式的操作日志记录）</h4>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis还支持一种追加式的操作日志记录，叫append only file，其日志文件以aof结局，我们一般各为aof文件。要开启aof日志的记录，你需要在配置文件中进行如下设置：</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
appendonly yes</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	这时候你所有的操作都会记录在aof日志文件中</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; GET name
(nil)
redis 127.0.0.1:6379&gt; SET name &quot;Ganesh Gunasegaran&quot;
OK
redis 127.0.0.1:6379&gt; EXIT

&rarr; cat /usr/local/var/db/redis/appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
SET
$4
name
$18
Ganesh Gunasegaran</pre>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	7.管理命令</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis支持多个DB，默认是16个，你可以设置将数据存在哪一个DB中，不同DB间的数据具有隔离性。也可以在多个DB间移动数据。</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SELECT 0
OK
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; SELECT 1
OK
redis 127.0.0.1:6379[1]&gt; GET name
(nil)
redis 127.0.0.1:6379[1]&gt; SELECT 0
OK
redis 127.0.0.1:6379&gt; MOVE name 1
(integer) 1
redis 127.0.0.1:6379&gt; SELECT 1
OK
redis 127.0.0.1:6379[1]&gt; GET name
&quot;John Doe&quot;</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis还能进行一些如下操作，获取一些运行信息</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379[1]&gt; DBSIZE
(integer) 1
redis 127.0.0.1:6379[1]&gt; INFO
redis_version:2.2.13
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:kqueue
......</pre>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis还支持对某个DB数据进行清除（当然清空所有数据的操作也是支持的）</p>
<pre style="border-left: rgb(186,189,182) 2px solid; padding-bottom: 10px; line-height: 14px; overflow-x: auto; overflow-y: auto; background-color: rgb(245,245,245); margin: 0px 0px 10px; padding-left: 10px; padding-right: 10px; color: rgb(68,68,68); font-size: 12px; padding-top: 10px">
redis 127.0.0.1:6379&gt; SET name &quot;John Doe&quot;
OK
redis 127.0.0.1:6379&gt; DBSIZE
(integer) 1
redis 127.0.0.1:6379&gt; SELECT 1
OK
redis 127.0.0.1:6379[1]&gt; SET name &quot;Sheldon Cooper&quot;
OK
redis 127.0.0.1:6379[1]&gt; DBSIZE
(integer) 1
redis 127.0.0.1:6379[1]&gt; SELECT 0
OK
redis 127.0.0.1:6379&gt; FLUSHDB
OK
redis 127.0.0.1:6379&gt; DBSIZE
(integer) 0
redis 127.0.0.1:6379&gt; SELECT 1
OK
redis 127.0.0.1:6379[1]&gt; DBSIZE
(integer) 1
redis 127.0.0.1:6379[1]&gt; FLUSHALL
OK
redis 127.0.0.1:6379[1]&gt; DBSIZE
(integer) 0</pre>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	8.客户端</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	Redis的客户端很丰富，几乎所有流行的语言都有其客户端，这里就不再赘述，有兴趣的同学可以上Redis的<a href="http://redis.io/clients" style="border-bottom: rgb(204,204,204) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" target="_blank">Clients页面</a>去查找。</p>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	9.资料引用</h3>
<ul style="padding-bottom: 0px; margin: 0px 0px 0px 25px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		<a href="http://redis.io/documentation" style="border-bottom: rgb(204,204,204) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" target="_blank">Redis documentation</a></li>
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		<a href="http://simonwillison.net/static/2010/redis-tutorial/" style="border-bottom: rgb(204,204,204) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" target="_blank">Simon Willison &ndash; Redis tutorial</a></li>
	<li style="padding-bottom: 0px; line-height: 18px; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
		<a href="http://blog.mjrusso.com/2010/10/17/redis-from-the-ground-up.html" style="border-bottom: rgb(204,204,204) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" target="_blank">Michael J. Russo &ndash; Redis from ground up</a></li>
</ul>
<h3 style="padding-bottom: 2px; line-height: 30px; margin: 0px 0px 3px; padding-left: 2px; padding-right: 2px; color: rgb(0,0,0); font-size: 18px; font-weight: bold; padding-top: 2px">
	10.总结</h3>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	<img alt="" class="alignnone" src="/upload/images/20111213/1627255950_0.png" style="border-bottom: rgb(204,204,204) 1px solid; border-left: rgb(204,204,204) 1px solid; padding-bottom: 4px; margin: 0px 0px 10px; padding-left: 4px; padding-right: 4px; display: inline; border-top: rgb(204,204,204) 1px solid; border-right: rgb(204,204,204) 1px solid; padding-top: 4px" title="Redis overview" width="600" /></p>
<p style="padding-bottom: 10px; margin: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px">
	来源：<a href="http://itsgg.com/2011/09/24/exploring-redis/" style="border-bottom: rgb(204,204,204) 1px dotted; padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; color: rgb(0,0,0); text-decoration: none; padding-top: 0px" target="_blank">itsgg.com</a></p>
]]></description>
<link>http://www.chenggang.net/posts/109</link>
<pubDate>Tue, 13 Dec 2011 16:27:25 +0800</pubDate>
<author>admin</author>
<category>默认分类</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/109</guid>
</item>
<item>
<title>分布式日志收集系统： Facebook Scribe </title>
<summary><![CDATA[以下是我在公司内部分享的关于分布式日志收集系统的PPT内容，现在与大家分享，希望对于需要使用的人能够起到基本的入门作用或是了解！ 1.分布式日志收集系统:背景介绍 许多公司的平台每天会产生大量的日志（一般为流式数据，如，搜索引擎的v，查询等），处理这些日志需要特定的日志系统，一般而言，这些系统需要具有以下特征： （1） 构建应用系统和分析系统的桥梁，并将它们之间的关联解耦； （2） 支持近实时的在线分析系统和类似于Hd之类的离线分析系统； （3） 具有高可扩展性。即：当数据量增加时，可以通过增…]]></summary>
<description><![CDATA[<p>
	&nbsp;</p>
<div id="cnblogs_post_body">
	<p>
		<span>以下是我在公司内部分享的关于分布式日志收集系统的PPT内容，现在与大家分享，希望对于需要使用的人能够起到基本的入门作用或是了解！</span></p>
	<p>
		1.分布式日志收集系统:背景介绍</p>
	<p>
		许多公司的平台每天会产生大量的日志（一般为流式数据，如，搜索引擎的pv，查询等），处理这些日志需要特定的日志系统，一般而言，这些系统需要具有以下特征：</p>
	<p>
		（1） 构建应用系统和分析系统的桥梁，并将它们之间的关联解耦；</p>
	<p>
		（2） 支持近实时的在线分析系统和类似于Hadoop之类的离线分析系统；</p>
	<p>
		（3） 具有高可扩展性。即：当数据量增加时，可以通过增加节点进行水平扩展。</p>
	<p>
		&nbsp;</p>
	<p>
		2.分布式日志收集系统：Facebook Scribe主要内容</p>
	<p>
		（1）Scribe简介及系统架构</p>
	<p>
		（2）Scribe技术架构</p>
	<p>
		（3）Scribe部署结构</p>
	<p>
		（4）Scribe主要功能和使用方案</p>
	<p>
		（5）Scribe的具体应用实例</p>
	<p>
		（6）Scribe的扩展</p>
	<p>
		（7）Scribe研究体会</p>
	<p>
		&nbsp;</p>
	<p>
		3.Scribe简介</p>
	<p>
		Scribe是facebook开源的日志收集系统，在facebook内部已经得到大量的应用。 Scribe是基于一个使用非阻断C++服务器的thrift服务的实现。它能够从各种日志源上收集日志，存储到一个中央存储系统 （可以是NFS，分布式文件系统等）上，以便于进行集中统计分析处理。它为日志的&ldquo;分布式收集，统一处理&rdquo;提供了一个可扩展的，高容错的方案。</p>
	<p>
		&nbsp;</p>
	<p>
		4.Scribe的系统架构</p>
	<p>
		<img alt="" src="/upload/images/20111213/1000026802_0.jpg" /></p>
	<p>
		如上图所示：Scribe从各种数据源上收集数据，放到一个共享队列上，然后push到后端的中央存储系统上。当中央存储系统出现故障时，scribe可以暂时把日志写到本地文件中，待中央存储系统恢复性能后，scribe把本地日志续传到中央存储系统上。</p>
	<p>
		&nbsp;</p>
	<p>
		5.Scribe的技术架构</p>
	<p>
		<img alt="" src="/upload/images/20111213/1000027052_1.jpg" /></p>
	<p>
		如上图所示：Scribe服务器底层数据通信框架是Thrift，Thrift也是Facebook开源的，并得到了广泛的使用。也用到了C++的准标准库boost，主要使用共享指针和文件相关的功能。Thrift也用到了libevent开发库和socket编程技术。</p>
	<p>
		&nbsp;</p>
	<p>
		6.Scribe部署结构</p>
	<p>
		<img alt="" src="/upload/images/20111213/1000023136_2.jpg" /></p>
	<p>
		&nbsp;</p>
	<p>
		7.Scribe的主要功能</p>
	<p>
		1.支持多种存储类型：7种并且可扩展</p>
	<p>
		2.日志自动切分功能：按文件大小和时间切分</p>
	<p>
		3.灵活的客户端：</p>
	<p>
		（1）支持多种常用语言（Thrift提供支持）；</p>
	<p>
		（2）可与应用系统集成；可以作实现独立客户端</p>
	<p>
		4.支持日志分类功能（Facebook有上百种日志分类）</p>
	<p>
		5.其他功能</p>
	<p>
		（1）连接池</p>
	<p>
		（2）灵活的日志缓存大小</p>
	<p>
		（3）多线程功能(消息队列)</p>
	<p>
		（4）scribe服务器之间可以转发日志</p>
	<p>
		6.以上功能都是可以通过配置文件来灵活配置</p>
	<p>
		&nbsp;</p>
	<p>
		8.Scribe使用方案</p>
	<p>
		（1）和产生日志文件的应用系统集成</p>
	<p>
		scribe能够和各种应用系统很好的集成是因为它提供几乎所有的开发语言的开发包</p>
	<p>
		（2）应用系统在本地产生日志文件，使用一个独立运行的客户端程序同样，独立的客户端也可以采用各种语言开发，我们采用的是python来开发客户端</p>
	<p>
		&nbsp;</p>
	<p>
		9.Scribe的具体应用实例</p>
	<p>
		1.Facebook肯定大量的使用，主要用于处理Facebook级别日志，一旦有新的日志分类生成，Scribe将自动处理。（Facebook有上百个日志分类）。</p>
	<p>
		2. Twitter：一款分布式实时统计系统Rainbird使用了scribe</p>
	<p>
		3.我的公司：</p>
	<p>
		（1）*****</p>
	<p>
		（2）*****</p>
	<p>
		（3）*****</p>
	<p>
		（4）*****</p>
	<p>
		（5）*****</p>
	<p>
		（6）*****</p>
	<p>
		4.其他</p>
	<p>
		&nbsp;</p>
	<p>
		10.Scribe的扩展：存在的问题</p>
	<p>
		虽然scribe系统是如此的优秀，但是也存在着一些不足和问题，针对存在的问题我们对scribe进行扩展。我们发现scribe存在的主要问题如下：</p>
	<p>
		1、单点故障问题</p>
	<p>
		有三个地方存在单点故障：</p>
	<p>
		（1）中心服务器</p>
	<p>
		（2）本地服务器</p>
	<p>
		（3）收集日志的客户端程序</p>
	<p>
		2、日志丢失问题</p>
	<p>
		当日志文件发生切分的时候可能导致日志丢失</p>
	<p>
		3、历史日志收集问题</p>
	<p>
		4、scribe服务器挂了没有及时通知</p>
	<p>
		&nbsp;</p>
	<p>
		11.Scribe的扩展：问题解决方案</p>
	<p>
		针对上面我们提出的问题，主要提供如下相应的解决方案：</p>
	<p>
		1.中心服务器单点故障</p>
	<p>
		可以部署多个中心服务器，然后本地服务器通过配置文件可以自动在这些服务器之间进行切换</p>
	<p>
		2.其余的问题我们都是通过自己写的python客户端解决的</p>
	<p>
		python客户端我们是基于一个开源的项目进行二次开发的，因为开源的python客户端功能很简单，只是跟踪一个日志文件并把日志文件的数据读取导入到scribe本地服务器</p>
	<p>
		&nbsp;</p>
	<p>
		12.Scribe的扩展：python客户端</p>
	<p>
		我们开发的python客户端主要实现了如下功能：</p>
	<p>
		1、解决本地scribe服务器的单点故障</p>
	<p>
		我们可以通过配置多个本地scribe服务器（通过配置文件配置，相当的灵活），python脚本会根据配置的这些服务器自动切换（当一个scribe挂掉之后自动切换，如果挂掉本地scribe服务器重新启动以后又会自动切换回去。</p>
	<p>
		2、解决日志丢失的问题</p>
	<p>
		开源的python客户端是按照固定的时间间隔扫描日志文件是否有变化，如果在这个时间段内发生日志切换会导致日志丢失。我们同样是采用这个方式去检测日志文件，不过我们在发生日志切分的时候会再次去检测被切分走得日志文件是否已经收集完毕。</p>
	<p>
		3、解决历史日志收集</p>
	<p>
		如果在我们运行python客户端以前已经产生了日志，这部分的日志收集也是我们新增的一个功能</p>
	<p>
		4、解决自身的单点故障问题</p>
	<p>
		不排除我们的python客户端也会挂掉的时候，当我们下次启动怎样保证我们收集的日志不重复不丢失是需要解决的问题。我们的解决方案就是对已经收集的日志文件的各种信息做序列化（主要是已经收集日志文件的位置）</p>
	<p>
		5、收集日志文件怎样保证按照日志生成的顺序收集</p>
	<p>
		日志的生成顺序就是跟他们文件的建立时间是相关的，通过这一点我们可以实现。</p>
	<p>
		6、及时通知机制</p>
	<p>
		为了及时的通知到scrib服务器挂掉的信息到相关人员，我们开发了邮件通知机制，就是当某一个本地scribe服务器挂掉以后会触发邮件发送</p>
	<p>
		&nbsp;</p>
	<p>
		13.Scribe研究体会</p>
	<p>
		怎样从我们工作的内容深入学习？</p>
	<p>
		1.每个人在公司负责开发的内容都是很有限的，怎样从我们开发的内容入手深入研究和学习更多的知识？</p>
	<p>
		2.Scribe研究的例子！</p>
	<p>
		<img alt="" src="/upload/images/20111213/1000025029_3.jpg" /></p>
	<p>
		&nbsp;</p>
	<p>
		14.总结：以上内容有一些是来至互联网，在加入了自己的一些理解，希望对需要的人有所帮助！</p>
	<p style="text-align: right; ">
		摘至：http://www.cnblogs.com/brucewoo/archive/2011/12/13/2285482.html</p>
</div>
<script></script>]]></description>
<link>http://www.chenggang.net/posts/108</link>
<pubDate>Tue, 13 Dec 2011 10:00:04 +0800</pubDate>
<author>admin</author>
<category>默认分类</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/108</guid>
</item>
<item>
<title>Linux Shell常用技巧</title>
<summary><![CDATA[十九. 和系统运行进程相关的Shll命令 : 1. 进程监控命令 () : 要对进程进行监测和控制，首先必须要了解当前进程的情况，也就是需要查看当前进程，而命令就是最基本同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等。总之大部分信息都是可以通过执行该命令得到的。 命令存在很多的命令行选项和参数，然而我们最为常用只有两种形式，这里先给出与它们相关的选项和参数的含义： : 显示终端上的所有进程，包括…]]></summary>
<description><![CDATA[<div id="cnblogs_post_body">
	<div id="cnblogs_post_body">
		<p>
			<span style="COLOR: #ff6600; FONT-SIZE: 14pt"><strong>十九.&nbsp; 和系统运行进程相关的Shell命令</strong></span><span style="COLOR: #ff6600; FONT-SIZE: 14pt"><strong>:</strong></span><br />
			&nbsp;&nbsp;&nbsp;&nbsp;<br />
			&nbsp;<span style="FONT-SIZE: 16px">&nbsp;&nbsp; <strong>1. 进程监控命令<span style="COLOR: #ff0000">(ps)</span>:</strong></span><br />
			&nbsp;&nbsp;&nbsp; 要对进程进行监测和控制，首先必须要了解当前进程的情况，也就是需要查看当前进程，而ps命令就是最基本同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等。总之大部分信息都是可以通过执行该命令得到的。<br />
			&nbsp;&nbsp;&nbsp; ps命令存在很多的命令行选项和参数，然而我们最为常用只有两种形式，这里先给出与它们相关的选项和参数的含义：<br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; a: 显示终端上的所有进程，包括其他用户的进程。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; u: 以用户为主的格式来显示程序状况。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; x: 显示所有程序，不以终端来区分。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; -e:显示所有进程。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; o: 其后指定要输出的列，如user，pid等，多个列之间用逗号分隔。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; -p:后面跟着一组pid的列表，用逗号分隔，该命令将只是输出这些pid的相关数据。</span><br />
			<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; ps aux</span></em><br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp; 0.0&nbsp; 0.1&nbsp;&nbsp; 2828&nbsp; 1400 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Ss&nbsp;&nbsp; 09:51&nbsp;&nbsp; 0:02 /sbin/init<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp; 0.0&nbsp; 0.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; 0 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S&nbsp;&nbsp;&nbsp; 09:51&nbsp;&nbsp; 0:00 [kthreadd]<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp; 0.0&nbsp; 0.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S&nbsp;&nbsp;&nbsp; 09:51&nbsp;&nbsp; 0:00 [migration/0]<br />
			&nbsp;&nbsp;&nbsp; ... ...&nbsp;&nbsp;<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; ps -eo user,pid,%cpu,%mem,start,time,command | head -n 4</span></em><br />
			&nbsp;&nbsp;&nbsp; USER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PID %CPU %MEM&nbsp; STARTED&nbsp;&nbsp;&nbsp;&nbsp; TIME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; COMMAND<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0&nbsp;&nbsp;&nbsp; 0.1&nbsp;&nbsp; 09:51:08&nbsp;&nbsp;&nbsp;&nbsp; 00:00:02&nbsp; /sbin/init<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0&nbsp;&nbsp;&nbsp; 0.0&nbsp;&nbsp; 09:51:08&nbsp;&nbsp;&nbsp;&nbsp; 00:00:00&nbsp; [kthreadd]<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0.0&nbsp;&nbsp;&nbsp; 0.0&nbsp;&nbsp; 09:51:08 &nbsp; &nbsp; 00:00:00&nbsp; [migration/0]<br />
			&nbsp;&nbsp;&nbsp; 这里需要说明的是，ps中存在很多和进程性能相关的参数，它们均以输出表格中的列的方式显示出来，在这里我们只是给出了非常常用的几个参数，至于更多参数，我们则需要根据自己应用的实际情况去看ps的man手册。<br />
			&nbsp;&nbsp;&nbsp; #以完整的格式显示pid为1(init)的进程的相关数据<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; ps -fp 1</span></em><br />
			&nbsp;&nbsp; &nbsp;UID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PID&nbsp; PPID&nbsp; C STIME TTY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TIME&nbsp;&nbsp; CMD<br />
			&nbsp;&nbsp; &nbsp;root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; 0 05:16&nbsp;&nbsp; ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00:00:03 /sbin/init<br />
			&nbsp;&nbsp;&nbsp;<br />
			&nbsp;&nbsp;&nbsp; <span style="FONT-SIZE: 16px"><strong>2. 改变进程优先级的命令<span style="COLOR: #ff0000">(nice和renice)</span>:</strong></span><br />
			&nbsp;&nbsp;&nbsp; 该Shell命令最常用的使用方式为：nice [-n &lt;优先等级&gt;][执行指令]，其中优先等级的范围从-20-19，其中-20最高，19最低，只有系统管理者可以设置负数的等级。<br />
			&nbsp;&nbsp;&nbsp; #后台执行sleep 100秒，同时在启动时将其nice值置为19<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; nice -n 19 sleep 100 &amp;</span></em><br />
			&nbsp;&nbsp;&nbsp; [1] 4661<br />
			&nbsp;&nbsp;&nbsp; #后台执行sleep 100秒，同时在启动时将其nice值置为-19<br />
			&nbsp;&nbsp;&nbsp; <em><span style="COLOR: #0000ff">/&gt; nice -n -19 sleep 100 &amp;</span></em><br />
			&nbsp;&nbsp;&nbsp; [2] 4664<br />
			&nbsp;&nbsp;&nbsp; #关注ps -l输出中用黄色高亮的两行，它们的NI值和我们执行是设置的值一致。<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; ps -l</span></em><br />
			&nbsp;&nbsp;&nbsp; F S&nbsp;&nbsp; UID&nbsp;&nbsp; PID&nbsp; PPID&nbsp; C PRI&nbsp; NI&nbsp; ADDR&nbsp; SZ&nbsp;&nbsp;&nbsp; WCHAN&nbsp; TTY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TIME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CMD<br />
			&nbsp;&nbsp;&nbsp; 4 S&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; 2833&nbsp; 2829&nbsp; 0&nbsp; 80&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1739&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; pts/2&nbsp;&nbsp;&nbsp; 00:00:00&nbsp; bash<br />
			<span style="BACKGROUND-COLOR: #ffff00">&nbsp;&nbsp;&nbsp; 0 S&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; 4661&nbsp; 2833&nbsp; 0&nbsp; 99&nbsp; 19&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1066&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pts/2&nbsp;&nbsp;&nbsp; 00:00:00&nbsp; sleep</span><br />
			<span style="BACKGROUND-COLOR: #ffff00">&nbsp;&nbsp;&nbsp; 4 S&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; 4664&nbsp; 2833&nbsp; 0&nbsp; 61 -19&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1066&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; pts/2&nbsp;&nbsp;&nbsp; 00:00:00&nbsp; sleep</span><br />
			&nbsp;&nbsp;&nbsp; 4 R&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp; 4665&nbsp; 2833&nbsp; 1&nbsp; 80&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1231 &nbsp; &nbsp; -&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; pts/2&nbsp;&nbsp;&nbsp; 00:00:00&nbsp; ps<br />
			&nbsp;&nbsp;&nbsp;<br />
			&nbsp;&nbsp;&nbsp; renice命令主要用于为已经执行的进程重新设定nice值，该命令包含以下几个常用选项：<br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; -g:　使用程序群组名称，修改所有隶属于该程序群组的程序的优先权。</span><br />
			<span style="COLOR: #ff0000">　 -p:&nbsp; 改变该程序的优先权等级，此参数为预设值。</span><br />
			<span style="COLOR: #ff0000">　 -u:&nbsp; 指定用户名称，修改所有隶属于该用户的程序的优先权。</span><br />
			&nbsp;&nbsp;&nbsp;<br />
			&nbsp;&nbsp;&nbsp; #切换到stephen用户下执行一个后台进程，这里sleep进程将在后台睡眠1000秒。<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; su stephen</span></em><br />
			<em><span style="COLOR: #0000ff">&nbsp;&nbsp;&nbsp; /&gt; sleep 1000&amp;&nbsp;&nbsp;</span></em><br />
			&nbsp;&nbsp;&nbsp; [1] <strong><span style="COLOR: #ff0000">4812</span></strong><br />
			&nbsp;&nbsp;&nbsp; <em><span style="COLOR: #0000ff">/&gt; exit&nbsp;</span></em>&nbsp; #退回到切换前的root用户<br />
			&nbsp;&nbsp;&nbsp; #查看已经启动的后台sleep进程，其ni值为0，宿主用户为stephen<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; ps -eo user,pid,ni,command | grep stephen</span></em><br />
			&nbsp;&nbsp;&nbsp; stephen&nbsp;&nbsp; 4812&nbsp;&nbsp; 0 sleep 1000<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4821&nbsp;&nbsp;&nbsp; 0 grep&nbsp; stephen<br />
			&nbsp;&nbsp;&nbsp; #以指定用户的方式修改该用户下所有进程的nice值<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; renice -n 5 -u stephen</span></em><br />
			&nbsp;&nbsp;&nbsp; 500: old priority 0, new priority 5<br />
			&nbsp;&nbsp;&nbsp; #从再次执行ps的输出结果可以看出，该sleep后台进程的nice值已经调成了5<br />
			&nbsp;<em><span style="COLOR: #0000ff">&nbsp;&nbsp; /&gt; ps -eo user,pid,ni,command | grep stephen</span></em><br />
			&nbsp;&nbsp;&nbsp; stephen&nbsp;&nbsp; 4812&nbsp;&nbsp; 5 sleep 1000<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; 4826 &nbsp; 0 grep&nbsp; stephen<br />
			&nbsp;&nbsp;&nbsp; #以指定进程pid的方式修改该进程的nice值<br />
			&nbsp;&nbsp;&nbsp; <em><span style="COLOR: #0000ff">/&gt; renice -n 10 -p 4812</span></em><br />
			&nbsp;&nbsp;&nbsp; 4812: old priority 5, new priority 10<br />
			&nbsp;&nbsp;&nbsp; #再次执行ps，该sleep后台进程的nice值已经从5变成了10<br />
			&nbsp;&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> /&gt; ps -eo user,pid,ni,command | grep stephen</span></em><br />
			&nbsp;&nbsp;&nbsp; stephen&nbsp;&nbsp; 4812&nbsp; 10 sleep 1000<br />
			&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4829&nbsp;&nbsp; 0 grep&nbsp; stephen</p>
		<p>
			<br />
			<span style="FONT-SIZE: 16px"><strong>&nbsp;&nbsp;&nbsp; 3. 列出当前系统打开文件的工具<span style="COLOR: #ff0000">(lsof)</span>:</strong></span><br />
			&nbsp;&nbsp; &nbsp;lsof(list opened files)，其重要功能为列举系统中已经被打开的文件。众所周知，linux环境中任何事物都是文件，如设备、目录、sockets等。所以，用好lsof命令，对日常的linux管理非常有帮助。下面先给出该命令的常用选项：<br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;-c command_prefix:</strong> 显示以command_prefix开头的进程打开的文件。</span><br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;-p PID:</strong> 显示指定PID已打开文件的信息</span><br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;+d directory:</strong>&nbsp; 从文件夹directory来搜寻(不考虑子目录)，列出该目录下打开的文件信息。</span><br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;+D directory:&nbsp;</strong> 从文件夹directory来搜寻(考虑子目录)，列出该目录下打开的文件信息。</span><br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;-d num_of_fd:</strong>&nbsp; 以File Descriptor的信息进行匹配，可使用3-10，表示范围，3,10表示某些值。</span><br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;-u user:</strong> 显示某用户的已经打开的文件，其中user可以使用正则表达式。</span><br />
			<span style="COLOR: #ff0000"><strong>&nbsp;&nbsp; &nbsp;-i:</strong> 监听指定的协议、端口、主机等的网络信息，格式为：[proto][@host|addr][:svc_list|port_list]</span><br />
			&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查看打开/dev/null文件的进程。<br />
			&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; lsof /dev/null | head -n 5</span></em><br />
			&nbsp;&nbsp; &nbsp;COMMAND&nbsp;&nbsp;&nbsp; PID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; USER&nbsp;&nbsp; FD&nbsp;&nbsp; TYPE DEVICE SIZE/OFF NODE NAME<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp; 0u&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0 3671 /dev/null<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp; 1u&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0 3671 /dev/null<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp; 2u&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0 3671 /dev/null<br />
			&nbsp;&nbsp; &nbsp;udevd 397&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp; 0u&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0 3671 /dev/null<br />
			&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查看打开22端口的进程<br />
			&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; lsof -i:22</span></em><br />
			&nbsp;&nbsp; &nbsp;COMMAND&nbsp; PID USER&nbsp;&nbsp; FD&nbsp;&nbsp; TYPE DEVICE SIZE/OFF NODE NAME<br />
			&nbsp;&nbsp; &nbsp;sshd&nbsp;&nbsp;&nbsp; 1582 root&nbsp;&nbsp;&nbsp; 3u&nbsp; IPv4&nbsp; 11989&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp; TCP *:ssh (LISTEN)<br />
			&nbsp;&nbsp; &nbsp;sshd&nbsp;&nbsp;&nbsp; 1582 root&nbsp;&nbsp;&nbsp; 4u&nbsp; IPv6&nbsp; 11991&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp; TCP *:ssh (LISTEN)<br />
			&nbsp;&nbsp; &nbsp;sshd&nbsp;&nbsp;&nbsp; 2829 root&nbsp;&nbsp;&nbsp; 3r&nbsp;&nbsp; IPv4&nbsp; 19635&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp; TCP bogon:ssh-&gt;bogon:15264 (ESTABLISHED)<br />
			&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查看init进程打开的文件<br />
			&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt;&nbsp; lsof -c init</span></em><br />
			&nbsp;&nbsp; &nbsp;COMMAND PID USER&nbsp;&nbsp; FD&nbsp;&nbsp; TYPE&nbsp;&nbsp;&nbsp;&nbsp; DEVICE&nbsp;&nbsp; SIZE/OFF&nbsp;&nbsp; NODE NAME<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; cwd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DIR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp;&nbsp;&nbsp; 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 /<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; rtd&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; DIR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp;&nbsp;&nbsp; 4096&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 /<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; txt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp; 136068&nbsp;&nbsp; 148567&nbsp;&nbsp;&nbsp;&nbsp; /sbin/init<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp;&nbsp; 58536&nbsp;&nbsp; 137507&nbsp;&nbsp;&nbsp;&nbsp; /lib/libnss_files-2.12.so<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp; 122232&nbsp; 186675&nbsp;&nbsp;&nbsp;&nbsp; /lib/libgcc_s-4.4.4-20100726.so.1<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp; 141492&nbsp; 186436&nbsp;&nbsp;&nbsp;&nbsp; /lib/ld-2.12.so<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp; 1855584 186631&nbsp;&nbsp;&nbsp;&nbsp; /lib/libc-2.12.so<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp; 133136&nbsp; 186632&nbsp;&nbsp;&nbsp;&nbsp; /lib/libpthread-2.12.so<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp;&nbsp; 99020&nbsp;&nbsp; 180422&nbsp;&nbsp;&nbsp;&nbsp; /lib/libnih.so.1.0.0<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp;&nbsp; 37304&nbsp;&nbsp; 186773&nbsp;&nbsp;&nbsp;&nbsp; /lib/libnih-dbus.so.1.0.0<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp;&nbsp; 41728&nbsp;&nbsp; 186633&nbsp;&nbsp;&nbsp;&nbsp; /lib/librt-2.12.so<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp; mem&nbsp;&nbsp;&nbsp; REG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8,2&nbsp;&nbsp; 286380&nbsp; 186634&nbsp;&nbsp;&nbsp;&nbsp; /lib/libdbus-1.so.3.4.0<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 0u&nbsp;&nbsp;&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3671&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /dev/null<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 1u&nbsp;&nbsp;&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3671&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /dev/null<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 2u&nbsp;&nbsp;&nbsp;&nbsp; CHR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1,3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3671&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /dev/null<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 3r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FIFO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7969&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pipe<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 4w&nbsp;&nbsp;&nbsp;&nbsp; FIFO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7969&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pipe<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 5r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DIR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inotify<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 6r&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DIR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0,10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inotify<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 7u&nbsp;&nbsp;&nbsp;&nbsp; unix&nbsp;&nbsp; 0xf61e3840&nbsp; 0t0&nbsp;&nbsp;&nbsp; 7970&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; socket<br />
			&nbsp;&nbsp; &nbsp;init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp; 9u&nbsp;&nbsp;&nbsp;&nbsp; unix&nbsp;&nbsp; 0xf3bab280&nbsp; 0t0&nbsp;&nbsp; 11211&nbsp;&nbsp;&nbsp;&nbsp; socket<br />
			&nbsp;&nbsp; &nbsp;在上面输出的FD列中，显示的是文件的File Descriptor number，或者如下的内容：<br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;cwd:&nbsp; current working directory;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;mem:&nbsp; memory-mapped file;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;mmap: memory-mapped device;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;pd:&nbsp;&nbsp; parent directory;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;rtd:&nbsp; root directory;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;txt:&nbsp; program text (code and data);</span><br />
			<span style="COLOR: #000000">&nbsp;&nbsp; &nbsp;文件的File Descriptor number显示模式有:</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;r for read access;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;w for write access;</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;u for read and write access;</span><br />
			<br />
			&nbsp;&nbsp; &nbsp;在上面输出的FD列中，显示的是文件的File Descriptor number，或者如下的内容：<br />
			&nbsp;&nbsp; <span style="COLOR: #ff0000">&nbsp;DIR:&nbsp; 目录</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;LINK: 链接文件</span><br />
			&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查看pid为1的进程(init)打开的文件，其输出结果等同于上面的命令，他们都是init。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; lsof -p 1</span></em>&nbsp;&nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查看owner为root的进程打开的文件。<br />
			&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; lsof -u root</span></em><br />
			&nbsp;&nbsp; &nbsp;#查看owner不为root的进程打开的文件。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; lsof -u ^root</span></em><br />
			&nbsp;&nbsp; &nbsp;#查看打开协议为tcp，ip为192.168.220.134，端口为22的进程。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; lsof -i tcp@192.168.220.134:22</span></em><br />
			&nbsp;&nbsp; &nbsp;COMMAND&nbsp; PID USER&nbsp;&nbsp; FD&nbsp;&nbsp; TYPE DEVICE SIZE/OFF NODE NAME<br />
			&nbsp;&nbsp; &nbsp;sshd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2829 root&nbsp;&nbsp;&nbsp;&nbsp; 3r&nbsp;&nbsp;&nbsp; IPv4&nbsp; 19635&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0t0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TCP&nbsp;&nbsp;&nbsp; bogon:ssh-&gt;bogon:15264 (ESTABLISHED)&nbsp;&nbsp;&nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查看打开/root文件夹，但不考虑目录搜寻<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; lsof +d /root</span></em><br />
			&nbsp;&nbsp; &nbsp;#查看打开/root文件夹以及其子目录搜寻<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; lsof +D /root</span></em><br />
			&nbsp;&nbsp; &nbsp;#查看打开FD(0-3)文件的所有进程<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; lsof -d 0-3</span></em></p>
		<p>
			<br />
			<span style="FONT-SIZE: 16px"><strong>&nbsp;&nbsp;&nbsp; 4. 进程查找/杀掉命令<span style="COLOR: #ff0000">(pgrep/pkill)</span>：</strong></span><br />
			&nbsp;&nbsp; &nbsp;查找和杀死指定的进程, 他们的选项和参数完全相同, 这里只是介绍pgrep。下面是常用的命令行选项：<br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-d：定义多个进程之间的分隔符, 如果不定义则使用换行符。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-n：表示如果该程序有多个进程正在运行，则仅查找最新的，即最后启动的。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-o：表示如果该程序有多个进程正在运行，则仅查找最老的，即最先启动的。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-G：其后跟着一组group id，该命令在搜索时，仅考虑group列表中的进程。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-u：其后跟着一组有效用户ID(effetive user id)，该命令在搜索时，仅考虑该effective user列表中的进程。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-U：其后跟着一组实际用户ID(real user id)，该命令在搜索时，仅考虑该real user列表中的进程。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-x：表示进程的名字必须完全匹配, 以上的选项均可以部分匹配。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-l： 将不仅打印pid,也打印进程名。</span><br />
			<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;-f： 一般与-l合用, 将打印进程的参数。</span><br />
			&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;#手工创建两个后台进程<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; sleep 1000&amp;</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; sleep 1000&amp;</span></em><br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程，同时输出所有找到的pid<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程pid，如果存在多个，他们之间使用:分隔，而不是换行符分隔。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -d: sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456:3457<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程pid，如果存在多个，这里只是输出最后启动的那一个。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -n sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程pid，如果存在多个，这里只是输出最先启动的那一个。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -o&nbsp; sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep，同时这个正在运行的进程的组为root和stephen。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -G root,stephen sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;#查找有效用户ID为root和oracle，进程名为sleep的进程。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -u root,oracle sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;#查找实际用户ID为root和oracle，进程名为sleep的进程。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -U root,oracle sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程，注意这里找到的进程名必须和参数中的完全匹配。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -x sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456<br />
			&nbsp;&nbsp; &nbsp;3457<br />
			&nbsp;&nbsp; &nbsp;#-x不支持部分匹配，sleep进程将不会被查出，因此下面的命令没有结果。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -x sle</span></em><br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程，同时输出所有找到的pid和进程名。&nbsp;&nbsp; &nbsp;<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -l sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456 sleep<br />
			&nbsp;&nbsp; &nbsp;3457 sleep<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程，同时输出所有找到的pid、进程名和启动时的参数。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -lf sleep</span></em><br />
			&nbsp;&nbsp; &nbsp;3456 sleep 1000<br />
			&nbsp;&nbsp; &nbsp;3457 sleep 1000<br />
			&nbsp;&nbsp; &nbsp;#查找进程名为sleep的进程，同时以逗号为分隔符输出他们的pid，在将结果传给ps命令，-f表示显示完整格式，-p显示pid列表，ps将只是输出该列表内的进程数据。<br />
			&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; pgrep -f sleep -d, | xargs ps -fp</span></em><br />
			&nbsp;&nbsp; &nbsp;UID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PID&nbsp; PPID&nbsp; C STIME TTY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TIME CMD<br />
			&nbsp;&nbsp; &nbsp;root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3456&nbsp; 2138&nbsp; 0 06:11 pts/5&nbsp;&nbsp;&nbsp; 00:00:00 sleep 1000<br />
			&nbsp;&nbsp; &nbsp;root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3457&nbsp; 2138&nbsp; 0 06:11 pts/5&nbsp;&nbsp;&nbsp; 00:00:00 sleep 1000&nbsp;</p>
	</div>
	<p>
		<span style="COLOR: #ff6600"><strong><span style="FONT-SIZE: 14pt">二十. 通过管道组合Shell命令获取系统运行数据<span style="COLOR: #ff6600; FONT-SIZE: 14pt"><strong>:</strong></span></span></strong></span></p>
	<p>
		<br />
		&nbsp;&nbsp; <span style="FONT-SIZE: 16px"><strong>&nbsp;1.&nbsp; 输出当前系统中占用内存最多的5条命令</strong></span><span style="FONT-SIZE: 16px"><strong>:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) 通过ps命令列出当前主机正在运行的所有进程。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) 按照第五个字段基于数值的形式进行正常排序(由小到大)。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#3) 仅显示最后5条输出。</span><br />
		&nbsp;&nbsp;<em><span style="COLOR: #0000ff"> &nbsp;/&gt; ps aux | sort -k 5n | tail -5</span></em><br />
		&nbsp;&nbsp; &nbsp;stephen&nbsp;&nbsp; 1861&nbsp; 0.2&nbsp; 2.0&nbsp; 96972 21596&nbsp; ?&nbsp; S&nbsp;&nbsp;&nbsp;&nbsp; Nov11&nbsp;&nbsp; 2:24 nautilus<br />
		&nbsp;&nbsp; &nbsp;stephen&nbsp;&nbsp; 1892&nbsp; 0.0&nbsp; 0.4 102108&nbsp; 4508&nbsp; ?&nbsp; S&lt;sl Nov11&nbsp;&nbsp; 0:00 /usr/bin/pulseaudio<br />
		&nbsp;&nbsp; &nbsp;stephen&nbsp;&nbsp; 1874&nbsp; 0.0&nbsp; 0.9 107648 10124 ?&nbsp; S&nbsp;&nbsp;&nbsp;&nbsp; Nov11&nbsp;&nbsp; 0:00 gnome-volume<br />
		&nbsp;&nbsp; &nbsp;stephen&nbsp;&nbsp; 1855&nbsp; 0.0&nbsp; 1.2 123776 13112 ?&nbsp; Sl&nbsp;&nbsp;&nbsp;&nbsp; Nov11&nbsp;&nbsp; 0:00 metacity<br />
		&nbsp;&nbsp; &nbsp;stephen&nbsp;&nbsp; 1831&nbsp; 0.0&nbsp; 0.9 125432&nbsp; 9768&nbsp; ?&nbsp; Ssl&nbsp;&nbsp; Nov11&nbsp;&nbsp; 0:05 /usr/libexec/gnome<br />
		&nbsp;&nbsp; &nbsp;<br />
		&nbsp;&nbsp; &nbsp;<strong><span style="FONT-SIZE: 16px">2.&nbsp; 找出cpu利用率高的20个进程</span></strong><span style="FONT-SIZE: 16px"><strong>:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) 通过ps命令输出所有进程的数据，-o选项后面的字段列表列出了结果中需要包含的数据列。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) 将ps输出的Title行去掉，grep -v PID表示不包含PID的行。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#3) 基于第一个域字段排序，即pcpu。n表示以数值的形式排序。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#4) 输出按cpu使用率排序后的最后20行，即占用率最高的20行。</span><br />
		&nbsp;&nbsp; &nbsp;<span style="COLOR: #0000ff"><em>/&gt; ps -e -o pcpu,pid,user,sgi_p,cmd | grep -v PID | sort -k 1n | tail -20</em></span><br />
		<br />
		&nbsp;&nbsp;&nbsp; <span style="FONT-SIZE: 16px"><strong>3.&nbsp; 获取当前系统物理内存的总大小:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) 以兆(MB)为单位输出系统当前的内存使用状况。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) 通过grep定位到Mem行，该行是以操作系统为视角统计数据的。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#3) 通过awk打印出该行的第二列，即total列。</span><br />
		&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; free -m | grep &quot;Mem&quot; | awk &#39;{print $2, &quot;MB&quot;}&#39;</span></em><br />
		&nbsp;&nbsp; &nbsp;1007 MB<br />
		<br />
		<span style="FONT-SIZE: 14pt"><strong><span style="COLOR: #ff6600">二十一. 通过管道组合Shell命令进行系统管理</span></strong></span><span style="COLOR: #ff6600; FONT-SIZE: 14pt"><strong>:</strong></span><br />
		<br />
		&nbsp;&nbsp; &nbsp;<span style="FONT-SIZE: 16px"><strong>1.&nbsp; 获取当前或指定目录下子目录所占用的磁盘空间，并将结果按照从大到小的顺序输出:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) 输出/usr的子目录所占用的磁盘空间。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) 以数值的方式倒排后输出。</span><br />
		&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; du -s /usr/* | sort -nr</span></em><br />
		&nbsp;&nbsp; &nbsp;1443980 /usr/share<br />
		&nbsp;&nbsp; &nbsp;793260&nbsp;&nbsp; /usr/lib<br />
		&nbsp;&nbsp; &nbsp;217584&nbsp;&nbsp; /usr/bin<br />
		&nbsp;&nbsp; &nbsp;128624&nbsp;&nbsp; /usr/include<br />
		&nbsp;&nbsp; &nbsp;60748&nbsp;&nbsp;&nbsp; /usr/libexec<br />
		&nbsp;&nbsp; &nbsp;45148&nbsp;&nbsp;&nbsp; /usr/src<br />
		&nbsp;&nbsp; &nbsp;21096&nbsp;&nbsp;&nbsp; /usr/sbin<br />
		&nbsp;&nbsp; &nbsp;6896&nbsp;&nbsp; &nbsp;&nbsp; /usr/local<br />
		&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /usr/games<br />
		&nbsp;&nbsp; &nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /usr/etc<br />
		&nbsp;&nbsp; &nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /usr/tmp<br />
		&nbsp;&nbsp; &nbsp;<br />
		&nbsp;&nbsp; &nbsp;<span style="FONT-SIZE: 16px"><strong>2.&nbsp; 批量修改文件名</strong></span><span style="FONT-SIZE: 16px"><strong>:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) find命令找到文件名扩展名为.output的文件。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) sed命令中的-e选项表示流编辑动作有多次，第一次是将找到的文件名中相对路径前缀部分去掉，如./aa改为aa。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; 流编辑的第二部分，是将20110311替换为mv &amp; 20110310，其中&amp;表示s命令的被替换部分，这里即源文件名。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp;&nbsp; 1表示被替换部分中#的(.*)。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; #3) 此时的输出应为</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp; &nbsp;mv 20110311.output 20110310.output</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp; &nbsp;mv 20110311abc.output 20110310abc.output</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp;&nbsp; 最后将上面的输出作为命令交给bash命令去执行，从而将所有</span><span style="COLOR: #ff0000">20110311*.output改为</span><span style="COLOR: #ff0000">20110311*.output</span><br />
		&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; find ./ -name &quot;*.output&quot; -print&nbsp; | sed -e &#39;s/.///g&#39; -e &#39;s/20110311(.*)/mv &amp; 201103101/g&#39; | bash</span></em><br />
		&nbsp;&nbsp;&nbsp;<br />
		<span style="FONT-SIZE: 16px"><strong>&nbsp;&nbsp; &nbsp;3.&nbsp; 统计当前目录下文件和目录的数量</strong></span><span style="FONT-SIZE: 16px"><strong>:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) ls -l命令列出文件和目录的详细信息。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp;&nbsp; #2) ls -l输出的详细列表中的第一个域字段是文件或目录的权限属性部分，如果权限属性部分的第一个字符为d，<br />
		&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp;&nbsp; 该文件为目录，如果是-，该文件为普通文件。<br />
		&nbsp;&nbsp;&nbsp; #3) 通过wc计算grep过滤后的行数。</span><br />
		&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; ls -l * | grep &quot;^-&quot; | wc -l</span></em><br />
		<em><span style="COLOR: #0000ff">&nbsp;&nbsp; &nbsp;/&gt; ls -l * | grep &quot;^d&quot; | wc -l</span></em><br />
		&nbsp;&nbsp;&nbsp;<br />
		&nbsp;&nbsp; &nbsp;<span style="FONT-SIZE: 16px"><strong>4.&nbsp; 杀掉指定终端的所有进程:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) 通过ps命令输出终端为pts/1的所有进程。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) 将ps的输出传给grep，grep将过滤掉ps输出的Title部分，-v PID表示不包含PID的行。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#3) awk打印输出grep查找结果的第一个字段，即pid字段。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#4) 上面的三个组合命令是在反引号内被执行的，并将执行的结果赋值给数组变量${K}。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#5) kill方法将杀掉数组${K}包含的pid。</span><br />
		&nbsp;&nbsp; <em><span style="COLOR: #0000ff">&nbsp;/&gt; kill -9 ${K}=`ps -t pts/1 | grep -v PID | awk &#39;{print $1}&#39;`&nbsp;&nbsp;</span></em> &nbsp;<br />
		<br />
		&nbsp;&nbsp; &nbsp;<span style="FONT-SIZE: 16px"><strong>5.&nbsp; 将查找到的文件打包并copy到指定目录</strong></span><span style="FONT-SIZE: 16px"><strong>:</strong></span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) 通过find找到当前目录下(包含所有子目录)的所有*.txt文件。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) tar命令将find找到的结果压缩成test.tar压缩包文件。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#3) 如果&amp;&amp;左侧括号内的命令正常完成，则可以执行&amp;&amp;右侧的shell命令了。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#4) 将生成后的test.tar文件copy到/home/.目录下。</span><br />
		&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; (find . -name &quot;*.txt&quot; | xargs tar -cvf test.tar) &amp;&amp; cp -f test.tar /home/.</span></em><br />
		&nbsp;&nbsp;&nbsp;<br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#1) cpio从find的结果中读取文件名，将其打包压缩后发送到./dest/dir(目标目录)。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#2) cpio的选项介绍：</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp; &nbsp;-d：创建需要的目录。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp; &nbsp;-a：重置源文件的访问时间。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp; &nbsp;-m：保护新文件的修改时间。</span><br />
		<span style="COLOR: #ff0000">&nbsp;&nbsp; &nbsp;#&nbsp;&nbsp; &nbsp;-p：将cpio设置为copy pass-through模式。</span><br />
		&nbsp;&nbsp; &nbsp;<em><span style="COLOR: #0000ff">/&gt; find . -name &quot;*&quot; | cpio -dampv ./dest/dir</span></em></p>
	<p>
		<span style="COLOR: #339966">　&nbsp; <em>最后需要说明的是，该篇Blog中绝大多数的示例来自于互联网，是本人经过一天左右的时间收集和整理之后筛选出来的，其中注释部分是我在后来添加的，以便于<span style="COLOR: #339966"><em>我们</em></span>阅读时的理解。如果今后再发现更好更巧妙的Shell组合命令，本人将持续更新该Blog。如果您有确实非常不错的Shell命令组合，且愿意和我们在这里分享，可以直接放在回复中，本人将对该篇Blog始终保持重点关注。</em></span></p>
</div>
<p style="text-align: right;">
	摘至：http://www.cnblogs.com/stephen-liu74/archive/2011/12/12/2262298.html</p>
]]></description>
<link>http://www.chenggang.net/posts/107</link>
<pubDate>Mon, 12 Dec 2011 21:52:11 +0800</pubDate>
<author>admin</author>
<category>Linux</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/107</guid>
</item>
<item>
<title>Yii中基于数据库的数据字典</title>
<summary><![CDATA[	基于数据库的数据字典	直接加载到controllers中	运行datadict/datadict,生成数据字典;	运行datadict/updatedict,自动更新数据字典;	附件下载	&nbsp;]]></summary>
<description><![CDATA[<p>
	基于数据库的数据字典</p>
<p>
	直接加载到controllers中<br />
	运行datadict/datadict,生成数据字典;<br />
	运行datadict/updatedict,自动更新数据字典;</p>
<p>
	Yii的官网时断时续，还有些东邪写在这里好了。</p>
<p>
	数据字典可以根据数据库生成data_dict的记录并生成当前应用下的语言翻译文件，加入你的应用是zh_cn的，就会在protected\messages\zh_cn\models目录下生成如下文件：</p>
<p>
	<img alt="" src="/upload/images/20111008103634.jpg" style="width: 599px; height: 577px" /></p>
<p>
	内容与数据表的字段相对应</p>
<pre class="brush:php;" title="code">
return array(
&#39;Contents&#39;=&gt;&#39;文章&#39;,
&#39;ID&#39;=&gt;&#39;编号&#39;,
&#39;Cat&#39;=&gt;&#39;分类&#39;,
&#39;Title&#39;=&gt;&#39;标题&#39;,
&#39;Subhead&#39;=&gt;&#39;短标题&#39;,
&#39;Initial&#39;=&gt;&#39;缩写&#39;,
&#39;Author&#39;=&gt;&#39;作者&#39;,
&#39;Source&#39;=&gt;&#39;来源&#39;,
&#39;Source Url&#39;=&gt;&#39;来源url&#39;,
&#39;Summary&#39;=&gt;&#39;摘要&#39;,
&#39;Content&#39;=&gt;&#39;内容&#39;,
&#39;Language&#39;=&gt;&#39;语言&#39;,
&#39;Status&#39;=&gt;&#39;状态&#39;,
&#39;Insert User&#39;=&gt;&#39;添加用户&#39;,
&#39;Insert Time&#39;=&gt;&#39;添加时间&#39;,
&#39;Update User&#39;=&gt;&#39;更新用户&#39;,
&#39;Update Time&#39;=&gt;&#39;更新时间&#39;,
&#39;Tags&#39;=&gt;&#39;标签&#39;,
&#39;Redirecturl&#39;=&gt;&#39;redirecturl&#39;,
&#39;Thumb&#39;=&gt;&#39;thumb&#39;,
&#39;Ishtml&#39;=&gt;&#39;ishtml&#39;,
&#39;Publish Time&#39;=&gt;&#39;publish_time&#39;,
&#39;Alias&#39;=&gt;&#39;alias&#39;,
);</pre>
<p>
	&nbsp;然后可以根据需要通过浏览器或者直接从文件翻译内容。</p>
<p>
	主要用在后台，修改/显示字段对应的名称就很方便了。</p>
<pre class="brush:php;" title="code">
public function attributeLabels()
	{
		return array(
			&#39;id&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;ID&#39;),
			&#39;cat_id&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Cat&#39;),
			&#39;title&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Title&#39;),
			&#39;subhead&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Subhead&#39;),
			&#39;initial&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Initial&#39;),
			&#39;author&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Author&#39;),
			&#39;source&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Source&#39;),
			&#39;source_url&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Source Url&#39;),
			&#39;redirecturl&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Redirecturl&#39;),
			&#39;tags&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Tags&#39;),
			&#39;thumb&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Thumb&#39;),
			&#39;summary&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Summary&#39;),
			&#39;content&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Content&#39;),
			&#39;language&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Language&#39;),
			&#39;ishtml&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Ishtml&#39;),
			&#39;file_name&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;File Name&#39;),
			&#39;status&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Status&#39;),
			&#39;publish_time&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Publish Time&#39;),
			&#39;insert_user&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Insert User&#39;),
			&#39;insert_time&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Insert Time&#39;),
			&#39;update_user&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Update User&#39;),
			&#39;update_time&#39; =&gt; Yii::t(&#39;models/Content&#39;,&#39;Update Time&#39;),
		);
	}</pre>
<p>
	下面是我的后台，</p>
<p>
	<img alt="" src="/upload/images/admin1.png" style="width: 697px; height: 463px;" /></p>
<p>
	<img alt="" src="/upload/images/datadict1_700x267.png" style="width: 700px; height: 267px;" /></p>
<p>
	<img alt="" src="/upload/images/datadict3_700x200.png" style="width: 700px; height: 200px;" /></p>
<p>
	&nbsp;</p>
<p>
	<span style="color: #ff0000">Yii官网在国内实在是时断时续，写的不清楚，各位见谅！</span></p>
<p>
	<a href="/upload/files/datadict.zip">附件下载</a></p>
<p>
	&nbsp;</p>
]]></description>
<link>http://www.chenggang.net/posts/104</link>
<pubDate>Fri, 07 Oct 2011 22:46:22 +0800</pubDate>
<author>小豆</author>
<category>Framework</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/104</guid>
</item>
<item>
<title>关键字高亮/添加超链接</title>
<summary><![CDATA[&nbsp;&nbsp;&nbsp; 博客总是有垃圾留言，考虑自己写一个，可是真动起手来还挺麻烦，需要考虑的挺多。<br />&nbsp;&nbsp;&nbsp;&nbsp;功能方面，1、最主要当然是内容；2、其次是内容之间的关联；3、内容的扩展，比如一篇产品介绍的文章，可能和普通文本的有些区别；4、标签/关键字；5、用户/留言&hellip;&hellip;<br />&nbsp;&nbsp;&nbsp; 稍微规划一下]]></summary>
<description><![CDATA[<p>
	&nbsp;&nbsp;&nbsp; 博客总是有垃圾留言，考虑自己写一个，可是真动起手来还挺麻烦，需要考虑的挺多。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;功能方面，1、最主要当然是内容；2、其次是内容之间的关联；3、内容的扩展，比如一篇产品介绍的文章，可能和普通文本的有些区别；4、标签/关键字；5、用户/留言&hellip;&hellip;<br />
	&nbsp;&nbsp;&nbsp; 稍微规划一下，准备学学TomatoCMS，做成核心+扩展功能的模式，再加一些plugins或者hooks完善周边功能。<br />
	&nbsp;&nbsp;&nbsp; 接下来，两个问题：黑词+关键字。黑词就简单些，屏蔽或者保存的时候提示就行了。关键字就比较麻烦些。主要是关系到SEO与文章的内联，关键词高亮。解决关键词高亮或者添加超链接，无非两种解决途径，生成Html以前添加或者生成Html以后添加。生成Html以前添加相对简单些，替换就完成了。生成Html以后，只能靠JS完成了。这还用若干种解决途径。1、把关键字生成关键字库，JS逐条循环，逐个替换。2、通过ajax，用后台程序替换。目前还没有得到满意的方案，不过看到一个很棒的网站（<a href="http://www.clickeye.cn/">http://www.clickeye.cn</a>），这方面做的不错。</p>
]]></description>
<link>http://www.chenggang.net/posts/102</link>
<pubDate>Thu, 11 Nov 2010 15:23:47 +0800</pubDate>
<author>小豆</author>
<category>Web进阶</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/102</guid>
</item>
<item>
<title>yum安装apache+php+mysql等</title>
<summary><![CDATA[<p>1. 安装Apahce, PHP, Mysql, 以及php连接mysql库组件。<br />　　yum -y install httpd php mysql mysql-server php-mysql <br />　　<br />　　2. 配置开机启动服务<br />　　 /sbin/chkconfig httpd on [设置apache服务器httpd服务开机启动]<br />　　 /sbin/chkconfig --add mysqld [在服务清单中添加mysql服务]<br />　　 ]]></summary>
<description><![CDATA[<p>1. 安装Apahce, PHP, Mysql, 以及php连接mysql库组件。<br />　　yum -y install httpd php mysql mysql-server php-mysql <br />　　<br />　　2. 配置开机启动服务<br />　　 /sbin/chkconfig httpd on [设置apache服务器httpd服务开机启动]<br />　　 /sbin/chkconfig --add mysqld [在服务清单中添加mysql服务]<br />　　 /sbin/chkconfig mysqld on [设置mysql服务开机启动]<br />　　<br />　　 /sbin/service httpd start [启动httpd服务,与开机启动无关]<br />　　 /sbin/service mysqld start [启动mysql服务,与开机无关]<br />　　<br />　　3.设置 mysql数据库root帐号密码。<br />　　mysqladmin -u root password 'newpassword' [引号内填密码]<br />　　<br />　　4. 让mysql数据库更安全<br />　　mysql -u root -p [此时会要求你输入刚刚设置的密码，输入后回车即可]<br />　　<br />　　mysql&gt; DROP DATABASE test; [删除test数据库]<br />　　mysql&gt; DELETE FROM mysql.user WHERE user = ''; [删除匿名帐户]<br />　　mysql&gt; FLUSH PRIVILEGES; [重载权限]<br />　　<br />　　5. 按照以上的安装方式, 配置出来的默认站点目录为/var/www/html/新建一个php脚本:<br />　　 phpinfo();<br />　　?&gt;<br />　　<br />　 　6. 新建一个数据库，添加一个数据库用户，设置用户权限。写个php脚本测试一下数据库连接吧。<br />　　mysql&gt; CREATE DATABASE my_db; <br />　　mysql&gt; GRANT ALL PRIVILEGES ON my_db.* TO 'user'@'localhost' IDENTIFIED BY 'password'; <br />　　<br />　　<br />　　<br />　　//安 装apache扩展<br />　　yum -y install httpd-manual mod_ssl mod_perl mod_auth_mysql<br />　　//安装php的扩展<br />　　yum install php-gd<br />　　yum -y install php-gd php-xml php-mbstring php-ldap php-pear php-xmlrpc<br />　　// 安装mysql扩展<br />　　yum -y install mysql-connector-odbc mysql-devel libdbi-dbd-mysql<br /><br />7， 如果命令行没有phpize，运行以下命令 <br />yum -y install php-devel<br /><br />8，安装pdo<br />pecl install pdo<br />PHP_PDO_SHARED=1 pecl install pdo_mysql<br />php.ini中添加<br />extension=pdo.so<br />extension=pdo_mysql.so<br /><br />9, 安装memcache<br />yum -y install php-pecl-memcache<br /><br />10, 安装php-eaccelerator<br />yum install php-eaccelerator.i686<br /><br /><br /><br />CentOS 5.x 系统下使用yum 升级php到5.2.x 最方便方法 <br />近期使用testlink 1.82 ，提及php需要升级到5.2以上，而centos 5.x目前提供php版本为5.1.6，<br />通过以下方法升级PHP到5.2比较方便，现推荐给大家。</p><p>先将以下地址导入。</p><p># rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka </p><p># vi /etc/yum.repos.d/CentOS-Base.repo 增加下面信息</p><p>[utterramblings]<br />name=Jason's Utter Ramblings Repo<br />baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/<br />enabled=1<br />gpgcheck=1<br />gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka</p><p>执行命令，自动升级。</p><p>yum update php -y<br />yum install libmcrypt -y<br /></p>]]></description>
<link>http://www.chenggang.net/posts/101</link>
<pubDate>Sat, 17 Jul 2010 20:50:48 +0800</pubDate>
<author>admin</author>
<category>默认分类</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/101</guid>
</item>
<item>
<title>Mysql5.1 VS SQL Server 2008</title>
<summary><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最近在做一个项目，从C#转到PHP，为了先实现原有的功能，很多都是按原来的逻辑直接搬过来的，尤其sql，但是感叹于mysql与sql Server之间的差异，太大了。其中一个sql语句，sql server执行只用了0.187s，mysql用了118.219s，简直天壤之别。要说明的是sql server安装在Compaq 6502s上，mysql安装在HP DL 385 G1（G]]></summary>
<description><![CDATA[<p>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最近在做一个项目，从C#转到PHP，为了先实现原有的功能，很多都是按原来的逻辑直接搬过来的，尤其sql，但是感叹于mysql与sql Server之间的差异，太大了。其中一个sql语句，sql server执行只用了0.187s，mysql用了118.219s，简直天壤之别。要说明的是sql server安装在Compaq 6502s上，mysql安装在HP DL 385 G1（GenuineIntel: Intel(R) Xeon(R) CPU E5430 @ 2.66GHz * 8）。<br />
	<br />
	&nbsp;&nbsp;&nbsp;&nbsp; 这样的话以后真用sql server了。</p>
]]></description>
<link>http://www.chenggang.net/posts/100</link>
<pubDate>Sun, 13 Jun 2010 22:29:09 +0800</pubDate>
<author>小豆</author>
<category>MySql数据库</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/100</guid>
</item>
<item>
<title>Yii Framework的gii使用方法及模板</title>
<summary><![CDATA[	Yii Framework 1.1.2版本中已经有了gii，
	就是一个基于web的脚手架！可以生成模型，控制器，视图等！
	
	一、配置
	配置protected/config/main.php
	
	&#39;modules&#39;=&gt;array(
	&#39;gii&#39;=&gt;array(
	&#39;class&#39;=&gt;&#39;system.gii.G...]]></summary>
<description><![CDATA[<p>
	Yii Framework 1.1.2版本中已经有了gii，<br />
	就是一个基于web的脚手架！可以生成模型，控制器，视图等！<br />
	<br />
	一、配置<br />
	配置protected/config/main.php</p>
<pre class="brush:php;" title="code">
&#39;modules&#39;=&gt;array(
&#39;gii&#39;=&gt;array(
&#39;class&#39;=&gt;&#39;system.gii.GiiModule&#39;,
&#39;password&#39;=&gt;&#39;123456&#39;,
//&#39;ipFilters&#39;=&gt;array(&#39;192.168.1.101&#39;),
//如果用IP访问,这里需配置相应的IP
),
 ),</pre>
<p>
	我们可以通过以下链接来访问: /index.php?r=gii<br />
	&nbsp;</p>
<ol>
	<li>
		进入生成器页面；</li>
	<li>
		填写字段以指定代码生成器的参数。例如，要使用module 生成器创建一个新模块，你需要指定模块ID；</li>
	<li>
		点击 Preview 按钮预览生成的代码。你将看到一个表展示了将被生成的一个代码文件列表。你可以点击其中的任何文件以预览代码。</li>
	<li>
		点击 Generate 按钮以生成代码文件；</li>
	<li>
		查看代码生成日志。</li>
</ol>
<p>
	<a name="readmore"></a><br />
	二、自定义模板</p>
<p>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;尽管默认的代码生成器已经可以产生很强大的代码，我也经常希望能定制他们或者创建个新的来满足我们的需求，例如，我们希望生成的代码能符合我们的编码风格，或者我们希望代码能支持国际化，这些都可以轻松的通过Gii实现 Gii 可以通过两种模式进行扩展：定制代码模板来扩展已有的代码生成器，和编写新的代码生成器。<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Gii 通过GiiModule::generatorPaths属性设置的路径搜索可用的代码生成器。如果需要定制，我们可以在应用的配置中如下配置这个属性。<br />
	&#39;gii&#39; &nbsp;&nbsp;=&gt; array(<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;class&#39; &nbsp;=&gt; &#39;system.gii.GiiModule&#39;,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;password&#39; =&gt; &#39;123456&#39;,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;generatorPaths&#39;=&gt;array( &#39;application.gii&#39;), //除了在默认的system.gii.generators之外，还在路径别名为application.gii的目录下检索可用的代码生成器<br />
	&nbsp;&nbsp;),<br />
	&nbsp;&nbsp;&nbsp; 有可能会在不同的目录底下有相同名字的代码生成器，这种情况下在GiiModule::generatorPaths中最先指定的，具有优先权。</p>
<p>
	<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们首先创建一个名为protected/gii/model/templates/compact的路径。这里的model意味着我们要重写摩尔恩的model代码生成器。templates/compact 表示我们要添加一个新的代码模板，名字为compact，然后我们修改应用的配置，把application.gii加入到 GiiModule::generatorPaths中，如同上面所叙现在打开model代码生成器页面。点击代码模板字段，在出现的下拉框里我们能看到我们新加的模板路径compact，如果我们选择这个模板来生成代码，我们会看到一个错误，那是因为我们还没有在compact底下放入任何的实际代码模板。</p>
<p>
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;下面开始我们真正的自定义的工作。打开文件protected/gii/model/templates/compact/model.php进行编辑。记住这个文件会像被作为视图文件使用，这意味着它可以包含PHP语句和声明。让我们修改模板，以便生成器产生的attributeLabels()方法，使用Yii::t()来对标签支持国际化。<br />
	<span class="php-hl-reserved">public</span> <span class="php-hl-reserved">function</span> <span class="php-hl-identifier">attributeLabels</span><span class="php-hl-brackets">(</span><span class="php-hl-brackets">)</span><br />
	<span class="php-hl-brackets">{</span><br />
	&nbsp;&nbsp;&nbsp; <span class="php-hl-reserved">return</span> <span class="php-hl-reserved">array</span><span class="php-hl-brackets">(</span><br />
	<span class="php-hl-code">&lt;?</span><span class="php-hl-identifier">php</span> <span class="php-hl-reserved">foreach</span><span class="php-hl-brackets">(</span><span class="php-hl-var">$labels</span> <span class="php-hl-reserved">as</span> <span class="php-hl-var">$name</span><span class="php-hl-code">=&gt;</span><span class="php-hl-var">$label</span><span class="php-hl-brackets">)</span><span class="php-hl-code">: ?&gt;<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;?</span><span class="php-hl-identifier">php</span> <span class="php-hl-reserved">echo</span> <span class="php-hl-quotes">&quot;</span><span class="php-hl-string">&#39;</span><span class="php-hl-var">$name</span><span class="php-hl-string">&#39; =&gt; Yii::t(&#39;application&#39;, &#39;</span><span class="php-hl-var">$label</span><span class="php-hl-string">&#39;),</span><span class="php-hl-special">\n</span><span class="php-hl-quotes">&quot;</span><span class="php-hl-code">; ?&gt;<br />
	&lt;?</span><span class="php-hl-identifier">php</span> <span class="php-hl-reserved">endforeach</span><span class="php-hl-code">; ?&gt;<br />
	&nbsp;&nbsp;&nbsp; </span><span class="php-hl-brackets">)</span><span class="php-hl-code">;</span><br />
	<span class="php-hl-brackets">}</span></p>
<p>
	<span class="php-hl-brackets">在每一个代码模板，我们可以访问一些预定义的变量，例如上面例子中的$labels。这些变量由相应的代码生成器产生。不同的代码生成器在他们各自的模板中可能产生不同的变量。请仔细阅读默认代码模板的中的描述。</span></p>
<br />
]]></description>
<link>http://www.chenggang.net/posts/99</link>
<pubDate>Sun, 30 May 2010 08:59:25 +0800</pubDate>
<author>小豆</author>
<category>Framework</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/99</guid>
</item>
<item>
<title>Mapper、DataGateway、ActiveRecord之一二</title>
<summary><![CDATA[最近在看Doctrine，但是搞不清ORM、Mapper、DataGateway、ActiveRecord都是个什么概念？他们之间什么关系？那种的效率高？ZF给的demo中用的Default_Model_GuestbookMapper，网上又有诸多的ActiveRecord，Qee的Model是属于那种呢？Yii的CActiveRecord又属于哪种呢？<br /><br />下面是摘录网友的笔记。<br /><br />我们讨论的问题目的在于如何让我们系统中的对象与数据库进行交互。由于数据库与对象之间存]]></summary>
<description><![CDATA[最近在看Doctrine，但是搞不清ORM、Mapper、DataGateway、ActiveRecord都是个什么概念？他们之间什么关系？那种的效率高？ZF给的demo中用的Default_Model_GuestbookMapper，网上又有诸多的ActiveRecord，Qee的Model是属于那种呢？Yii的CActiveRecord又属于哪种呢？<br /><br />下面是摘录网友的笔记。<br /><br />我们讨论的问题目的在于如何让我们系统中的对象与数据库进行交互。由于数据库与对象之间存在着结构上的差异，Mapping是相当困难的。作者不推荐开发人员自己进行Mapping Layer的开发，这是危险的也是及其可能失败的。作者推荐购买专业的工具，虽然这些工具通常很昂贵。我没见过这种工具，到目前为止，我所接触的项目确实有Mapping layer，但它并不是典型的Mapping layer between Relational Database and Object，它是处于JSP页面与Database之间的Mapping，用于自动地将用户在页面上填写的数据更新到数据库中。这在Web项目中是很好用的，但目前这个Mapping Layer还不能做到general，它只能适用与特定的Web Application架构。(:^), 跑题了!!!!)下面开始与大家聊聊三种Database Mapping层的常用的系统架构。 <br /><a name="readmore"></a><br /><span style="color: red"><strong>1. 网关模式（Gateway）</strong></span> <br />之所以称之&ldquo;网关&rdquo;，顾名思义，Mapping层扮演着一个代理的角色，应用逻辑层无需知道具体Mapping的细节，而只需通过网关的公共接口，提交数据更新或者数据加载请求，由网关去执行具体的Object到Record或者Record到Object的转换。从而实现了数据层的透明。应用逻辑层所要了解的只有网关的信息和其公共接口。使用公共接口同时有助应用逻辑代码在不同的数据层的复用：无需改变应用逻辑层的任何代码，只需为特定的数据层实现特定的网关。网关模式具体分为两种：Row Data Gateway &amp; Table Data Gateway <br /><strong><span style="color: green">共同的特点</span></strong>： <br />对应于数据库中的每个Table，有一个Mapping Class，并且在这个class中每个column有其对应的字段；所有的数据库mapping代码都存在于在Mapping Class之中，使数据库访问代码与应用逻辑完全分离； <br /><strong><span style="color: green">Row Data Gateway</span></strong> <br />Mapping Class是一个对应于数据库中某张表格的一条记录。记录的每个字段对应于Class中的一个Field。所有访问数据的细节都被封装在这个接口中。Row Data Gateway与Transaction Script配合使用，效果很好 <br /><strong>典型案例</strong>: Java中的SessionBean（Transaction Script）和EntityBean（Row Data Gateway） <br /><strong>适用情况</strong>：应用逻辑相对复杂，对象与对象之间交互繁多的大规模系统； <br /><br /><span style="color: green"><strong>Table Data Gateway</strong></span>： <br />这个接口定义了关于某个Table的所有查询（find），更新，插入和删除代码。Table Data Gateway将输入的参数mapping成对应的SQL，并执行SQL，最后返回适当的数据结构。如何返回Query的信息是一个具有欺骗性的决策问题。当需要返回多个记录并且函数只允许返回一个结果时，你将面临着多种选择：Map &amp; Data Transfer Object &amp; Record Set。 <br />Map：不是一个好方法，map中的Key常常是一种HardCode； <br />Data Transfer Object：是避免map的一个方法，并且可以被重用； <br />Record Set：虽然会使Business Logic Layer不能完全与数据库访问层相分离，但是如果我们的开发平台有很多基于Record Set的工具，采用它不失为一个好方法（.NET）。 <br /><strong>典型案例</strong>：Window DNA架构； <br /><strong>适用情况</strong>：以显示信息，修改信息为功能的MIS（信息管理系统）； <br /><br /><span style="color: red"><strong>2. 活动记录模式（Active Record）</strong></span> <br />将Business Logic与数据库访问放置于同一个Business Object中。这种模式出现的原因是业务逻辑与数据库模型非常相似。Active Record同时负责数据库存取和基于这些数据的应用逻辑的执行。应用程序的所有逻辑可以都在Active Record中，也可以是部分。有一点是默认前提，Active Record的数据结构和数据库Schema必须保持一致（在我看来这是个缺点！） <br /><br />Active Record中通常有以下方法： <br /><strong>*</strong> 从SQL数据集创建Active Record的构建方法； <br /><strong>*</strong> 静态的finder方法用于封装SQL查询并且返回Active Record记录； <br /><strong>*</strong> 用Active Record中的数据更新数据库的方法； <br /><strong>*</strong> 所有字段getting和settting方法； <br /><strong>*</strong> 实现应用逻辑的方法； <br /><br />活动记录模式的优点在于简单，其缺点在于没有隐藏数据库层，从而导致很难应用其他OR Mapping模式在活动记录模式之上。另外一方面，活动记录模式与Row Data Gateway的区别在于数据库存取代码是在Business Object中（Active Record）还是在一个单独的Mapping Class中（Row Data Gateway），当然也有同时存在于两者的情况；如果应用逻辑的复杂程度迫使你适用面向对象的一些机制（Direct relationships，collections and Inheritance），这时直接将数据库存取代码置于Business Object中，由于有大量的转换，会使事情变得混乱，这时应该适用Data Mapper。 <br />但这并不是个好方法，因为它将面向对象设计和数据库设计紧密耦合在一起，这随着项目进展会使对设计的重构工作变得及其困难。通常我们会将数据库访问代码分离到一个Gateway中。有一种情况例外，当你对Transaction Script &amp; Row Data Gateway的架构进行重构的时候，为了去除Transaction Script中的重复代码，将其放进Row Data Gateway中，这是就转变成Active Record了。 <br /><br />适用情况：当应用逻辑不复杂，主要是创建，更新，插入，删除操作，而且操作主要是针对单条记录时； <br /><br /><span style="color: red"><strong>3. 数据映射模式（Data Mapper）</strong></span> <br />这是最复杂，但最灵活的一种架构模式。使用Data Mapper，Business Objects可以与数据库结构完全的分离，他们无需知道数据库的结构和数据更新的细节。Data Mapper对于那些无法在关系型数据库表示的对象系统特性非常有效，例如Collection成员结构和继承关系。Data Mapper是内存中对象与数据库之间的媒介。它负责双方之间的数据传输。数据映射模式（Data Mapper）与网关模式最大的（Gateway）最大的区别在于依赖和控制的位置相反。在网关模式中，应用逻辑层需要了解数据库中的数据结构，二在数据映射模式中，应用逻辑无需了解数据库设计，提高了应用层（business logic）和数据层（data source）的分离，便于两者的开发和测试。 <br />面向对象的对象系统与面向关系的关系型数据库是两种异构的结构，因此在对象系统中的很多机制（collections, inheritance等）都无法在关系型数据库中得到直接的表示，这就是数据映射模式产生的原因。在这种情况下，在两种模式下的数据转换变得相当复杂，因此我们有必要将它分层，否则任何一方（对象系统和数据库）的改变都将波及对方。 <br />数据映射层的最大目标就是将业务逻辑（domain）和数据层（data source）分离。整个数据映射层（Data Mapper）完全独立于系统其他部分，可以被完全替换或者允许一个逻辑层重用于不同的数据层上。但要实现它有很多重要的问题必须解决，而且不同人可以采用不同的方法实现这个数据映射模式（Data Mapper）。因此这里只介绍几个重要的实现问题。 <br /><br /><span style="color: green"><strong>① Finder方法的处理</strong></span> <br />处理方法： <br />在一个独立的Package中，为Finder方法定义一个接口，然后在数据映射层实现这个接口。逻辑层通过接口调用Finder方法，后者通过数据映射层加载数据。 <br />原因：之所以使用接口的原因，在于使Finder方法标准化，这样应用逻辑层虽然可能在任何地方都会调用Finder方法取得带有数据的Business Object，但却不依赖于数据映射层。 <br />Finder方法：将方法调用转换成SQL查询； <br />数据映射层：从数据集中获得数据并创建Business Object； <br /><br />遗留问题： <br /><strong>*</strong> 数据映射层如何知道那些Object被更新了，哪些被创建，哪些被删除了？ <br /><strong>*</strong> 如何控制每次查询获得的记录数，以尽量减少查询的数目？ <br /><strong>*</strong> 其他模式如何用在数据映射层（Lazy Load, Registry, Identity Map）? <br /><br /><span style="color: green"><strong>② 如何将数据映射到Business Object的字段中</strong></span> <br />数据映射层需要访问Business Object的所有字段，因此这些方法必须被设置为public，但这不不是我们所预想的。这个问题没有明确的答案，几种可选的方法都有两面性。 <br /><strong>*</strong> 将数据映射层于逻辑层放置于同一个包下 <br />缺点：有可能使事情变得更混乱； <br /><strong>*</strong> 使用Reflection方法来访问Object的字段 <br />缺点：速度慢； <br /><strong>*</strong> 增加状态标志来保证在数据库加载环境下访问这些字段 <br /><br />针对这个问题，在创建Business Object的时候，你有两个选择，使用胖构造函数（这个名词是我自己取的:^)）空构造函数。 <br />胖构造函数（Rich Constructor） <br />优点：保证Object至少包含必须的数据；对于常量字段，无需setting方法； <br />缺点：必须考虑循环引用问题（cyclic reference）； <br /><br />空构造函数（Empty Constructor） <br />优点：不会出现循环引用问题（cyclic reference）； <br />缺点：对于常量字段，仍然需要setting方法，可能引入潜在错误； <br /><br />③ 基于元数据的映射（Metadata based Mapping） <br /><strong>*</strong> 显式代码：这要求每个Business Object有一个Mapping class； <br /><strong>*</strong> Metadata Mapping：元数据被存储在单独的class和文件中，我倾向于文件，随着xml的广泛使用，以XML形式存储元数据会增强移植性； <br /><br /><span style="color: red"><strong>3种OR Mapping架构模式的取舍和选用</strong></span> <br />OR Mapping架构取决于应用逻辑层的架构。如果使用表模式（Table Module）来组织应用逻辑，那么Table Data Gateway是你的最佳选择；如果使用Transaction Script模式来组织应用逻辑，那么如果开发平台提供了使用数据集的方便就采用Table Data Gateway，否则采用Row Data Gateway；如果是使用Domain Model来建立应用逻辑模型，那么对于复杂的大系统，颖毫不犹豫地选择数据映射模式，对于逻辑简单的小系统，Active Record也是一个可选方案。<br /><br />摘至：<a href="http://epubcn.rubypdf.com/read-htm-tid-12435-uid-10830.html" target="_blank">http://epubcn.rubypdf.com/read-htm-tid-12435-uid-10830.html</a>]]></description>
<link>http://www.chenggang.net/posts/98</link>
<pubDate>Tue, 18 May 2010 15:05:23 +0800</pubDate>
<author>admin</author>
<category>php/java</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/98</guid>
</item>
<item>
<title>jquery调试函数$.dump</title>
<summary><![CDATA[<p>//调试函数$.dump();<br />jQuery(function($) {</p><p>&nbsp;&nbsp;&nbsp; /* 判断id是否为null */<br />&nbsp;&nbsp;&nbsp; $.idisnull = function(id)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $$(id) === null;<br />&nbsp;&nbsp;&n]]></summary>
<description><![CDATA[<p>//调试函数$.dump();<br />jQuery(function($) {</p><p>&nbsp;&nbsp;&nbsp; /* 判断id是否为null */<br />&nbsp;&nbsp;&nbsp; $.idisnull = function(id)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return $$(id) === null;<br />&nbsp;&nbsp;&nbsp; };</p><p>&nbsp;&nbsp;&nbsp; /* 获取dom对象 */<br />&nbsp;&nbsp;&nbsp; function $$(id)<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return document.getElementById(id);<br />&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;&nbsp;&nbsp; /* 超级强大的输出测试 */<br />&nbsp;&nbsp;&nbsp; $.dump = function( msg,time )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time = time &amp;&amp; time * 1000 &#124;&#124; 2000;</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (typeof msg === &quot;string&quot;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg = msg.indexOf('&#124;') != -1 &amp;&amp; '&lt;p&gt;'+ msg.split('&#124;').join('&lt;/p&gt;&lt;p&gt;') &#124;&#124;'&lt;p&gt;' + msg ;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (typeof msg === 'object')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var msgs = new Array();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(var p in msg)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msgs.push(p + ':&amp;nbsp;' + msg[p]);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; msg = '&lt;p&gt;' + msgs.join('&lt;/p&gt;&lt;p&gt;');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( $.idisnull('debug_dump') )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $('body').prepend('&lt;div id=&quot;debug_dump&quot;&gt;&lt;/div&gt;');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $('div#debug_dump')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .css({<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; position&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 'absolute',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; backgroundColor : '#000',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opacity&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '0.65',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '0',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; left&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '0',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : $('body').width(),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lineHeight&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '28px',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zIndex&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '99999',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textIndent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '20px',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; color&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : '#fff'<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; })<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .html('输出结果是： '+ msg +'&lt;/p&gt;')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .click(function(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(this).mouseout(function(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setTimeout(function(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $('div#debug_dump').fadeOut('slow').empty().remove();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },time);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; });<br />&nbsp;&nbsp;&nbsp; };</p><p>});</p>]]></description>
<link>http://www.chenggang.net/posts/97</link>
<pubDate>Sun, 16 May 2010 17:58:31 +0800</pubDate>
<author>admin</author>
<category>Jquery</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/97</guid>
</item>
<item>
<title>Zend Application之application.ini配置，基于多模板、多module的（1.8以上）</title>
<summary><![CDATA[在Zend Framework1.8以后加入的Zend_Application，可以说 Zend_Application 和其引入的 Bootstrap 及 Resource 概念，大大简化了应用程序的初始化组装过程。<br /><br />下面主要说下Bootstrap.php及application.ini的配置。<br />]]></summary>
<description><![CDATA[<p>
	在Zend Framework1.8以后加入的Zend_Application，可以说 Zend_Application 和其引入的 Bootstrap 及 Resource 概念，大大简化了应用程序的初始化组装过程。<br />
	<br />
	下面主要说下Bootstrap.php及application.ini的配置。<br />
	<a name="readmore"></a><br />
	1.Bootstrap<br />
	class Bootstrap extends Zend_Application_Bootstrap_Bootstrap中主要做些初始化的工作，以_init开头的function都会在加载的过程中被运行。举例如下：<br />
	class Bootstrap extends Zend_Application_Bootstrap_Bootstrap<br />
	{<br />
	protected function _initConfig()<br />
	{<br />
	$config = new Zend_Config($this-&gt;getOptions());<br />
	Zend_Registry::set(&#39;config&#39;, $config);<br />
	return $config;<br />
	}<br />
	<br />
	protected function _initView()<br />
	{<br />
	//Different view implementation<br />
	$extraParams = $this-&gt;getOption(&#39;smarty&#39;);<br />
	$view = new Custom_View_Smarty($extraParams);<br />
	$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);<br />
	$viewRenderer-&gt;setViewSuffix(&#39;html&#39;);<br />
	Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);<br />
	}<br />
	<br />
	public function _initDoctrine()<br />
	{<br />
	require_once &#39;Doctrine.php&#39;;<br />
	$loader = Zend_Loader_Autoloader::getInstance();<br />
	$loader-&gt;pushAutoloader(array(&#39;Doctrine&#39;, &#39;autoload&#39;));<br />
	<br />
	$doctrineConfig = $this-&gt;getOption(&#39;doctrine&#39;);<br />
	$connectionString = $this-&gt;getOption(&#39;resources&#39;);<br />
	<br />
	$dsn = new PDO(&#39;mysql:dbname=&#39; . $connectionString[&#39;db&#39;][&#39;params&#39;][&#39;dbname&#39;] .<br />
	&#39;;host=&#39; . $connectionString[&#39;db&#39;][&#39;params&#39;][&#39;host&#39;],<br />
	$connectionString[&#39;db&#39;][&#39;params&#39;][&#39;username&#39;],<br />
	$connectionString[&#39;db&#39;][&#39;params&#39;][&#39;password&#39;]);<br />
	<br />
	$manager = Doctrine_Manager::getInstance();<br />
	$manager-&gt;setAttribute(<br />
	Doctrine::ATTR_MODEL_LOADING,<br />
	Doctrine::MODEL_LOADING_CONSERVATIVE);<br />
	<br />
	// Add models and generated base classes to Doctrine autoloader<br />
	Doctrine::loadModels($doctrineConfig[&#39;models_path&#39;]);<br />
	<br />
	$manager-&gt;openConnection($dsn);<br />
	<br />
	return $manager;<br />
	}<br />
	}<br />
	<br />
	主要是做一些初始化的工作。<br />
	<br />
	2、application.ini<br />
	application.ini主要是配置Zend_Application_Resource的参数。<br />
	Zend_Application_Resource是 Zend Framework 针对 php 这种 web 开发语言的特性而加入的。它所阐述的思想是：<strong>按需加载 (Loaded On Demand)</strong> 。因为 php 每次解析都是资源循环的完整过程，这使得如何将每次php解析的代码量减至最低，就成了优化php应用程序的重要一环，也是众多框架在开发过程中的重点问题之一。</p>
<p>
	目前 Zend Framework 1.8 提供的默认资源总共10个：</p>
<p>
	&nbsp;</p>
<p>
	1. Zend_Application_Resource_Db</p>
<p>
	2. Zend_Application_Resource_Frontcontroller</p>
<p>
	3. Zend_Application_Resource_Layout</p>
<p>
	4. Zend_Application_Resource_Locale</p>
<p>
	5. Zend_Application_Resource_Modules</p>
<p>
	6. Zend_Application_Resource_Navigation</p>
<p>
	7. Zend_Application_Resource_Router</p>
<p>
	8. Zend_Application_Resource_Session</p>
<p>
	9. Zend_Application_Resource_Translate</p>
<p>
	10. Zend_Application_Resource_View<br />
	<br />
	在application.ini中配置的参数，会自动加载到resource中，自动完成初始化的过程。我的配置如下：<br />
	[production]<br />
	includePaths.library = APPLICATION_PATH &quot;/../libs&quot;<br />
	appnamespace = &quot;Application&quot;</p>
<p>
	;=========== 类自动加载的前缀<br />
	autoloadernamespaces.0 = &quot;Zend_&quot;<br />
	autoloadernamespaces.1 = &quot;Custom_&quot;</p>
<p>
	;=========== php ini配置<br />
	phpsettings.date.timezone = &quot;Asia/Shanghai&quot;<br />
	phpSettings.display_startup_errors = 1<br />
	phpSettings.display_errors = 1<br />
	phpsettings.error_reporting = 8191</p>
<p>
	;=========== bootstrap类的路径及类名<br />
	bootstrap.path = APPLICATION_PATH &quot;/Bootstrap.php&quot;<br />
	bootstrap.class = &quot;Bootstrap&quot;</p>
<p>
	;=========== front controller配置<br />
	resources.frontController.moduleDirectory = APPLICATION_PATH &quot;/modules/&quot;<br />
	resources.frontController.moduleControllerDirectoryName = &quot;controllers&quot;<br />
	resources.frontController.defaultModule = &quot;default&quot;<br />
	resources.frontController.defaultControllerName = &quot;index&quot;<br />
	resources.frontController.defaultAction = &quot;index&quot;<br />
	resources.frontController.baseUrl = &quot;/www&quot;<br />
	resources.frontController.noErrorHandler = 1<br />
	resources.frontController.throwExceptions = 1</p>
<p>
	;============网站模块(不同模块对应不同layout,与不同的ViewHelper)<br />
	resources.view.params.default.basePath = APPLICATION_PATH &quot;/modules/default/views/&quot;<br />
	;resources.view.params.default.helperPath = &quot;Custom/View/Helper/Default/&quot;<br />
	;resources.view.params.default.layout = &quot;default&quot;<br />
	;resources.view.params.default.layoutPath = APPLICATION_PATH &quot;/modules/default/views/layouts&quot;</p>
<p>
	;=========== 数据库配置<br />
	resources.db.adapter = &quot;pdo_mysql&quot;<br />
	resources.db.params.host = &quot;localhost&quot;<br />
	resources.db.params.username = &quot;test&quot;<br />
	resources.db.params.password = &quot;123456&quot;<br />
	resources.db.params.dbname = &quot;test&quot;<br />
	resources.db.params.prefix = &quot;tt_&quot;<br />
	resources.db.isDefaultTableAdapter = true<br />
	resources.db.params.driver_options.1002 = &quot;SET NAMES UTF8;&quot;</p>
<p>
	;============smarty<br />
	smarty.left_delimiter = &quot;&lt;{&quot;<br />
	smarty.right_delimiter = &quot;}&gt;&quot;<br />
	smarty.caching = 0</p>
<p>
	;============网站生成Cache配置<br />
	cache.type = file<br />
	cache.dir = APPLICATION_PATH &quot;/cache/&quot;<br />
	cache.pagedir = APPLICATION_PATH &quot;/cache/page/&quot;<br />
	cache.lifetime = 7200<br />
	cache.automatic_serialization = TRUE</p>
<p>
	;=================== doctrine ===========<br />
	doctrine.data_fixtures_path = APPLICATION_PATH &quot;/doctrine/data/fixtures&quot;<br />
	doctrine.models_path = APPLICATION_PATH &quot;/models&quot;<br />
	doctrine.migrations_path = APPLICATION_PATH &quot;/doctrine/migrations&quot;<br />
	doctrine.sql_path = APPLICATION_PATH &quot;/doctrine/data/sql&quot;<br />
	doctrine.yaml_schema_path = APPLICATION_PATH &quot;/doctrine/schema&quot;<br />
	<br />
	<br />
	参考：<br />
	1、<a href="http://www.oophp.cn/article/view/id/368">http://www.oophp.cn/article/view/id/368</a><br />
	2、<a href="http://kbs.kimbs.cn/blog/list/post/8/title/building-multi-modules-and-multi-templates-application-using-Zend_Application">http://kbs.kimbs.cn/blog/list/post/8/title/building-multi-modules-and-multi-templates-application-using-Zend_Application</a></p>
]]></description>
<link>http://www.chenggang.net/posts/96</link>
<pubDate>Thu, 06 May 2010 15:10:15 +0800</pubDate>
<author>小豆</author>
<category>Framework</category>
<guid isPermaLink="true">http://www.chenggang.nethttp://www.chenggang.net/posts/96</guid>
</item>
</channel></rss>
