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

<channel>
	<title>程序员 in the house &#187; LAMP</title>
	<atom:link href="http://blog.thinklet.net/franky/category/lamp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.thinklet.net/franky</link>
	<description>跳街舞比我劲的，写程序没我历害；写程序比我历害的，跳街舞比不上我。</description>
	<lastBuildDate>Sun, 18 Apr 2010 16:20:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>使用Xdebug深入调试PHP</title>
		<link>http://blog.thinklet.net/franky/2010/02/23/shiyongxdebugshenrudiaoshiphp/</link>
		<comments>http://blog.thinklet.net/franky/2010/02/23/shiyongxdebugshenrudiaoshiphp/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 15:24:56 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=174</guid>
		<description><![CDATA[Xdebug功能简介
Xdebug是PHP的一个插件(zend_extension)。主页：http://www.xdebug.org/。它提供大供php的调试信息。主要包含以下内容：

在错误信息中提供 层级跟踪 并且 功能跟踪。

为用户定义的函数展现全部参数
展现函数名，文件名，代码行数
支持成员函数


内存分配
防止死循环
PHP脚本的概况分析
代码覆盖范围分析
能够通过客户端软件调试PHP脚本

其中1,2,3是Xdebug默认提供的功能。只要启用了Xdebug就可以使用了。
如何使用PHP脚本的概况分析功能？
xdebug.profiler_enable 设为On，默认为Off


]]></description>
			<content:encoded><![CDATA[<p><strong>Xdebug功能简介</strong></p>
<p>Xdebug是PHP的一个插件(zend_extension)。主页：<a href="http://www.xdebug.org/">http://www.xdebug.org/</a>。它提供大供php的调试信息。主要包含以下内容：</p>
<ol>
<li>在错误信息中提供 层级跟踪 并且 功能跟踪。
<ul>
<li>为用户定义的函数展现全部参数</li>
<li>展现函数名，文件名，代码行数</li>
<li>支持成员函数</li>
</ul>
</li>
<li>内存分配</li>
<li>防止死循环</li>
<li>PHP脚本的概况分析</li>
<li>代码覆盖范围分析</li>
<li>能够通过客户端软件调试PHP脚本</li>
</ol>
<p>其中1,2,3是Xdebug默认提供的功能。只要启用了Xdebug就可以使用了。</p>
<p><strong><span style="font-weight: normal">如何使用PHP脚本的概况分析功能？</span></strong></p>
<p><strong><span style="font-weight: normal"><a href="http://www.xdebug.org/docs/all_settings#profiler_enable">xdebug.profiler_enable</a> 设为On，默认为Off</span></strong></p>
<p><strong><span style="font-weight: normal"><br />
</span></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2010/02/23/shiyongxdebugshenrudiaoshiphp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux下的time 命令</title>
		<link>http://blog.thinklet.net/franky/2010/01/10/linuxxiadetimemingling/</link>
		<comments>http://blog.thinklet.net/franky/2010/01/10/linuxxiadetimemingling/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 07:00:27 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=169</guid>
		<description><![CDATA[time命令在测试程序效率的时候很有用，也很方便。
它以秒为单位将一条命令执行期间所用的时间、系统时间和 time 命令的执行时间打印在标准错误中。
例如：
说明
执行命令行”command [arguments...]“，命令行执行结束时在标准输出中打印执行该命令行的时间统计结果，其统计结果包含以下数据：
1)实际时间(real time): 从command命令行开始执行到运行终止的消逝时间；
2)用户CPU时间(user CPU time): 命令执行完成花费的用户CPU时间，即命令在用户态中执行时间总和；
3)系统CPU时间(system CPU time): 命令执行完成花费的系统CPU时间，即命令在核心态中执行时间总和。
其中，用户CPU时间和系统CPU时间之和为CPU时间，即命令占用CPU执行的时间总和。实际时间要大于CPU时间，因为Linux是多任务操作系统，往往在执行一条命令时，系统还要处理其它任务。
另一个需要注意的问题是即使每次执行相同命令，但所花费的时间也是不一样，其花费时间是与系统运行相关的。
例1：
1. # time date
2. Sun Mar 26 22:45:34 GMT-8 2006
3.
4. real    0m0.136s
5. user    0m0.010s
6. sys     0m0.070s
7. #
在例1中，执行命令”time date”(见第1行)。系统先执行命令”date”，第2行为命令”date”的执行结果。第3-6行为执行命令”date”的时间统计结果，其中第4 行”real”为实际时间，第5行”user”为用户CPU时间，第6行”sys”为系统CPU时间。以上三种时间的显示格式均为 MMmNN[.FFF]s。
在例1中，CPU时间 = 用户CPU时间 + 系统CPU时间 = 0m0.010s + 0m0.070s = 0m0.080s，实际时间大于CPU时间，说明在date命令运行的同时，还有其它任务在运行.
time命令还可以拿测试php等脚本效率。
例如：time php test.php
]]></description>
			<content:encoded><![CDATA[<p>time命令在测试程序效率的时候很有用，也很方便。</p>
<p>它以秒为单位将一条命令执行期间所用的时间、系统时间和 time 命令的执行时间打印在标准错误中。<br />
例如：<br />
说明<br />
执行命令行”command [arguments...]“，命令行执行结束时在标准输出中打印执行该命令行的时间统计结果，其统计结果包含以下数据：<br />
1)实际时间(real time): 从command命令行开始执行到运行终止的消逝时间；<br />
2)用户CPU时间(user CPU time): 命令执行完成花费的用户CPU时间，即命令在用户态中执行时间总和；<br />
3)系统CPU时间(system CPU time): 命令执行完成花费的系统CPU时间，即命令在核心态中执行时间总和。<br />
其中，用户CPU时间和系统CPU时间之和为CPU时间，即命令占用CPU执行的时间总和。实际时间要大于CPU时间，因为Linux是多任务操作系统，往往在执行一条命令时，系统还要处理其它任务。<br />
另一个需要注意的问题是即使每次执行相同命令，但所花费的时间也是不一样，其花费时间是与系统运行相关的。<br />
例1：<br />
1. # time date<br />
2. Sun Mar 26 22:45:34 GMT-8 2006<br />
3.<br />
4. real    0m0.136s<br />
5. user    0m0.010s<br />
6. sys     0m0.070s<br />
7. #<br />
在例1中，执行命令”time date”(见第1行)。系统先执行命令”date”，第2行为命令”date”的执行结果。第3-6行为执行命令”date”的时间统计结果，其中第4 行”real”为实际时间，第5行”user”为用户CPU时间，第6行”sys”为系统CPU时间。以上三种时间的显示格式均为 MMmNN[.FFF]s。<br />
在例1中，CPU时间 = 用户CPU时间 + 系统CPU时间 = 0m0.010s + 0m0.070s = 0m0.080s，实际时间大于CPU时间，说明在date命令运行的同时，还有其它任务在运行.</p>
<p>time命令还可以拿测试php等脚本效率。<br />
例如：time php test.php</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2010/01/10/linuxxiadetimemingling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>编写PHP扩展之环境准备:GNU autoconf, automake,libtoolm4</title>
		<link>http://blog.thinklet.net/franky/2009/12/27/bianxiephpkuozhanzhihuanjingzhunbeignuautoconfautomakelibtoolm4/</link>
		<comments>http://blog.thinklet.net/franky/2009/12/27/bianxiephpkuozhanzhihuanjingzhunbeignuautoconfautomakelibtoolm4/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 14:16:05 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=163</guid>
		<description><![CDATA[PREPARING YOUR SYSTEM
  While the result will run on any system, a developer&#8217;s setup needs these
  tools:
    GNU autoconf
    GNU automake
    GNU libtool
    GNU m4
  All of these are available from 
    ftp://ftp.gnu.org/pub/gnu/
PHP源代码目录下README.SELF-CONTAINED-EXTENSIONS文件如是说。
马上google了一下。
GNU autoconf
Autoconf是一个用于生成可以自动地配置软件源代码包以适应多种Unix类系统的 shell脚本的工具。由Autoconf生成的配置脚本在运行的时候与Autoconf是无关的，就是说配置脚本的用户并不需要拥有Autoconf。 
由Autoconf生成的配置脚本在运行的时候不需要用户的手工干预；通常它们甚至不需要通过给出参数以确定系统的类型。相反，它们对软件包可能需要的各种特征进行独立的测试。（在每个测试之前，它们打印一个单行的消息以说明它们正在进行的检测，以使得用户不会因为等待脚本执行完毕而焦躁。）因此，它们在混合系统或者从各种常见Unix变种定制而成的系统中工作的很好。没有必要维护文件以储存由各个Unix变种、各个发行版本所支持的特征的列表。 
对于每个使用了Autoconf的软件包，Autoconf从一个列举了该软件包需要的，或者可以使用的系统特征的列表的模板文件中生成配置脚本。在shell代码识别并响应了一个被列出的系统特征之后，Autoconf允许多个可能使用（或者需要）该特征的软件包共享该特征。如果后来因为某些原因需要调整shell代码，就只要在一个地方进行修改；所有的配置脚本都将被自动地重新生成以使用更新了的代码。 [...]]]></description>
			<content:encoded><![CDATA[<p>PREPARING YOUR SYSTEM</p>
<p>  While the result will run on any system, a developer&#8217;s setup needs these<br />
  tools:</p>
<p>    GNU autoconf<br />
    GNU automake<br />
    GNU libtool<br />
    GNU m4</p>
<p>  All of these are available from </p>
<p>    ftp://ftp.gnu.org/pub/gnu/</p>
<p>PHP源代码目录下README.SELF-CONTAINED-EXTENSIONS文件如是说。<br />
马上google了一下。</p>
<p><strong>GNU autoconf</strong></p>
<p>Autoconf是一个用于生成可以自动地配置软件源代码包以适应多种Unix类系统的 shell脚本的工具。由Autoconf生成的配置脚本在运行的时候与Autoconf是无关的，就是说配置脚本的用户并不需要拥有Autoconf。 </p>
<p>由Autoconf生成的配置脚本在运行的时候不需要用户的手工干预；通常它们甚至不需要通过给出参数以确定系统的类型。相反，它们对软件包可能需要的各种特征进行独立的测试。（在每个测试之前，它们打印一个单行的消息以说明它们正在进行的检测，以使得用户不会因为等待脚本执行完毕而焦躁。）因此，它们在混合系统或者从各种常见Unix变种定制而成的系统中工作的很好。没有必要维护文件以储存由各个Unix变种、各个发行版本所支持的特征的列表。 </p>
<p>对于每个使用了Autoconf的软件包，Autoconf从一个列举了该软件包需要的，或者可以使用的系统特征的列表的模板文件中生成配置脚本。在shell代码识别并响应了一个被列出的系统特征之后，Autoconf允许多个可能使用（或者需要）该特征的软件包共享该特征。如果后来因为某些原因需要调整shell代码，就只要在一个地方进行修改；所有的配置脚本都将被自动地重新生成以使用更新了的代码。 </p>
<p>Metaconfig包在目的上与Autoconf很相似，但它生成的脚本需要用户的手工干预，在配置一个大的源代码树的时候这是十分不方便的。不象Metaconfig脚本，如果在编写脚本时小心谨慎， Autoconf可以支持交叉编译（cross-compiling）。 </p>
<p>Autoconf目前还不能完成几项使软件包可移植的工作。其中包括为所有标准的目标自动创建`Makefile&#8217;文件，包括在缺少标准库函数和头文件的系统上提供替代品。目前正在为在将来添加这些特征而工作。<br />
<a href="http://www.linuxforum.net/books/autoconf.html">详细请看</a></p>
<p><strong>GNU automake</strong><br />
Automake是一个从文件`Makefile.am&#8217;自动生成`Makefile.in&#8217; 的工具。每个`Makefile.am&#8217;基本上是一系列make的宏定义（make规则也会偶尔出现）。生成的`Makefile.in&#8217;s服从GNU Makefile标准。 </p>
<p>GNU Makefile标准文档（参见GNU编码标准中的‘Makefile惯例’节）长、复杂，而且会发生改变。Automake的目的就是解除个人GNU维护者维护Makefile的负担（并且让Automake的维护者来承担这个负担）。 </p>
<p>典型的Automake输入文件是一系列简单的宏定义。处理所有这样的文件以创建 `Makefile.in&#8217;。在一个项目（project）的每个目录中通常包含一个 `Makefile.am&#8217;。 </p>
<p>Automake在几个方面对一个项目做了限制；例如它假定项目使用Autoconf （参见Autoconf手册），并且对`configure.in&#8217;的内容施加了某些限制。 </p>
<p>为生成`Makefile.in&#8217;，Automake需要perl。但是由Automake创建的发布完全服从GNU标准，并且在创建中不需要perl。 </p>
<p><a href="http://www.linuxforum.net/books/automake.html">详细请看</a></p>
<p><strong>GNU Libtool</strong><br />
GNU Libtool是一种属于GNU建构系统的GNU程序设计工具，用来产生可携式的库。这里引用libtool手册的说明：</p>
<p>在过去，如果源码包的开发人员要充分利用共享库的能力，就要为软件运行的每个平台写客制化的支持码，也要设计一个配置界面，使程序包安装程序可以选择以什么样的库建构。</p>
<p>GNU libtool藉著将平台特定的相依性，和用户界面，都封装在一个脚本中，来简化开发人员的工作。GNU libtool的目的是使每一个主机类型的完整功能都可以通过一个泛用接口来产生，又可以免去一堆讨厌的错误消息。</p>
<p>GNU libtool的接口目标是一致的。开发人员在建立源码包建构共享库时，应该不用去读低级的文件，他们只需要运行软件包的配置脚本（或同性质的文件），而让libtool去照顾细节。</p>
<p>通常libtool是与GNU建构系统中的autoconf和automake这两个工具一起使用。</p>
<p><a href="http://zh.wikipedia.org/zh-cn/Libtool">详细请看</a></p>
<p><strong>GNU m4</strong><br />
GNU m4为m4宏前处理器的GNU版本。其目的是为了避免传统m4前处理器中的多种限制，诸如对行长度的最大值限制，宏大小的最大值限制，宏数量的限制等。拿掉这些霸道的限制是GNU计划的既定目标之一。</p>
<p>GNU Autoconf包使GNU m4的功能得以广为使用。</p>
<p>GNU m4目前是由Eric Blake来维护</p>
<p><a href="http://zh.wikipedia.org/wiki/GNU_m4">详细请看</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/12/27/bianxiephpkuozhanzhihuanjingzhunbeignuautoconfautomakelibtoolm4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>/etc/fstab 文件详解</title>
		<link>http://blog.thinklet.net/franky/2009/10/20/etcfstabwenjianxiangjie/</link>
		<comments>http://blog.thinklet.net/franky/2009/10/20/etcfstabwenjianxiangjie/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 02:46:43 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[etc fstab]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=151</guid>
		<description><![CDATA[工作中用到的哦，做个记录！
       有很多人经常修改/etc/fstab文件，但是其中却有很多人对这个文件所表达的意义不太清楚，因为只要按照一定的模式，就可以轻而易举地添加一行挂载信息，而不需要完全理解其中的原理。下面就让我们来看看到底还有多少是我们不了解的。
   /etc/fstab是用来存放文件系统的静态信息的文件。位于/etc/目录下，可以用命令less /etc/fstab 来查看，如果要修改的话，则用命令 vi /etc/fstab 来修改。
       当系统启动的时候，系统会自动地从这个文件读取信息，并且会自动将此文件中指定的文件系统挂载到指定的目录。下面我来介绍如何在此文件下填写信息。
   在这个文件下，我们要关注的是它的六个域，分别为：、、 、、、。下面将详细介绍这六个域的详细意义。
      1、。这里用来指定你要挂载的文件系统的设备名称或块信息，也可以是远程的文件系统。做过嵌入式linux开发的朋友都可能知道 mount 192.168.1.56:/home/nfs /mnt/nfs/ -o nolock (可以是其他IP)命令所代表的意义。它的任务是把IP为192.168.1.56的远程主机上的/home/nfs/目录挂载到本机的/mnt/nfs /目录之下。如果要把它写进/etc/fstab文件中，file system这部分应填写为：/192.168.1.56:/home/nfs/。
   如果想把本机上的某个设备（device）挂载上来，写法如：/dev/sda1、/dev/hda2或/dev/cdrom，其中，/dev/sda1 表示第一个串口硬盘的第一个分区，也可以是第一个SCSI硬盘的第一个分区，/dev/hda1表示第一个IDE硬盘的第一个分区，/dev/cdrom 表示光驱。
   此外，还可以label(卷标)或UUID（Universally Unique Identifier全局唯一标识符）来表示。用label表示之前，先要e2label创建卷标，如：e2label /dir_1 /dir_2，其意思是说用/dir_2来表示/dir_1的名称。然后，再在/etc/fstab下按如下形式添加：LABEL=/dir_2 /dir_2  [...]]]></description>
			<content:encoded><![CDATA[<p>工作中用到的哦，做个记录！</p>
<p>       有很多人经常修改/etc/fstab文件，但是其中却有很多人对这个文件所表达的意义不太清楚，因为只要按照一定的模式，就可以轻而易举地添加一行挂载信息，而不需要完全理解其中的原理。下面就让我们来看看到底还有多少是我们不了解的。</p>
<p>   /etc/fstab是用来存放文件系统的静态信息的文件。位于/etc/目录下，可以用命令less /etc/fstab 来查看，如果要修改的话，则用命令 vi /etc/fstab 来修改。</p>
<p>       当系统启动的时候，系统会自动地从这个文件读取信息，并且会自动将此文件中指定的文件系统挂载到指定的目录。下面我来介绍如何在此文件下填写信息。</p>
<p>   在这个文件下，我们要关注的是它的六个域，分别为：、、 、、、。下面将详细介绍这六个域的详细意义。</p>
<p>      1、。这里用来指定你要挂载的文件系统的设备名称或块信息，也可以是远程的文件系统。做过嵌入式linux开发的朋友都可能知道 mount 192.168.1.56:/home/nfs /mnt/nfs/ -o nolock (可以是其他IP)命令所代表的意义。它的任务是把IP为192.168.1.56的远程主机上的/home/nfs/目录挂载到本机的/mnt/nfs /目录之下。如果要把它写进/etc/fstab文件中，file system这部分应填写为：/192.168.1.56:/home/nfs/。</p>
<p>   如果想把本机上的某个设备（device）挂载上来，写法如：/dev/sda1、/dev/hda2或/dev/cdrom，其中，/dev/sda1 表示第一个串口硬盘的第一个分区，也可以是第一个SCSI硬盘的第一个分区，/dev/hda1表示第一个IDE硬盘的第一个分区，/dev/cdrom 表示光驱。</p>
<p>   此外，还可以label(卷标)或UUID（Universally Unique Identifier全局唯一标识符）来表示。用label表示之前，先要e2label创建卷标，如：e2label /dir_1 /dir_2，其意思是说用/dir_2来表示/dir_1的名称。然后，再在/etc/fstab下按如下形式添加：LABEL=/dir_2 /dir_2      。重启后，系统就会将/dir_1挂载到/dir_2目录上。对于UUID，可以用vol_id -u /dev/sdax来获取。比如我想挂载第一块硬盘的第十一个分区，先用命令vol_id -u /dev/sda11 来取得UUID，比如是：5dc08a62-3472-471b-9ef5-0a91e5e2c126，然后在这个域上填写： UUID=5dc08a62-3472-471b-9ef5-0a91e5e2c126，即可表示/dev/sda11。Red Hat linux 一般会使用label，而Ubuntu linux 一般会用UUID。</p>
<p>   2、。挂载点，也就是自己找一个或创建一个dir（目录），然后把文件系统挂到这个目录上，然后就可以从这个目录中访问要挂载文件系统。对于swap分区，这个域应该填写：none，表示没有挂载点。</p>
<p>       3、。这里用来指定文件系统的类型。下面的文件系统都是目前Linux所能支持的：adfs、befs、cifs、ext3、 ext2、ext、iso9660、kafs、minix、msdos、vfat、umsdos、proc、reiserfs、swap、 squashfs、nfs、hpfs、ncpfs、ntfs、affs、ufs。</p>
<p>   4、。这里用来填写设置选项，各个选项用逗号隔开。由于选项非常多，而这里篇幅有限，所以不再作详细介绍，如需了解，请用命令 man mount 来查看。但在这里有个非常重要的关键字需要了解一下：defaults，它代表包含了选项rw,suid,dev,exec,auto,nouser和 async。</p>
<p>   5、。此处为1的话，表示要将整个里的内容备份；为0的话，表示不备份。现在很少用到dump这个工具，在这里一般选0。</p>
<p>   6、。这里用来指定如何使用fsck来检查硬盘。如果这里填0，则不检查；挂载点为 / 的（即根分区），必须在这里填写1，其他的都不能填写1。如果有分区填写大于1的话，则在检查完根分区后，接着按填写的数字从小到大依次检查下去。同数字的同时检查。比如第一和第二个分区填写2，第三和第四个分区填写3，则系统在检查完根分区后，接着同时检查第一和第二个分区，然后再同时检查第三和第四个分区。<br />
（作者：陈景忠，来源：http://hi.baidu.com/jingzhongchen/blog/item/8e6f552dcead7ce98b139952.html）</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/10/20/etcfstabwenjianxiangjie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux操作系统运行模式（runlevel）简述</title>
		<link>http://blog.thinklet.net/franky/2009/10/03/linuxcaozuoxitongyunxingmoshirunleveljianshu/</link>
		<comments>http://blog.thinklet.net/franky/2009/10/03/linuxcaozuoxitongyunxingmoshirunleveljianshu/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 14:04:25 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=149</guid>
		<description><![CDATA[Linux 操作系统自从开始启动至启动完毕需要经历几个不同的阶段，这几个阶段就叫做Runlevel，同样，当Linux操作系统关闭时也要经历另外几个不同的 Runlevel，下面我们就准备详细介绍一下Runlevel，并向您展示一些小技巧来让您的Linux系统避免不必要的重启动。
　　Runlevel可以认为是系统状态，形象一点，您可以认为 Runlevel有点象微软的windows操作系统中的Normal，safemode，和Command prompt only。进入每个Runlevel都需要启动或关闭相应的一系列服务(services)，这些服务(services)以初始化脚本的方式放置于目录 /etc/rc.d/rc?.d/或者/etc/rc?.d下面(?代表Runlevel的对应序号)。
　　在大多数的Linux发行版本中，通常有8个Runlevel
　　Runlevel System State
　　0 Halt the system
　　1 Single user mode
　　2 Basic multi user mode
　　3 Multi user mode
　　5 Multi user mode with GUI
　　6 Reboot the system
　　S, s Single user mode
　　多数的桌面的Linux系统缺省的Runlevel是5，用户登陆时是图形界面，而多数的服务器版本的Linux系统缺省的Runlevel是3，用户登陆时是字符界面，Runlevel 1和2除了调试之外很少使用，Runlevel s和S并不是直接给用户使用，而是用来为Single user mode作准备。
　　Linux的运行模式比起windows的启动模式的优势在于：你可以在系统空闲时使用.init工具切换你现在使用的Runlevel，另外，当你关闭或者启动 Linux系统时你已经不知不觉中切换你的Runlevel，系统关机进程需要调用Runlevel(0或6)来关闭所有正在运行中的进程。
　　显示当前运行模式
　　刚入门时，你或许对先前和目前正在使用中的运行模式很好奇，Runlevel命令可以用来显示这些信息：
　　$ /sbin/Runlevel
　　3 5
　　Runlevel命令的输出结果表明最初的运行模式是3，而现在的运行模式是5。
　　切换运行模式
　　切换运行模式使用telinit命令(root用户)：
　　$ /sbin/telinit
　　通常，切换运行模式的目的是重启某些应用进程，比如 XFree86，将运行模式从5切换到3将终止XFree86以及与之相关的所有进程，然后再把运行模式切换到5，XFree86就可以很干净的启动。在做这些工作之前，请确保所有在XFree86下的工作都已经保存，用root用户：
　　$ /sbin/telinit 3
　　$ /sbin/telinit 5
　　在键入命令之后，你的屏幕可能会显示一些服务启动或者停止的信息。
　　在运行模式中加入启动服务
要在某个运行模式中加入一个启动服务，首先要新建该服务启动脚本，然后把它放置于/etc/rc.d/init.d或者/etc/init.d/(根据你的 Linux版本有所不同)，要将该启动脚本与运行模式关联起来，你需要这个运行模式的目录下建立一个与/etc/rc.d/init.d/下启动脚本的 symbolic link，文件名的前缀通常为SXX，XX为数字，这个数字是用来控制该运行模式下服务的启动顺序。脚本的执行顺序是按照数字大小升序执行，就是数字越小越先执行，下面就是一个在运行模式中加入启动服务具体的例子：
　　$ cp myservice /etc/rc.d/init.d/
　　$ ln -s [...]]]></description>
			<content:encoded><![CDATA[<p>Linux 操作系统自从开始启动至启动完毕需要经历几个不同的阶段，这几个阶段就叫做Runlevel，同样，当Linux操作系统关闭时也要经历另外几个不同的 Runlevel，下面我们就准备详细介绍一下Runlevel，并向您展示一些小技巧来让您的Linux系统避免不必要的重启动。</p>
<p>　　Runlevel可以认为是系统状态，形象一点，您可以认为 Runlevel有点象微软的windows操作系统中的Normal，safemode，和Command prompt only。进入每个Runlevel都需要启动或关闭相应的一系列服务(services)，这些服务(services)以初始化脚本的方式放置于目录 /etc/rc.d/rc?.d/或者/etc/rc?.d下面(?代表Runlevel的对应序号)。</p>
<p>　　在大多数的Linux发行版本中，通常有8个Runlevel</p>
<p>　　Runlevel System State</p>
<p>　　0 Halt the system</p>
<p>　　1 Single user mode</p>
<p>　　2 Basic multi user mode</p>
<p>　　3 Multi user mode</p>
<p>　　5 Multi user mode with GUI</p>
<p>　　6 Reboot the system</p>
<p>　　S, s Single user mode</p>
<p>　　多数的桌面的Linux系统缺省的Runlevel是5，用户登陆时是图形界面，而多数的服务器版本的Linux系统缺省的Runlevel是3，用户登陆时是字符界面，Runlevel 1和2除了调试之外很少使用，Runlevel s和S并不是直接给用户使用，而是用来为Single user mode作准备。</p>
<p>　　Linux的运行模式比起windows的启动模式的优势在于：你可以在系统空闲时使用.init工具切换你现在使用的Runlevel，另外，当你关闭或者启动 Linux系统时你已经不知不觉中切换你的Runlevel，系统关机进程需要调用Runlevel(0或6)来关闭所有正在运行中的进程。</p>
<p>　　显示当前运行模式</p>
<p>　　刚入门时，你或许对先前和目前正在使用中的运行模式很好奇，Runlevel命令可以用来显示这些信息：</p>
<p>　　$ /sbin/Runlevel</p>
<p>　　3 5</p>
<p>　　Runlevel命令的输出结果表明最初的运行模式是3，而现在的运行模式是5。</p>
<p>　　切换运行模式</p>
<p>　　切换运行模式使用telinit命令(root用户)：</p>
<p>　　$ /sbin/telinit</p>
<p>　　通常，切换运行模式的目的是重启某些应用进程，比如 XFree86，将运行模式从5切换到3将终止XFree86以及与之相关的所有进程，然后再把运行模式切换到5，XFree86就可以很干净的启动。在做这些工作之前，请确保所有在XFree86下的工作都已经保存，用root用户：</p>
<p>　　$ /sbin/telinit 3</p>
<p>　　$ /sbin/telinit 5</p>
<p>　　在键入命令之后，你的屏幕可能会显示一些服务启动或者停止的信息。</p>
<p>　　在运行模式中加入启动服务</p>
<p>要在某个运行模式中加入一个启动服务，首先要新建该服务启动脚本，然后把它放置于/etc/rc.d/init.d或者/etc/init.d/(根据你的 Linux版本有所不同)，要将该启动脚本与运行模式关联起来，你需要这个运行模式的目录下建立一个与/etc/rc.d/init.d/下启动脚本的 symbolic link，文件名的前缀通常为SXX，XX为数字，这个数字是用来控制该运行模式下服务的启动顺序。脚本的执行顺序是按照数字大小升序执行，就是数字越小越先执行，下面就是一个在运行模式中加入启动服务具体的例子：</p>
<p>　　$ cp myservice /etc/rc.d/init.d/</p>
<p>　　$ ln -s /etc/rc.d/init.d/myservice /etc/rc3.d/S99myservice</p>
<p>　　这样，下次以Runlevel 3启动时，myservice就会自动启动。</p>
<p>　　以某个Runlevel启动</p>
<p>　　你可以自己制定启动时所进入的Runlevel，如果你的系统使用的是lilo，在启动命令中将相应的部分为：</p>
<p>　　LILO: Linux 5</p>
<p>　　如果你使用的是GRUB，在启动时你可以按住e键进入设置模式，相应的位置显示为：</p>
<p>　　kernel /vmlinuz ro root=/dev/hda1 5</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/10/03/linuxcaozuoxitongyunxingmoshirunleveljianshu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>linux的根目录下的tmpfs是啥？有啥用？</title>
		<link>http://blog.thinklet.net/franky/2009/10/01/linuxdegenmuluxiadetmpfsshishayoushayong/</link>
		<comments>http://blog.thinklet.net/franky/2009/10/01/linuxdegenmuluxiadetmpfsshishayoushayong/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 16:44:47 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=147</guid>
		<description><![CDATA[最近装了一个CenOS5.3，发现根目录下多了一个叫tmpfs的目录。
上网搜了一下相关资料，这里作一下记录：
介绍 tmpfs
如果必须一下子说清楚 tmpfs，那么 tmpfs 就象虚拟磁盘（ramdisk），但不一样。象虚拟磁盘一样，tmpfs 可以使用您的 RAM，但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备，并需要一个 mkfs 之类的命令才能真正地使用它，tmpfs 是一个文件系统，而不是块设备；您只是安装它，它就可以使用了。总而言之，这让 tmpfs 成为有机会遇到的最好的基于 RAM 的文件系统。
tmpfs 和 VM
让我们来看看 tmpfs 更有趣的一些特性吧。正如前面提到的一样，tmpfs 既可以使用 RAM， 也可以使用交换分区。刚开始这看起来可能有点武断，但请记住 tmpfs 也是我们知道的“虚拟内存文件系统”。而且，您可能也知道，Linux 内核的虚拟内存资源同时来源于您的 RAM 和交换分区。内核中的 VM 子系统将这些资源分配到系统中的其它部分，并负责在后台管理这些资源，通常是透明地将 RAM 页移动到交换分区或从交换分区到 RAM 页。
tmpfs 文件系统需要 VM 子系统的页面来存储文件。tmpfs 自己并不知道这些页面是在交换分区还是在 RAM 中；做这种决定是 VM 子系统的工作。tmpfs 文件系统所知道的就是它正在使用某种形式的虚拟内存。
不是块设备
这里是 tmpfs 文件系统另一个有趣的特性。不同于大多数“标准的”文件系统，如 ext3、ext2、XFS、JFS、ReiserFS 和其它一些系统，tmpfs 并不是存在于一个底层块设备上面。因为 tmpfs 是直接建立在 VM 之上的，您用一个简单的 mount 命令就可以创建 tmpfs 文件系统了。
# mount [...]]]></description>
			<content:encoded><![CDATA[<p>最近装了一个CenOS5.3，发现根目录下多了一个叫tmpfs的目录。</p>
<p>上网搜了一下相关资料，这里作一下记录：</p>
<p>介绍 tmpfs<br />
如果必须一下子说清楚 tmpfs，那么 tmpfs 就象虚拟磁盘（ramdisk），但不一样。象虚拟磁盘一样，tmpfs 可以使用您的 RAM，但它也可以使用您的交换分区来存储。而且传统的虚拟磁盘是个块设备，并需要一个 mkfs 之类的命令才能真正地使用它，tmpfs 是一个文件系统，而不是块设备；您只是安装它，它就可以使用了。总而言之，这让 tmpfs 成为有机会遇到的最好的基于 RAM 的文件系统。</p>
<p>tmpfs 和 VM<br />
让我们来看看 tmpfs 更有趣的一些特性吧。正如前面提到的一样，tmpfs 既可以使用 RAM， 也可以使用交换分区。刚开始这看起来可能有点武断，但请记住 tmpfs 也是我们知道的“虚拟内存文件系统”。而且，您可能也知道，Linux 内核的虚拟内存资源同时来源于您的 RAM 和交换分区。内核中的 VM 子系统将这些资源分配到系统中的其它部分，并负责在后台管理这些资源，通常是透明地将 RAM 页移动到交换分区或从交换分区到 RAM 页。<br />
tmpfs 文件系统需要 VM 子系统的页面来存储文件。tmpfs 自己并不知道这些页面是在交换分区还是在 RAM 中；做这种决定是 VM 子系统的工作。tmpfs 文件系统所知道的就是它正在使用某种形式的虚拟内存。</p>
<p>不是块设备<br />
这里是 tmpfs 文件系统另一个有趣的特性。不同于大多数“标准的”文件系统，如 ext3、ext2、XFS、JFS、ReiserFS 和其它一些系统，tmpfs 并不是存在于一个底层块设备上面。因为 tmpfs 是直接建立在 VM 之上的，您用一个简单的 mount 命令就可以创建 tmpfs 文件系统了。<br />
# mount tmpfs /mnt/tmpfs -t tmpfs</p>
<p>执行这个命令之后，一个新的 tmpfs 文件系统就安装在 /mnt/tmpfs，随时可以使用。注意，不需运行 mkfs.tmpfs ；事实上，那是不可能的，因为没有这样的命令存在。在 mount 命令执行之后，文件系统立即就被安装并且可以使用了，类型是 tmpfs 。这和 Linux 虚拟磁盘如何使用大相径庭；标准的 Linux 虚拟磁盘是 块设备，所以在使用它们之前必须用您选择的文件系统将其格式化。相反，tmpfs 是一个文件系统。所以，您可以简单地安装它就可以使用了。</p>
<p>tmpfs有以下优势：<br />
1。动态文件系统的大小，<br />
2。tmpfs 的另一个主要的好处是它闪电般的速度。因为典型的 tmpfs 文件系统会完全驻留在 RAM 中，读写几乎可以是瞬间的。<br />
3。tmpfs 数据在重新启动之后不会保留，因为虚拟内存本质上就是易失的。所以有必要做一些脚本做诸如加载，绑定的操作。</p>
<p>一些应用例子：</p>
<p>1。squid的缓存目录设置</p>
<p>vi /etc/squid/squid.conf</p>
<p>修改成<br />
cache_dir ufs /tmp 256 16 256<br />
这里的第一个256表示使用256M内存，我觉得高性能LINUX双效防火墙HOWTO使用ramdisk的方法还不如直接使用tmpfs，至少每次启动不用mkfs，还可以动态改变大小。</p>
<p>然后重启一下服务，ok，现在所有的squid缓存文件都保存倒tmpfs文件系统里了，很快哦。</p>
<p>2。对php性能的优化</p>
<p>对于一个访问量大的以apache＋php的网站，可能tmp下的临时文件都会很多，比如seesion或者一些缓存文件，那么你可以把它保存到tmpfs文件。</p>
<p>保存seesion的方法很简单了只要修改php.ini就行了，由于我已经把/dev/stm/tmp与/tmp绑定，所以不改写也行，至于php程序产生的缓存文件那只能改自己的php程序了：）</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/10/01/linuxdegenmuluxiadetmpfsshishayoushayong/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mysql实用小技巧</title>
		<link>http://blog.thinklet.net/franky/2009/08/18/mysqlshiyongxiaojiqiao/</link>
		<comments>http://blog.thinklet.net/franky/2009/08/18/mysqlshiyongxiaojiqiao/#comments</comments>
		<pubDate>Tue, 18 Aug 2009 11:20:29 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=9</guid>
		<description><![CDATA[1. 控制台中运行sql,在最后加\G可以将但到的信息，分行展示.
例如：
mysql&#62; select id,name from workitems limit 2 \G;
*************************** 1. row ***************************
  id: 223255
name: 提供获取指定用户项目列表的API
*************************** 2. row ***************************
  id: 223256
name: 提供获取指定用户项目列表的API
2 rows in set (0.00 sec)
2. 在where子句在锁嵌套count()
错误做法：select * from user_num where count(user)&#62;＝2 group by user;
正确做法：select * from user_num group by user HAVING count(user)&#62;＝2 ;
3. 如何解决mysqlbinlog: unknown variable &#8216;default-character-set=utf8&#8242;的错误。
加入 &#8211;no_defaults 参数
如: /usr/bin/mysqlbinlog &#8211;no-defaults ./log.000043 [...]]]></description>
			<content:encoded><![CDATA[<p>1. 控制台中运行sql,在最后加\G可以将但到的信息，分行展示.<br />
例如：<br />
mysql&gt; select id,name from workitems limit 2 \G;<br />
*************************** 1. row ***************************<br />
  id: 223255<br />
name: 提供获取指定用户项目列表的API<br />
*************************** 2. row ***************************<br />
  id: 223256<br />
name: 提供获取指定用户项目列表的API<br />
2 rows in set (0.00 sec)</p>
<p>2. 在where子句在锁嵌套count()<br />
错误做法：select * from user_num where count(user)&gt;＝2 group by user;<br />
正确做法：select * from user_num group by user HAVING count(user)&gt;＝2 ;</p>
<p>3. 如何解决mysqlbinlog: unknown variable &#8216;default-character-set=utf8&#8242;的错误。<br />
加入 &#8211;no_defaults 参数<br />
如: /usr/bin/mysqlbinlog &#8211;no-defaults ./log.000043 </p>
<p>4. 跨表插入数据。<br />
INSERT INTO table1<br />
(`field1`,`field2 )<br />
SELECT  `field1`,`field2<br />
FROM table1 WHERE &#8230;..</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/08/18/mysqlshiyongxiaojiqiao/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何在CAKEPHP应用中嵌套另一个CAKEPHP应用 &#8211; TAPD3新版本的部署方案</title>
		<link>http://blog.thinklet.net/franky/2009/04/02/%e5%a6%82%e4%bd%95%e5%9c%a8cakephp%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%a5%97%e5%8f%a6%e4%b8%80%e4%b8%aacakephp%e5%ba%94%e7%94%a8-tapd32%e7%9a%84%e9%83%a8%e7%bd%b2%e6%96%b9%e6%a1%88/</link>
		<comments>http://blog.thinklet.net/franky/2009/04/02/%e5%a6%82%e4%bd%95%e5%9c%a8cakephp%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%a5%97%e5%8f%a6%e4%b8%80%e4%b8%aacakephp%e5%ba%94%e7%94%a8-tapd32%e7%9a%84%e9%83%a8%e7%bd%b2%e6%96%b9%e6%a1%88/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 16:17:48 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[技术运营]]></category>
		<category><![CDATA[cakephp;php;lamp]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=92</guid>
		<description><![CDATA[我们的tapd3新版本(一个CAKEPHP应用)要发布了，但是由于某原因不能代替现有的老版本(另一个CAKEPHP应用)。两个版本必须并存。但域名只有一个（tapd3.oa.com），并且已经被老版本占用着。
那么我们的tapd3新版本只能挂tapd3.oa.com的一个目录下了，目录就暂定为tapd3.oa.com/beta/吧。这样，访问http://tapd3.oa.com/beta时就是访问新版本，访问http://tapd.oa.com的话还是以前的老版本。
 
方案定下来了，动手进行配置。
注：下文出现的TAPD3_ROOT表示tapd3老版本（一个CAKEPHP应用）的根目录。
1.了解现有的设置：
    服务器: apache
    配置有虚拟主机：tapd3.oa.com；其DocumentRoot为TAPD3_ROOT/app/webroot；此目录已经打开AllowOverRide
2.设置虚拟主机的DocumentRoot.
把虚拟主机：tapd3.oa.com的DocumentRoot设为TAPD3_ROOT，这个并没有任何影响，效果跟值为TAPD3_ROOT/app/webroot时一样的。因为默认下CAKEPHP的根目录有这样的一个.htaccess文件。

RewriteEngine on
RewriteRule    ^$ app/webroot/    [L]
RewriteRule    (.*) app/webroot/$1 [L]

这个文件的作用是把当前目录下的所有请求重定向到app/webroot/下面。
3.放入代码。
先把tapd3新版本的代码checkout一份到TAPD3_ROOT目录下（跟config/ controller/ model/ view/ 目录同一级），并以bata命名。
4.修改TAPD3_ROOT目录下的.htaccess文件。
如果Apache没有作其它配置的话，访问http://tapd3.oa.com/beta/时，请求数据应该就会到beta这个目录下面去找。但是CAKEPHP根目录，也就是我们的TAPD3_ROOT目录下面存在着第2步所说的这个.htaccess文件。把http://tapd3.oa.com/beta/这个请求的服务器数据路径被重定向到app/webroot下面去了，以致不能达到我们想要的效果。
这里要改动一下这个.htaccess文件，使访问http://tapd3.oa.com/beta/时，服务器还是去beta目录去查找数据。改变后的.htaccess文件如下：

RewriteEngine on
RewriteRule    ^$ app/webroot/    [L]
RewriteCond    ${REQUEST_URI} !beta    //这句表示请求uri不等于beta时，下面的重写命令才生效。
RewriteRule    (.*) app/webroot/$1 [L]

大功做成！
访问http://tapd3.oa.com还是原来的CAKEPHP应用；
访问http://tapd3.oa.com/bata/就是新的CAKEPHP应用啦。
]]></description>
			<content:encoded><![CDATA[<p>我们的tapd3新版本(一个CAKEPHP应用)要发布了，但是由于某原因不能代替现有的老版本(另一个CAKEPHP应用)。两个版本必须并存。但域名只有一个（tapd3.oa.com），并且已经被老版本占用着。</p>
<p>那么我们的tapd3新版本只能挂tapd3.oa.com的一个目录下了，目录就暂定为tapd3.oa.com/beta/吧。这样，访问http://tapd3.oa.com/beta时就是访问新版本，访问http://tapd.oa.com的话还是以前的老版本。</p>
<p> </p>
<p>方案定下来了，动手进行配置。<br />
注：下文出现的TAPD3_ROOT表示tapd3老版本（一个CAKEPHP应用）的根目录。</p>
<h4>1.了解现有的设置：</h4>
<p>    服务器: apache<br />
    配置有虚拟主机：tapd3.oa.com；其DocumentRoot为TAPD3_ROOT/app/webroot；此目录已经打开AllowOverRide</p>
<h4>2.设置虚拟主机的DocumentRoot.</h4>
<p>把虚拟主机：tapd3.oa.com的DocumentRoot设为TAPD3_ROOT，这个并没有任何影响，效果跟值为TAPD3_ROOT/app/webroot时一样的。因为默认下CAKEPHP的根目录有这样的一个.htaccess文件。<br />
<code><br />
RewriteEngine on<br />
RewriteRule    ^$ app/webroot/    [L]<br />
RewriteRule    (.*) app/webroot/$1 [L]<br />
</code><br />
这个文件的作用是把当前目录下的所有请求重定向到app/webroot/下面。</p>
<h4>3.放入代码。</h4>
<p>先把tapd3新版本的代码checkout一份到TAPD3_ROOT目录下（跟config/ controller/ model/ view/ 目录同一级），并以bata命名。</p>
<h4>4.修改TAPD3_ROOT目录下的.htaccess文件。</h4>
<p>如果Apache没有作其它配置的话，访问http://tapd3.oa.com/beta/时，请求数据应该就会到beta这个目录下面去找。但是CAKEPHP根目录，也就是我们的TAPD3_ROOT目录下面存在着第2步所说的这个.htaccess文件。把http://tapd3.oa.com/beta/这个请求的服务器数据路径被重定向到app/webroot下面去了，以致不能达到我们想要的效果。<br />
这里要改动一下这个.htaccess文件，使访问http://tapd3.oa.com/beta/时，服务器还是去beta目录去查找数据。改变后的.htaccess文件如下：<br />
<code><br />
RewriteEngine on<br />
RewriteRule    ^$ app/webroot/    [L]<br />
RewriteCond    ${REQUEST_URI} !beta    //这句表示请求uri不等于beta时，下面的重写命令才生效。<br />
RewriteRule    (.*) app/webroot/$1 [L]<br />
</code></p>
<p>大功做成！<br />
访问http://tapd3.oa.com还是原来的CAKEPHP应用；<br />
访问http://tapd3.oa.com/bata/就是新的CAKEPHP应用啦。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/04/02/%e5%a6%82%e4%bd%95%e5%9c%a8cakephp%e5%ba%94%e7%94%a8%e4%b8%ad%e5%b5%8c%e5%a5%97%e5%8f%a6%e4%b8%80%e4%b8%aacakephp%e5%ba%94%e7%94%a8-tapd32%e7%9a%84%e9%83%a8%e7%bd%b2%e6%96%b9%e6%a1%88/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>如何利用Ruby来解析XML</title>
		<link>http://blog.thinklet.net/franky/2009/03/12/%e5%a6%82%e4%bd%95%e5%88%a9%e7%94%a8ruby%e6%9d%a5%e8%a7%a3%e6%9e%90xml/</link>
		<comments>http://blog.thinklet.net/franky/2009/03/12/%e5%a6%82%e4%bd%95%e5%88%a9%e7%94%a8ruby%e6%9d%a5%e8%a7%a3%e6%9e%90xml/#comments</comments>
		<pubDate>Wed, 11 Mar 2009 16:25:55 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[技术运营]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=80</guid>
		<description><![CDATA[前段时候做个小工具，把每天的svn日志抽出来取，再把必要的信息通过邮件方式知会大家。
最后采用的技术是ruby on rails 的rake。实现过程中必须要用ruby解析xml文件。上网查了一些相关的资料，方法有很多，在这里做一个汇总：
1. 使用REXML
doc = REXML::Document.new(File.open(file_path))
doc.elements.each(&#8217;log/logentry&#8217;) do &#124;ele&#124;
author_ele = ele.get_elements(&#8217;author&#8217;)
msg_ele = ele.get_elements(&#8217;msg&#8217;)
end
2. 使用XmlSimple
xml_file = File.open(file_path)
data = XmlSimple.xml_in(xml_file)
data['logentry'].each do &#124;item&#124;
item['msg']
item['author']
end
3. 使用Hpricot
Hpricot是一个HTML解释的库，支持XML。Hpricot允许开发者通过CSS-selectors和X-Path访问html元素，因此你很轻松就可以明确目标标记，还有它是用C语言写的，因此相当快。
安装方法：gem install hpricot
# load the RedHanded home page
doc = Hpricot(open(&#8221;http://redhanded.hobix.com/index.html&#8221;))
# change the CSS class on links
(doc/&#8221;span.entryPermalink&#8221;).set(&#8221;class&#8221;, &#8220;newLinks&#8221;)
# remove the sidebar  (doc/&#8221;#sidebar&#8221;).remove
# print the altered HTML
puts doc
]]></description>
			<content:encoded><![CDATA[<p>前段时候做个小工具，把每天的svn日志抽出来取，再把必要的信息通过邮件方式知会大家。</p>
<p>最后采用的技术是ruby on rails 的rake。实现过程中必须要用ruby解析xml文件。上网查了一些相关的资料，方法有很多，在这里做一个汇总：</p>
<p>1. 使用REXML<br />
doc = REXML::Document.new(File.open(file_path))<br />
doc.elements.each(&#8217;log/logentry&#8217;) do |ele|<br />
author_ele = ele.get_elements(&#8217;author&#8217;)<br />
msg_ele = ele.get_elements(&#8217;msg&#8217;)<br />
end</p>
<p>2. 使用XmlSimple</p>
<p>xml_file = File.open(file_path)<br />
data = XmlSimple.xml_in(xml_file)<br />
data['logentry'].each do |item|<br />
item['msg']<br />
item['author']</p>
<p>end</p>
<p>3. 使用Hpricot</p>
<p>Hpricot是一个HTML解释的库，支持XML。Hpricot允许开发者通过CSS-selectors和X-Path访问html元素，因此你很轻松就可以明确目标标记，还有它是用C语言写的，因此相当快。</p>
<p>安装方法：gem install hpricot</p>
<p># load the RedHanded home page</p>
<p>doc = Hpricot(open(&#8221;http://redhanded.hobix.com/index.html&#8221;))</p>
<p># change the CSS class on links</p>
<p>(doc/&#8221;span.entryPermalink&#8221;).set(&#8221;class&#8221;, &#8220;newLinks&#8221;)</p>
<p># remove the sidebar  (doc/&#8221;#sidebar&#8221;).remove</p>
<p># print the altered HTML</p>
<p>puts doc</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/03/12/%e5%a6%82%e4%bd%95%e5%88%a9%e7%94%a8ruby%e6%9d%a5%e8%a7%a3%e6%9e%90xml/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>实战！利用APC来缓存和优化 PHP 的中间代码</title>
		<link>http://blog.thinklet.net/franky/2009/02/19/%e5%ae%9e%e6%88%98%ef%bc%81%e5%88%a9%e7%94%a8apc%e6%9d%a5%e7%bc%93%e5%ad%98%e5%92%8c%e4%bc%98%e5%8c%96-php-%e7%9a%84%e4%b8%ad%e9%97%b4%e4%bb%a3%e7%a0%81/</link>
		<comments>http://blog.thinklet.net/franky/2009/02/19/%e5%ae%9e%e6%88%98%ef%bc%81%e5%88%a9%e7%94%a8apc%e6%9d%a5%e7%bc%93%e5%ad%98%e5%92%8c%e4%bc%98%e5%8c%96-php-%e7%9a%84%e4%b8%ad%e9%97%b4%e4%bb%a3%e7%a0%81/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 16:25:47 +0000</pubDate>
		<dc:creator>frankychen</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[APC]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP优化]]></category>
		<category><![CDATA[PHP加速]]></category>

		<guid isPermaLink="false">http://blog.thinklet.net/franky/?p=53</guid>
		<description><![CDATA[Alternative PHP Cache（APC）是 PHP 的一个免费公开的优化代码缓存。它用来提供免费，公开并且强健的架构来缓存和优化 PHP 的中间代码。]]></description>
			<content:encoded><![CDATA[<p>Alternative PHP Cache（APC）是 PHP 的一个免费公开的优化代码缓存。它用来提供免费，公开并且强健的架构来缓存和优化 PHP 的中间代码。</p>
<p>部署APC很简单：<br />
1.  安装APC，PHP的一个扩展。<br />
2. 修改php.ini文件，加入extension = apc.so句 ，启用apc扩展（更多apc运行时配置可见<a href="http://cn.php.net/manual/en/apc.configuration.php">http://cn.php.net/manual/en/apc.configuration.php</a>）。<br />
3. 重启Apache，使php配置生效。</p>
<p>我做了一个测试，看看APC到底能给php应用带来多大的性能上的提高。</p>
<p>测试环境如下：<br />
APC ： Version  3.0.19<br />
PHP ：  Version  5.2.4-2ubuntu5.5<br />
APC Host ：   saturn（我的虚拟机，256M内存）<br />
Server Software ：  Apache/2.2.8 (Ubuntu) PHP/5.2.4-2ubuntu5.5 with Suhosin-Patch<br />
PHP 应用 ： CAKEPHP  1.2.1.8004<br />
性能测试工具 ：apache ab</p>
<p><strong>测试数据如下：<br />
</strong><br />
没启用APC的所得的数据<br />
Concurrency Level:      10<br />
Time taken for tests:   119.262053 seconds<br />
Complete requests:      500<br />
Failed requests:        47<br />
   (Connect: 0, Length: 47, Exceptions: 0)<br />
Write errors:           0<br />
Total transferred:      670445 bytes<br />
HTML transferred:       492945 bytes<br />
Requests per second:    4.19 [#/sec] (mean)<br />
Time per request:       2385.241 [ms] (mean)<br />
Time per request:       238.524 [ms] (mean, across all concurrent requests)<br />
Transfer rate:          5.48 [Kbytes/sec] received</p>
<p>启用APC的所得的数据<br />
Concurrency Level:      10<br />
Time taken for tests:   19.495444 seconds<br />
Complete requests:      500<br />
Failed requests:        55<br />
   (Connect: 0, Length: 55, Exceptions: 0)<br />
Write errors:           0<br />
Total transferred:      670435 bytes<br />
HTML transferred:       492935 bytes<br />
Requests per second:    25.65 [#/sec] (mean)<br />
Time per request:       389.909 [ms] (mean)<br />
Time per request:       38.991 [ms] (mean, across all concurrent requests)<br />
Transfer rate:          33.55 [Kbytes/sec] received</p>
<p> </p>
<p>测试数据可以看到，没启用APC时服务器每秒只可以处理4.19个请求，启用APC时服务器每秒处理请求数据增加至25.65个。性能提升接近600%。当然这个数据在不同的环境下会有出入，但是无论怎样，APC可以大幅度提高PHP的性能是肯定的。</p>
<p>PHP优化工具还有很多，如eAccelerator, Xcache等等。据网上资料显示eAccelerator性能要优于APC和Xcache。而我们的tapd平台服务器所用的PHP优化工具正是eAccelerator。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinklet.net/franky/2009/02/19/%e5%ae%9e%e6%88%98%ef%bc%81%e5%88%a9%e7%94%a8apc%e6%9d%a5%e7%bc%93%e5%ad%98%e5%92%8c%e4%bc%98%e5%8c%96-php-%e7%9a%84%e4%b8%ad%e9%97%b4%e4%bb%a3%e7%a0%81/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<a style="display: none;" href="http://mcinside.com/">MC Inside</a>