<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_小狼的世界</title><subtitle type="text">不积跬步，无以至千里、不积细流，无以成江海</subtitle><id>http://feed.cnblogs.com/blog/u/43046/rss</id><updated>2012-02-04T03:42:26Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/43046/rss"/><entry><id>http://www.cnblogs.com/cocowool/archive/2012/02/04/2337841.html</id><title type="text">PHP中的正则表达式及模式匹配</title><summary type="text">整理摘抄了手册中关于PHP模式修正符的内容，真切的体会到手册的好处</summary><published>2012-02-04T03:42:00Z</published><updated>2012-02-04T03:42:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2012/02/04/2337841.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2012/02/04/2337841.html"/><content type="html">&lt;!--?xml version="1.0" encoding="UTF-8" standalone="no"?--&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;PHP中对于正则处理文本提供了两种方式，一种是PCRE方式（PCRE库是一个实现了与perl 5在语法和语义上略有差异(详见下文)的正则表达式模式匹配功能的函数集. 当前的实现对应于perl 5.005.）；另一个是POSIX方式。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;PCRE函数库中的函数使用的模式语法非常类似perl. 表达式必须用分隔符闭合, 比如一个正斜杠(/). 分隔符可以使任意非字母数字, 除反斜杠(\)和空字节之外的非空白ascii字符. 如果分隔符 在表达式中使用, 需要使用反斜线进行转义. 自php 4.0.4开始, 可以使用perl样式的(), {}, []以及&amp;lt;&amp;gt;作为分隔符. 更详细的解释参见模式语法.&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;结束分隔符后面可以紧跟模式修饰符来影响匹配效果. 参见模式修饰符.&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong style="font-size: 18px; "&gt;PCRE的模式修正符&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;i (PCRE_CASELESS)&amp;nbsp;&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果设定此修正符，模式中的字符将同时匹配大小写字母。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;s（PCRE_DOTALL）&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果设定了此修正符，模式中的圆点元字符（.）匹配所有的字符，包括换行符。没有此设定的话，则不包括换行符。这和 Perl 的 /s 修正符是等效的。排除字符类例如 [^a] 总是匹配换行符的，无论是否设定了此修正符。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;m（PCRE_MULTILINE）&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;默认情况下，PCRE 将目标字符串作为单一的一&amp;#8220;行&amp;#8221;字符所组成的（甚至其中包含有换行符也是如此）。&amp;#8220;行起始&amp;#8221;元字符（^）仅仅匹配字符串的起始，&amp;#8220;行结束&amp;#8221;元字符（$）仅仅匹配字符串的结束，或者最后一个字符是换行符时其前面（除非设定了 D 修正符）。这和 Perl 是一样的。当设定了此修正符，&amp;#8220;行起始&amp;#8221;和&amp;#8220;行结束&amp;#8221;除了匹配整个字符串开头和结束外，还分别匹配其中的换行符的之后和之前。这和 Perl 的 /m 修正符是等效的。如果目标字符串中没有&amp;#8220;\n&amp;#8221;字符或者模式中没有 ^ 或 $，则设定此修正符没有任何效果。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;x (PCRE_EXTENDED)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果设置了这个修饰符, 模式中的没有经过转义的或不在字符类中的空白数据字符总会被忽略, 并且位于一个未转义的字符类外部的#字符和下一个换行符之间的字符也被忽略. 这个修饰符 等同于perl中的/x修饰符, 使被编译模式中可以包含注释. 注意: 这仅用于数据字符. 空白字符 还是不能在模式的特殊字符序列中出现, 比如序列(?(引入了一个条件子组(译注: 这种语法定义的 特殊字符序列中如果出现空白字符会导致编译错误. 比如( ?(就会导致错误.).&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;e (PREG_REPLACE_EVAL)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果这个修饰符设置了, preg_replace()在进行了对替换字符串的 后向引用替换之后, 将替换后的字符串作为php代码评估之行(eval函数方式), 并使用之行结果 作为实际参与替换的字符串. 单引号, 双引号, 反斜线(\)和NULL字符在 后向引用替换时会被用反斜线转义.&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;font  color="#ff2617"&gt;仅preg_replace()使用此修饰符, 其他PCRE函数忽略此修饰符.&lt;/font&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;A (PCRE_ANCHORED)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果设置了这个修饰符, 模式被强制为"锚定"模式, 也就是说约束匹配使其仅从 目标字符串的开始位置搜索. 这个效果同样可以使用适当的模式构造出来, 并且 这也是perl种实现这种模式的唯一途径.&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;D (PCRE_DOLLAR_ENDONLY)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果这个修饰符被设置, 模式中的元字符美元符号仅仅匹配目标字符串的末尾. 如果这个修饰符 没有设置, 当字符串以一个换行符结尾时, 美元符号还会匹配该换行符(但不会匹配之前的任何换行符). 如果设置了修饰符m, 这个修饰符被忽略. 在perl中没有与此修饰符等同的修饰符.&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;当一个模式需要多次使用的时候, 为了得到匹配速度的提升, 值得花费一些时间 对其进行一些额外的分析. 如果设置了这个修饰符, 这个额外的分析就会执行. 当前, 这种对一个模式的分析仅仅适用于非锚定模式的匹配(即没有单独的固定开始字符).&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;U (PCRE_UNGREEDY)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;这个修饰符逆转了量词的"贪婪"模式. 使量词默认为非贪婪的, 通过量词后紧跟? 的方式可以使其成为贪婪的. 这和perl是不兼容的. 它同样可以使用 模式内修饰符设置 (?U)进行设置, 或者在量词后以问号标记其非贪婪(比如.*?).&lt;font  color="#ff2617"&gt;在非贪婪模式, 通常不能匹配超过 pcre.backtrack_limit 的字符.&lt;/font&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;X (PCRE_EXTRA)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;这个修饰符打开了PCRE与perl不兼容的附件功能. 模式中的任意反斜线后就ingen一个 没有特殊含义的字符都会导致一个错误, 以此保留这些字符以保证向后兼容性. 默认 情况下, 在perl中, 反斜线紧跟一个没有特殊含义的字符被认为是该字符的原文. 当前没有其他特性由这个修饰符控制.&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;J (PCRE_INFO_JCHANGED)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;内部选项设置(?J)修改本地的PCRE_DUPNAMES选项. 允许子组重名. (译注:只能通过内部选项设置, 外部的/J设置会产生错误.)&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;u (PCRE8)&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;此修正符打开一个与perl不兼容的附加功能. 模式字符串被认为是utf-8的. 这个修饰符 从unix版php 4.1.0或更高, win32版php 4.2.3开始可用. php 4.3.5开始检查模式的utf-8合法性. This modifier turns on additional functionality of PCRE that is incompatible with Perl. Pattern strings are treated as UTF-8. This modifier is available from PHP 4.1.0 or greater on Unix and from PHP 4.2.3 on win32. UTF-8 validity of the pattern is checked since PHP 4.3.5.&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;参考资料：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、&lt;a href="http://topic.csdn.net/u/20091231/02/ae285993-01db-4551-bb56-eeca1a407724.html"&gt;preg_match_all截取body正则表达式&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、&lt;a href="http://blog.sina.com.cn/s/blog_5ac88b350100bz2h.html"&gt;PHP正则表达式匹配多行及模式匹配&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、&lt;a href="http://docs.php.net/manual/zh/reference.pcre.pattern.modifiers.php"&gt;PHP Manual PCRE模式&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2337841.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2012/02/04/2337841.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2012/01/17/2324950.html</id><title type="text">Mac下连接VPN的设置</title><summary type="text">很多IT公司都会给员工申请VPN，方便大家不在公司的时候访问公司的网络资源。同样是使用SecurID卡，之前的东家使用的PPTP的方式，当时买了Mac之后，很轻松的就能够配置VPN的连接。现在换了东家，他们使用的是Cisco IPSec的方式进行的VPN连接，配置的时候花了一点功夫，相信很多朋友都有配置VPN的问题，记下来供有需要朋友使用。VPN知识科普关于VPN，我之前的理解为就是通过一个加密可靠的信道访问一个对公网不可见的网络资源。看了下百度百科才了解VPN的隧道协议主要有三种：PPTP、L2TP和IPSec。其中PPTP和L2TP协议工作在OSI模型的二层，IPSec是第三层隧道协议，也</summary><published>2012-01-17T10:27:00Z</published><updated>2012-01-17T10:27:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2012/01/17/2324950.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2012/01/17/2324950.html"/><content type="html">&lt;!--?xml version="1.0" encoding="UTF-8" standalone="no"?--&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;很多IT公司都会给员工申请VPN，方便大家不在公司的时候访问公司的网络资源。同样是使用SecurID卡，之前的东家使用的PPTP的方式，当时买了Mac之后，很轻松的就能够配置VPN的连接。现在换了东家，他们使用的是Cisco IPSec的方式进行的VPN连接，配置的时候花了一点功夫，相信很多朋友都有配置VPN的问题，记下来供有需要朋友使用。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;VPN知识科普&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;关于VPN，我之前的理解为就是通过一个加密可靠的信道访问一个对公网不可见的网络资源。看了下百度百科才了解VPN的隧道协议主要有三种：PPTP、L2TP和IPSec。其中PPTP和L2TP协议工作在OSI模型的二层，IPSec是第三层隧道协议，也是最常用的协议。L2TP和IPSec配合使用是目前性能最好，应用最广泛的一种，只是可惜还没有遇到过这样的VPN。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;Mac下的VPN连接的创建&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;不得不说Mac下VPN连接的创建和管理非常方便、简单。记得之前在Fedora下为了配置一个能够使用PPTP的VPN连接，费了九牛二虎之力，Mac下，很轻松的就搞定了。言归正传，首先进入Mac的&amp;#8220;网络配置&amp;#8221; Network Preferences。可以通过状态栏的网络图表进入，也可以从系统配置中选择网络 Network进入，如下图：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/ScreenShot2012-01-16at%E4%B8%8B%E5%8D%882.17.57.png" width="671" height="560" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p3433/fb284cd895f55932f29ac1e16d6eeb7c.png"  alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;进入网络后，看到列表下方有个加减号，用来添加和删除网络连接。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/ScreenShot2012-01-16at%E4%B8%8B%E5%8D%882.19.54.png" width="679" height="587" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p3433/dfd4445df67c46a36707c3a80155cadf.png"  alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;点击加号后可以创建一个新的连接，选择VPN，VPN下有三种类型，分别是：PPTP、Cisco IPSec、L2TP Over IPSec。可以根据自己的情况选择适用的类型，并且可以为每一个连接起一个名字，方便记忆。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/ScreenShot2012-01-16at%E4%B8%8B%E5%8D%883.21.12.png" width="429" height="206" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;下面就是具体每种类型的配置方法：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;1、使用PPTP的方式&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;PPTP的连接方式比较简单，界面如下图：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/ScreenShot2012-01-17at%E4%B8%8A%E5%8D%8810.53.53.png" width="465" height="417" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p3433/a98c27c2f5aa99875bcb396c442c4964.png"  alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;其中服务器地址 Server Address这一栏填写从公司网管那里获得的VPN地址&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;用户名 Account Name 这一栏填写自己的用户名&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;因为是动态密码，所以每次连接的时候会提示输入密码，配置界面就没有密码的输入框了。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;配制完成后点击状态栏的VPN连接图标，会弹出输入密码的对话框。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/ScreenShot2012-01-17at%E4%B8%8A%E5%8D%8810.56.04.png" width="433" height="272" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p3433/86be470b25e651a60fdae0d901d50aa8.png"  alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;验证成功后，就可以在状态栏看到VPN的连接了，会显示连接的时长。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong&gt;2、使用Cisco IPSec方式&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;适用Cisco IPSec的方式创建过程和PPTP大同小异，也是在网络配置面板中点击加号进行创建。在配置的时候与PPTP有些不同，先看截图：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/ScreenShot2012-01-17at%E4%B8%8A%E5%8D%8811.00.36.png" width="683" height="587" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p3433/4f337b66f6481f3220e2ee34270a0043.png"  alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;在服务器地址 Server Address中填写公司VPN的地址；&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;在用户名 Account Name 中填写用户名；&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;在密码 Password 这一栏中留空，因为每次需要输入SecurID的动态密码；&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;然后点击授权设置 Authentication Settings&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;在 共享密钥 Shared Secret 中填入从公司网管那里得到的共享密钥（）；&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;在 组名 Group Name 中填写 自己VPN所属的组名；&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;关于共享密钥，有些公司会以明文的形式告知，有的会用PGP的方式发送一个加密的密码，需要使用自己的私钥解密后使用。这个过程大多数都会有文档说明，这里就不过多阐述了。流程也可以参考之前的一篇文章：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;SecurID卡小贴士：SecurID卡坚固小巧，用起来也很方便，只是千万要小心别丢失了，因为可以是要花大洋赔偿的。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;参考资料：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、&lt;a href="http://kerneltravel.eefocus.com/Kevin/blog/11-09/230878_53c71.html"&gt;Mac下配置基于SecureID的Cisco IPSec VPN全攻略&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、&lt;a href="http://baike.baidu.com/view/19735.htm"&gt;百度百科VPN&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、&lt;a href="http://www.iteye.com/topic/593613"&gt;Mac使用VPNC连接Cisco IPSec&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2324950.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2012/01/17/2324950.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/12/29/2305955.html</id><title type="text">短链接算法收集与分析</title><summary type="text">短链接就不说了，大家已经都清楚了，如下所示就是短链接： 新浪微博 http://t.cn/SVpONM 腾讯微博 http://url.cn/302yor Yun.io http://d.yun.io/PNri2v 短链接的好处：1、内容需要；2、用户友好；3、便于管理。 如何实现呢，大概有三个步骤： 1、定义一个URL映射算法，可以将长的URL映射成短字符串； 2、使用一个存储（数据库？NoSQL？）来存储完成的映射； 3、实现自己的URL映射算法； 一般来说，第三步是我们比较头疼的，如何将一个长的URL字符串，映射成一个较短的字符串呢。我总结了三种办法： ...</summary><published>2011-12-29T05:10:00Z</published><updated>2011-12-29T05:10:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/12/29/2305955.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/12/29/2305955.html"/><content type="html">&lt;p&gt;短链接就不说了，大家已经都清楚了，如下所示就是短链接：&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;新浪微博&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://t.cn/SVpONM"&gt;http://t.cn/SVpONM&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;腾讯微博&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://url.cn/302yor?type=1&amp;amp;from=19&amp;amp;u=wonwang&amp;amp;s=3&amp;amp;f=1&amp;amp;skey="&gt;http://url.cn/302yor&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Yun.io&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;a href="http://d.yun.io/PNri2v"&gt;http://d.yun.io/PNri2v&lt;/a&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;短链接的好处：1、内容需要；2、用户友好；3、便于管理。&lt;/p&gt;  &lt;p&gt;如何实现呢，大概有三个步骤：&lt;/p&gt;  &lt;p&gt;1、定义一个URL映射算法，可以将长的URL映射成短字符串；&lt;/p&gt;  &lt;p&gt;2、使用一个存储（数据库？NoSQL？）来存储完成的映射；&lt;/p&gt;  &lt;p&gt;3、实现自己的URL映射算法；&lt;/p&gt;  &lt;p&gt;一般来说，第三步是我们比较头疼的，如何将一个长的URL字符串，映射成一个较短的字符串呢。我总结了三种办法：&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;普通实现&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;我想以前大家学习过十进制和二进制的互相转换，或者十进制和十六进制的互相转换，那么为了更短，我们可以使用62进制，对于一个数字ID进行转码，转换成一个短字符串。&lt;/p&gt;  &lt;p&gt;这种做法的缺点是没有办法保证所有链接都是固定的位数的长度，而且在高并发的情况下，如何保证能够快速分发是个问题。&lt;/p&gt;  &lt;p&gt;具体实现方法：&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;/**     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * 利用62进制对数字ID进行短链接编码，缺点不能保证每个短链接是固定长度      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @author&amp;nbsp; wanshiqiang&amp;lt;wangshiqiang@360.cn&amp;gt;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param integer $integer      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param string $base      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private function getShortenedURLFromID ($integer, $base = ALLOWED_CHARS)      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $length = strlen($base);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while($integer &amp;gt; $length - 1)      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $out = $base[fmod($integer, $length)] . $out;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $integer = floor( $integer / $length );      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $base[$integer] . $out;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /**      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * 对62进制编码的短链接进行解码      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; *      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @author&amp;nbsp; wangshiqiang&amp;lt;wangshiqiang@360.cn&amp;gt;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param string $string      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; * @param string $base      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private function getIDFromShortenedURL ($string, $base = ALLOWED_CHARS)      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $length = strlen($base);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $size = strlen($string) - 1;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $string = str_split($string);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $out = strpos($base, array_pop($string));      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach($string as $i =&amp;gt; $char)      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $out += strpos($base, $char) * pow($length, $size - $i);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $out;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;文艺实现&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;算法描述：使用6个字符来表示短链接，我们使用ASCII字符中的'a'-'z','0'-'5'，共计32个字符做为集合。每个字符有32种状态，六个字符就可以表示32^6（1073741824），那么如何得到这六个字符，描述如下：&lt;/p&gt;  &lt;p&gt;对传入的长URL进行Md5，得到一个32位的字符串，这个字符串变化很多，是16的32次方，基本上可以保证唯一性。将这32位分成四份，每一份8个字符，这时机率变成了16的8次方，是4294967296，这个数字碰撞的机率也比较小啦，关键是后面的一次处理。我们将这个8位的字符认为是16进制整数，也就是1*('0x'.$val)，然后取0-30位，每5个一组，算出他的整数值，然后映射到我们准备的32个字符中，最后就能够得到一个6位的短链接地址。&lt;/p&gt;  &lt;p&gt;PHP实现如下：&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;function shorten( $long_url )     &lt;br /&gt;{      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $base32 = "abcdefghijklmnopqrstuvwxyz012345";      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $hex = md5( $long_url );      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $hexLen = strlen( $hex );      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $subHexLen = $hexLen / 8;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $output = array();      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for( $i = 0; $i &amp;lt; $subHexLen; $i++ )      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $subHex = substr( $hex, $i * 8, 8 );      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $subHex = 0x3FFFFFFF &amp;amp; ( 1 * ('0x' . $subHex ) ); &lt;/p&gt;&lt;p&gt;$out = '';&amp;nbsp;&lt;/p&gt;&lt;p&gt;for( $j = 0; $j &amp;lt; 6; $j++ )      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $val = 0x0000001F &amp;amp; $int;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $out .= $base32[$val];      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $int = $int &amp;gt;&amp;gt; 5;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $output[] = $out;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $output;      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;二逼实现&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;下面这个函数使用了纯随机的方式来生成一个短链接，虽然我们可以通过查询操作来确保不重复使用短链接，可是... 这样真的靠谱吗~~&lt;/p&gt;  &lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;   &lt;p&gt;function random($length, $pool = '') {     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $random = '';      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (empty($pool)) { $pool&amp;nbsp;&amp;nbsp;&amp;nbsp; = 'abcdefghkmnpqrstuvwxyz'; $pool&amp;nbsp;&amp;nbsp; .=      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '23456789'; }      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; srand ((double)microtime()*1000000);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for($i = 0; $i &amp;lt; $length; $i++) { $random .=      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; substr($pool,(rand()%(strlen ($pool))), 1); }      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return $random;      &lt;br /&gt;}&lt;/p&gt; &lt;/blockquote&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1296de55-0862-4b26-98eb-264397851b41" &gt;Technorati 标签: &lt;a href="http://technorati.com/tags/%e7%9f%ad%e9%93%be%e6%8e%a5" rel="tag"&gt;短链接&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Short+Url" rel="tag"&gt;Short Url&lt;/a&gt;,&lt;a href="http://technorati.com/tags/%e6%98%a0%e5%b0%84" rel="tag"&gt;映射&lt;/a&gt;,&lt;a href="http://technorati.com/tags/%e5%93%88%e5%b8%8c" rel="tag"&gt;哈希&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;参考资料：&lt;/p&gt;  &lt;p&gt;1、&lt;a href="http://qn-lf.iteye.com/blog/1084516"&gt;微博短地址原理解析&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2、&lt;a href="http://www.iteye.com/topic/973365?page=2"&gt;微博短域名原理及作用&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3、&lt;a href="http://code.google.com/p/yourls/downloads/list"&gt;Yours.org&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;4、&lt;a href="http://briancray.com/2009/08/26/free-php-url-shortener-script/"&gt;Free PHP URL Shorten script that kicks ass&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5、&lt;a href="http://www.snippetit.com/2009/04/php-short-url-algorithm-implementation/"&gt;PHP Short Url Algorithm Implementation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;6、&lt;a href="http://www.snippetit.com/2008/10/implement-your-own-short-url/"&gt;Implement your own short URL&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;7、&lt;a href="http://hi.baidu.com/jok607/blog/item/a2258b25ce28827a35a80f6b.html"&gt;短网址算法初步汇总&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;8、&lt;a href="http://i.laoer.com/short-url.html"&gt;Short Url 实现方式&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2305955.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/12/29/2305955.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/12/20/2294564.html</id><title type="text">Hadoop学习笔记一：单节点安装</title><summary type="text">通过本节的学习，可以掌握如何在单节点上使用Hadoop进行Map/Reduce以及HDFS存储的实现。 环境要求： 支持的平台： 支持GNU/Linux平台，可以作为测试和生产环境使用。Hadoop在2000个节点的生产环境中经受过考验。 支持Win32平台作为测试环境，正式环境的测试还不够充分，所以发布版暂时不能支持Win32环境。 需要的软件： 1、J...</summary><published>2011-12-20T04:53:00Z</published><updated>2011-12-20T04:53:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/12/20/2294564.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/12/20/2294564.html"/><content type="html">&lt;p&gt;通过本节的学习，可以掌握如何在单节点上使用Hadoop进行Map/Reduce以及HDFS存储的实现。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;环境要求：&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;支持的平台：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 支持GNU/Linux平台，可以作为测试和生产环境使用。Hadoop在2000个节点的生产环境中经受过考验。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 支持Win32平台作为测试环境，正式环境的测试还不够充分，所以发布版暂时不能支持Win32环境。&lt;/p&gt;  &lt;p&gt;需要的软件：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 1、Java 1.6.x，必须。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 2、ssh、sshd，必须。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 如果是在Windows环境下，你也许需要 Cygwin。&lt;/p&gt;  &lt;p&gt;安装必要的软件&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 如果服务器没有必要的软件，就必须进行安装。不同的发行版本，有不同的安装方法。例如Ubuntu下：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $ sudo apt-get install ssh&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $ sudo apt-get install rsync&lt;/p&gt;  &lt;p&gt;&lt;b&gt;下载Hadoop&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 从 &lt;a href="http://hadoop.apache.org/core/releases.html"&gt;这里&lt;/a&gt; 下载一个Hadoop的稳定版本。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;开始我们的Hadoop之旅&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 解压下载的软件，在解压后的目录中，编辑 conf/hadoop-env.sh 脚本设置服务器的JAVA_HOME目录。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 我的环境是 Centos6.0，yum安装了OPEN-JDK，对应的目录为： &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/jre/&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 执行 bin/hadoop 命令，如果如下图所示，我们就做好使用 Hadoop 的准备了。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/cocowool/201112/201112201253251360.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Image(1)" border="0" alt="Image(1)" src="http://images.cnblogs.com/cnblogs_com/cocowool/201112/201112201253263344.png" width="244" height="181" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 可以用三种方式使用Hadoop：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 本地模式(Local Standalone Mode)；&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 伪分布式模式(Pseudo-Distributed Mode)；&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 完全分布式模式；&lt;/p&gt;  &lt;p&gt;&lt;b&gt;本地模式&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 默认情况下，Hadoop是配置为本地运行的，以一个单独的Java进程运行，这种方式非常适合Debug。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 在本地，我选择了对 194Mb 的访问日志进行分析，如下代码：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bin/hadoop jar hadoop-examples-0.20.203.0.jar grep input/ output/ 'favicon[a-z.]+'&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 这个任务是分析日志中出现的favicon的次数，统计结果如下：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/cocowool/201112/201112201253268361.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Image(2)" border="0" alt="Image(2)" src="http://images.cnblogs.com/cnblogs_com/cocowool/201112/201112201253265886.png" width="244" height="36" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 其中part文件中存储了我要查找的favicon字符串出现的次数。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;伪分布式模式&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;配置：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 参照官方的配置进行，分别对conf/core-site.xml、conf/hdf-site.xml、conf/mapred-site.xml进行配置。配置的内容都比较类似，主要是配置一个服务器的主机名，然后配置对应的IP或值。&lt;/p&gt;  &lt;p&gt;设置无需密码的SSH：&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 按照官方的设置&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $ cat ~/.ssh/id_dsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 但是第一次登陆的时候始终需要提示是否保存，这个有点不得其解。&lt;/p&gt;  &lt;p&gt;&lt;b&gt;执行：&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 首先格式化一个新的分布式文件系统&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $ bin/hadoop namenode -format&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 完成后，会有一些提示，根据提示可以在 /tmp/hadoop-root/dfs 中找到两个文件夹。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 然后启动 Hadoop 的守护进程&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $ bin/start-all.sh&lt;/p&gt;  &lt;p&gt;&lt;strike&gt;我在安装的过程中提示了未知的jvm参数，但是并没有重大的影响，启动仍正常结束了，不知道什么原因&lt;/strike&gt;。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 这个问题是因为用root用户启动造成的，可以参考参考资料6中的方法，为hadoop这个文件打一个patch就可以解决。然后重新格式化namenode，进行测试。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; bin/hadoop jar hadoop-examples-0.20.203.0.jar grep logs output 'favicon'&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 执行上面的语句，可以对日志进行 WordCount 的分析。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 测试完成后，可以关闭所有的服务&lt;/p&gt;  &lt;p&gt;bin/stop-all.sh&lt;/p&gt;  &lt;p&gt;参考资料：&lt;/p&gt;  &lt;p&gt;1、&lt;a href="http://hadoop.apache.org/common/docs/stable/single_node_setup.html"&gt;Single Node Setup&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2、&lt;a href="http://hadoop.apache.org/common/docs/r0.20.0/hdfs_shell.html#put"&gt;Hdfs Shell Handbook&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3、&lt;a href="http://stackoverflow.com/questions/5293446/hdfs-error-could-only-be-replicated-to-0-nodes-instead-of-1"&gt;Hdfs error：could only be replicated to 0 nodes instead of 1&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;4、&lt;a href="http://www.koopman.me/2009/04/hadoop-0183-could-not-create-the-java-virtual-machine/"&gt;Hadoop：Could not create Java Virtual Machine&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5、&lt;a href="http://lucene.472066.n3.nabble.com/Namenode-not-starting-td3302351.html"&gt;Namenode not starting&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;6、&lt;a href="https://issues.apache.org/jira/browse/HDFS-1943"&gt;Faile to start datanode while start-dfs.sh is executed by root user&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2294564.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/12/20/2294564.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/12/14/2287360.html</id><title type="text">VirtualBox克隆后无法找到网卡的问题</title><summary type="text">Virtualbox现在更新到了4.1.6版本，我记得在之前的版本中，镜像的克隆只能通过命令行的方式来进行，现在已经可以通过界面来进行克隆了，可以说非常的方便。 克隆的时候，我选择了Reinitialize the MAC address of all the network cards。 开机启动之后，发现找不到网卡，无论netwok restart还是reboot都是无效，报错如下。 ...</summary><published>2011-12-14T03:31:00Z</published><updated>2011-12-14T03:31:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/12/14/2287360.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/12/14/2287360.html"/><content type="html">&lt;p&gt;Virtualbox现在更新到了4.1.6版本，我记得在之前的版本中，镜像的克隆只能通过命令行的方式来进行，现在已经可以通过界面来进行克隆了，可以说非常的方便。&lt;/p&gt;  &lt;p&gt;克隆的时候，我选择了Reinitialize the MAC address of all the network cards。&lt;/p&gt;  &lt;p&gt;开机启动之后，发现找不到网卡，无论netwok restart还是reboot都是无效，报错如下。&lt;/p&gt;  &lt;p&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Device eth0 does not seem to be present, delayinitialization.&lt;/p&gt;  &lt;p&gt;使用参考资料中的 mv /etc/udev/rules.d/70-persistent-net.rules ~ 重启也没有用。&lt;/p&gt;  &lt;p&gt;然后定睛看了一下这个文件的内容，发现 NAME 的地方配置的有问题，而且克隆后的机器，网卡配置中的MAC地址没有对应的更新，需要手工修改下。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/cocowool/201112/201112141131163985.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="Image" border="0" alt="Image" src="http://images.cnblogs.com/cnblogs_com/cocowool/201112/201112141131177606.png" width="244" height="162" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;一切完成后，重新启动服务器，网卡正常工作，OK！&lt;/p&gt;  &lt;p&gt;参考资料：&lt;/p&gt;  &lt;p&gt;1、&lt;a href="http://zxh116116.iteye.com/blog/1172039"&gt;Virtualbox克隆&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;2、&lt;a href="http://hi.baidu.com/52xjm/blog/item/0e7cf6fc98474a98b901a0a2.html"&gt;VMWare克隆或复制虚拟机后找不到网卡的解决方法&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;3、&lt;a href="http://linux.die.net/man/8/udev"&gt;udev - Linux Man Page&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2287360.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/12/14/2287360.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/12/08/2280670.html</id><title type="text">Centos6最小化安装中设置网卡默认启动</title><summary type="text">Centos 6.0版本提供了一个&amp;quot;最小化&amp;quot;（Minimal）安装的选项。这是一个非常好的改进，因为系统中再也不会存在那些不必要的文件和服务，这样我们就可以实现服务器为我们所需要的服务提供最大的资源能力。Minimal的安装也带来了一些缺点，系统默认提供的网络管理工具 NetworkManager 实际上没有安装在 Minimal 的系统上。这样我们就不得不手工编辑网卡的配置文件。典型的网卡配置文件（/etc/sysconfig/network-script/ifcfg-X）格式如下： IPADDR=192.168.0.33 BOOTPROTO=none NETMA...</summary><published>2011-12-08T06:02:00Z</published><updated>2011-12-08T06:02:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/12/08/2280670.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/12/08/2280670.html"/><content type="html">&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;Centos 6.0版本提供了一个"最小化"（Minimal）安装的选项。这是一个非常好的改进，因为系统中再也不会存在那些不必要的文件和服务，这样我们就可以实现服务器为我们所需要的服务提供最大的资源能力。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;Minimal的安装也带来了一些缺点，系统默认提供的网络管理工具 NetworkManager 实际上没有安装在 Minimal 的系统上。这样我们就不得不手工编辑网卡的配置文件。典型的网卡配置文件（/etc/sysconfig/network-script/ifcfg-X）格式如下：&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;pre style="line-height: normal; "&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; white-space: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;     IPADDR=192.168.0.33      &lt;br /&gt;BOOTPROTO=none &lt;br /&gt;     NETMASK=255.255.255.0 &lt;br /&gt;     GATEWAY=192.168.0.1 &lt;br /&gt;     DNS1=192.168.0.1      &lt;br /&gt;DNS2=192.168.0.2      &lt;br /&gt;USERCTL=yes &lt;br /&gt;     ONBOOT="yes" &lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: normal; "&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; white-space: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;Centos 6的Minimal下，默认onboot="no"，并且设置了依赖 NetworkManager 的选项，NM_CONTROLLED="yes"。这个配置看起来有点可笑，因为minimal的情况下并没有安装 NetworkManger。所以我们需要修改为： &lt;/span&gt;&lt;/pre&gt;&lt;pre style="line-height: normal; "&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; white-space: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;     ONBOOT="yes"      MM_Controlled="no" &lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;同时，如果需要自动获取IP，我们还应该加上&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BOOTPROTO="dhcp"&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;现在重启一下，网卡就可以随机启动了。&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;参考资料：&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;1、&lt;a href="http://diznix.com/2011/07/11/network-configuration-in-minimal-linux-installs/"&gt;Netowork Configuration in minimal Linux installs&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;2、&lt;a href="http://it.toolbox.com/blogs/linux-gnu/configuring-the-ethernet-nic-in-centos-6-rhel-6-scientific-linux-6-48390"&gt;Configuring the ethernet nic in centos 6&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;3、&lt;a href="http://home.roadrunner.com/%7Ecomputertaijutsu/wireless.html"&gt;Troubleshooting Linux Connections&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="border-collapse: separate; font-family: Tahoma; line-height: normal; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; font-size: medium; "&gt;4、&lt;a href="http://226617.cn/archives/929.htm"&gt;克隆Centos6虚拟机后网络无法启动问题解决&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2280670.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/12/08/2280670.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/12/04/2275497.html</id><title type="text">使用PHP脚本来写Daemon程序</title><summary type="text">什么是Daemon进程这又是一个有趣的概念，daemon在英语中是&amp;quot;精灵&amp;quot;的意思，就像我们经常在迪斯尼动画里见到的那些，有些会飞，有些不会，经常围着动画片的主人公转来转去，啰里啰唆地提一些忠告，时不时倒霉地撞在柱子上，有时候还会想出一些小小的花招，把主人公从敌人手中救出来，正因如此，daemon有时也被译作&amp;quot;守护神&amp;quot;。所以，daemon进程在国内也有两种译法，有些人译作&amp;quot;精灵进程&amp;quot;，有些人译作&amp;quot;守护进程&amp;quot;，这两种称呼的出现频率都很高。与真正的daemon相似，daemon进程也习惯于把自己隐藏在人们的视线之外，默默</summary><published>2011-12-04T07:48:00Z</published><updated>2011-12-04T07:48:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/12/04/2275497.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/12/04/2275497.html"/><content type="html">&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&#xD;
&lt;!--?xml version="1.0" encoding="UTF-8" standalone="no"?--&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;span style="font-size: 24px; "&gt;&lt;strong&gt;什么是Daemon进程&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;这又是一个有趣的概念，daemon在英语中是"精灵"的意思，就像我们经常在迪斯尼动画里见到的那些，有些会飞，有些不会，经常围着动画片的主人公转来转去，啰里啰唆地提一些忠告，时不时倒霉地撞在柱子上，有时候还会想出一些小小的花招，把主人公从敌人手中救出来，正因如此，daemon有时也被译作"守护神"。所以，daemon进程在国内也有两种译法，有些人译作"精灵进程"，有些人译作"守护进程"，这两种称呼的出现频率都很高。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;与真正的daemon相似，daemon进程也习惯于把自己隐藏在人们的视线之外，默默为系统做出贡献，有时人们也把它们称作"后台服务进程"。daemon进程的寿命很长，一般来说，从它们一被执行开始，直到整个系统关闭，它们才会退出。几乎所有的服务器程序，包括我们熟知的Apache和wu-FTP，都用daemon进程的形式实现。很多Linux下常见的命令如inetd和ftpd，末尾的字母d就是指daemon。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;为什么一定要使用daemon进程呢？Linux中每一个系统与用户进行交流的界面称为终端（terminal），每一个从此终端开始运行的进程都会依附于这个终端，这个终端就称为这些进程的控制终端（Controlling terminal），当控制终端被关闭时，相应的进程都会被自动关闭。关于这点，读者可以用X-Window中的XTerm试验一下，（每一个XTerm就是一个打开的终端，）我们可以通过键入命令启动应用程序，比如：$netscape&amp;nbsp;然后我们关闭XTerm窗口，刚刚启动的netscape窗口也会随之一同突然蒸发。但是daemon进程却能够突破这种限制，即使对应的终端关闭，它也能在系统中长久地存在下去，如果我们想让某个进程长命百岁，不因为用户或终端或其他的变化而受到影响，就必须把这个进程变成一个daemon进程。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong style="font-size: 24px; "&gt;Daemon进程的编程规则&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;如果想把自己的进程变成daemon进程，我们必须严格按照以下步骤进行：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、调用fork产生一个子进程，同时父进程退出。我们所有后续工作都在子进程中完成。这样做我们可以：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;1.1 如果我们是从命令行执行的该程序，这可以造成程序执行完毕的假象，shell会回去等待下一条命令；&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;1.2 刚刚通过fork产生的新进程一定不会是一个进程组的组长，这为第2步的执行提供了前提保障。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;这样做还会出现一种很有趣的现象：由于父进程已经先于子进程退出，会造成子进程没有父进程，变成一个孤儿进程（orphan）。每当系统发现一个孤儿进程，就会自动由1号进程收养它，这样，原先的子进程就会变成1号进程的子进程。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;2、调用setsid系统调用。这是整个过程中最重要的一步。&lt;font color="#ff2617"&gt;setsid的介绍见附录2&lt;/font&gt;，它的作用是创建一个新的会话（session），并自任该会话的组长（session leader）。如果调用进程是一个进程组的组长，调用就会失败，但这已经在第1步得到了保证。调用setsid有3个作用：&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2.1 让进程摆脱原会话的控制；&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2.2 让进程摆脱原进程组的控制；&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;2.3 让进程摆脱原控制终端的控制；&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;总之，就是让调用进程完全独立出来，脱离所有其他进程的控制。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;3、把当前工作目录切换到根目录。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;如果我们是在一个临时加载的文件系统上执行这个进程的，比如：/mnt/floppy/，该进程的当前工作目录就会是/mnt/floppy/。在整个进程运行期间该文件系统都无法被卸下（umount），而无论我们是否在使用这个文件系统，这会给我们带来很多不便。解决的方法是使用chdir系统调用把当前工作目录变为根目录，应该不会有人想把根目录卸下吧。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;关于chdir的用法，参见附录1。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;当然，在这一步里，如果有特殊的需要，我们也可以把当前工作目录换成其他的路径，比如/tmp。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;4、将文件权限掩码设为0。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;这需要调用系统调用umask，参见附录3。每个进程都会从父进程那里继承一个文件权限掩码，当创建新文件时，这个掩码被用于设定文件的默认访问权限，屏蔽掉某些权限，如一般用户的写权限。当另一个进程用exec调用我们编写的daemon程序时，由于我们不知道那个进程的文件权限掩码是什么，这样在我们创建新文件时，就会带来一些麻烦。所以，我们应该重新设置文件权限掩码，我们可以设成任何我们想要的值，但一般情况下，大家都把它设为0，这样，它就不会屏蔽用户的任何操作。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;如果你的应用程序根本就不涉及创建新文件或是文件访问权限的设定，你也完全可以把文件权限掩码一脚踢开，跳过这一步。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;5、关闭所有不需要的文件。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;同文件权限掩码一样，我们的新进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不被我们的daemon进程读或写，但它们一样消耗系统资源，而且可能导致所在的文件系统无法卸下。需要指出的是，文件描述符为0、1和2的三个文件（文件描述符的概念将在下一章介绍），也就是我们常说的输入、输出和报错这三个文件也需要被关闭。很可能不少读者会对此感到奇怪，难道我们不需要输入输出吗？但事实是，在上面的第2步后，我们的daemon进程已经与所属的控制终端失去了联系，我们从终端输入的字符不可能达到daemon进程，daemon进程用常规的方法（如printf）输出的字符也不可能在我们的终端上显示出来。所以这三个文件已经失去了存在的价值，也应该被关闭。&amp;nbsp;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;span style="font-size: 24px; "&gt;使用PHP编写Gearman的Worker守护进程&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;在我之前的文章中，介绍过Gearman的使用。在我的项目中，我使用了PHP来编写一直运行的Worker。如果按照Gearman官方推荐的例子，只是简单的一个循环来等待任务，会有一些问题，包括：1、当代码进行过修改之后，如何让代码的修改生效；2、重启Worker的时候，如何保证当前的任务处理完成才重启。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;针对这个问题，我考虑了以下的解决方法：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、每次修改完代码后，Worker需要手工重启（先杀死然后启动）。这个只能解决重新加载配置文件的问题。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、在Worker中设置，单次任务循环完成后，就对Worker进行重启。这个方案的问题在于消耗比较大。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、在Worker中添加一个退出函数，如果需要Worker退出的时候，在Client端发送一个优先级比较高的退出调用。这个需要客户端配合，在使用后台类任务时，不太适合。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;4、在Worker中检查文件是否发生变化，如果发生了变化，退出并重启自身。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;5、为Worker编写信号控制，接受重启指令，类似于 http restart graceful 指令。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;最后，结合4和5两种方法，可以实现这样一个Daemon，如果配置文件发生了变化，他就会自动重启；如果接受到了用户的 kill &amp;nbsp;-1 pid 信号，也会重新启动。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;代码如下：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;div&gt;&amp;lt;?php&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&lt;span style="color: #0000FF;"&gt;declare&lt;/span&gt;(&amp;nbsp;ticks&amp;nbsp;=&amp;nbsp;1&amp;nbsp;);&lt;br /&gt;&#xD;
&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;This&amp;nbsp;case&amp;nbsp;will&amp;nbsp;check&amp;nbsp;the&amp;nbsp;config&amp;nbsp;file&amp;nbsp;regularly,&amp;nbsp;if&amp;nbsp;the&amp;nbsp;config&amp;nbsp;file&amp;nbsp;changed,&amp;nbsp;it&amp;nbsp;will&amp;nbsp;restart&amp;nbsp;it&amp;nbsp;self&lt;br /&gt;&#xD;
//&amp;nbsp;If&amp;nbsp;you&amp;nbsp;want&amp;nbsp;to&amp;nbsp;restart&amp;nbsp;the&amp;nbsp;daemon&amp;nbsp;gracefully,&amp;nbsp;give&amp;nbsp;it&amp;nbsp;a&amp;nbsp;HUP&amp;nbsp;signal&lt;br /&gt;&#xD;
//&amp;nbsp;by&amp;nbsp;shiqiang&amp;lt;cocowool@gmail.com&amp;gt;&amp;nbsp;at&amp;nbsp;2011-12-04&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&lt;br /&gt;&#xD;
&lt;span style="color: #800080;"&gt;$init_md5&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #008080;"&gt;md5_file&lt;/span&gt;(&amp;nbsp;'config.php');&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;nbsp;register&amp;nbsp;signal&amp;nbsp;handler&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;pcntl_signal(&amp;nbsp;SIGALRM,&amp;nbsp;"signal_handler",&amp;nbsp;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&amp;nbsp;);&lt;br /&gt;&#xD;
pcntl_signal(&amp;nbsp;SIGHUP,&amp;nbsp;'signal_handler',&amp;nbsp;&lt;span style="color: #0000FF;"&gt;TRUE&lt;/span&gt;&amp;nbsp;);&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&lt;span style="color: #800080;"&gt;$job_flag&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #0000FF;"&gt;FALSE&lt;/span&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Job&amp;nbsp;status&amp;nbsp;flag,&amp;nbsp;to&amp;nbsp;justify&amp;nbsp;if&amp;nbsp;the&amp;nbsp;job&amp;nbsp;has&amp;nbsp;been&amp;nbsp;finished&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&lt;span style="color: #800080;"&gt;$signal_flag&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #0000FF;"&gt;FALSE&lt;/span&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Signal&amp;nbsp;status&amp;nbsp;flag,&amp;nbsp;to&amp;nbsp;justify&amp;nbsp;whether&amp;nbsp;we&amp;nbsp;received&amp;nbsp;the&amp;nbsp;kill&amp;nbsp;-1&amp;nbsp;signal&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&lt;br /&gt;&#xD;
&lt;span style="color: #0000FF;"&gt;while&lt;/span&gt;(&amp;nbsp;1&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800080;"&gt;$job_flag&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #0000FF;"&gt;FALSE&lt;/span&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Job&amp;nbsp;status&amp;nbsp;flag&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;"Worker&amp;nbsp;start&amp;nbsp;running&amp;nbsp;...&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008080;"&gt;sleep&lt;/span&gt;(5);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;"Worker's&amp;nbsp;task&amp;nbsp;done&amp;nbsp;...&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800080;"&gt;$flag&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #0000FF;"&gt;TRUE&lt;/span&gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;Job&amp;nbsp;status&amp;nbsp;flag&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AutoStart(&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal_flag&lt;/span&gt;&amp;nbsp;);&lt;br /&gt;&#xD;
}&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&amp;nbsp;signal_handler(&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;)&amp;nbsp;{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;global&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;$job_flag&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;global&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal_flag&lt;/span&gt;;&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;switch&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;case&lt;/span&gt;&amp;nbsp;SIGQUIT:&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008080;"&gt;date&lt;/span&gt;('y-m-d&amp;nbsp;H:i:s',&amp;nbsp;&lt;span style="color: #008080;"&gt;time&lt;/span&gt;()&amp;nbsp;)&amp;nbsp;.&amp;nbsp;"&amp;nbsp;Caught&amp;nbsp;Signal&amp;nbsp;:&amp;nbsp;SIGQUIT&amp;nbsp;-&amp;nbsp;No&amp;nbsp;:&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;exit&lt;/span&gt;(0);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;break&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;case&lt;/span&gt;&amp;nbsp;SIGSTOP:&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008080;"&gt;date&lt;/span&gt;('y-m-d&amp;nbsp;H:i:s',&amp;nbsp;&lt;span style="color: #008080;"&gt;time&lt;/span&gt;()&amp;nbsp;)&amp;nbsp;.&amp;nbsp;"&amp;nbsp;Caught&amp;nbsp;Signal&amp;nbsp;:&amp;nbsp;SIGSTOP&amp;nbsp;-&amp;nbsp;No&amp;nbsp;:&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;break&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;case&lt;/span&gt;&amp;nbsp;SIGHUP:&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008080;"&gt;date&lt;/span&gt;('y-m-d&amp;nbsp;H:i:s',&amp;nbsp;&lt;span style="color: #008080;"&gt;time&lt;/span&gt;()&amp;nbsp;)&amp;nbsp;.&amp;nbsp;"&amp;nbsp;Caught&amp;nbsp;Signal&amp;nbsp;:&amp;nbsp;SIGHUP&amp;nbsp;-&amp;nbsp;No&amp;nbsp;:&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$flag&lt;/span&gt;&amp;nbsp;===&amp;nbsp;&lt;span style="color: #0000FF;"&gt;TRUE&lt;/span&gt;&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;AutoStart(&amp;nbsp;&lt;span style="color: #0000FF;"&gt;TRUE&lt;/span&gt;&amp;nbsp;);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal_flag&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #0000FF;"&gt;TRUE&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;break&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;case&lt;/span&gt;&amp;nbsp;SIGALRM:&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;&lt;span style="color: #008080;"&gt;date&lt;/span&gt;('y-m-d&amp;nbsp;H:i:s',&amp;nbsp;&lt;span style="color: #008080;"&gt;time&lt;/span&gt;()&amp;nbsp;)&amp;nbsp;.&amp;nbsp;"&amp;nbsp;Caught&amp;nbsp;Signal&amp;nbsp;:&amp;nbsp;SIGALRM&amp;nbsp;-&amp;nbsp;No&amp;nbsp;:&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;pcntl_exec(&amp;nbsp;'/bin/ls'&amp;nbsp;);&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pcntl_alarm(&amp;nbsp;5&amp;nbsp;);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;break&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;default&lt;/span&gt;:&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;break&lt;/span&gt;;&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&#xD;
}&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&amp;nbsp;AutoStart(&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #0000FF;"&gt;FALSE&lt;/span&gt;,&amp;nbsp;&lt;span style="color: #800080;"&gt;$filename&lt;/span&gt;&amp;nbsp;=&amp;nbsp;'config.php'&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;global&lt;/span&gt;&amp;nbsp;&lt;span style="color: #800080;"&gt;$init_md5&lt;/span&gt;;&lt;br /&gt;&#xD;
&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$signal&lt;/span&gt;&amp;nbsp;||&amp;nbsp;&lt;span style="color: #008080;"&gt;md5_file&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$filename&lt;/span&gt;&amp;nbsp;)&amp;nbsp;!=&amp;nbsp;&lt;span style="color: #800080;"&gt;$init_md5&lt;/span&gt;&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;"The&amp;nbsp;config&amp;nbsp;file&amp;nbsp;has&amp;nbsp;been&amp;nbsp;changed,&amp;nbsp;we&amp;nbsp;are&amp;nbsp;going&amp;nbsp;to&amp;nbsp;restart.&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800080;"&gt;$pid&lt;/span&gt;&amp;nbsp;=&amp;nbsp;pcntl_fork();&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$pid&lt;/span&gt;&amp;nbsp;==&amp;nbsp;-1&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;"Fork&amp;nbsp;error&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$pid&lt;/span&gt;&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;){&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;"Parent&amp;nbsp;exit&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;exit&lt;/span&gt;(0);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #800080;"&gt;$init_md5&lt;/span&gt;&amp;nbsp;=&amp;nbsp;&lt;span style="color: #008080;"&gt;md5_file&lt;/span&gt;(&amp;nbsp;&lt;span style="color: #800080;"&gt;$filename&lt;/span&gt;&amp;nbsp;);&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #0000FF;"&gt;print&lt;/span&gt;&amp;nbsp;"Child&amp;nbsp;continue&amp;nbsp;to&amp;nbsp;run&amp;nbsp;\n";&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&#xD;
}&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;参考资料：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、&lt;a href="https://github.com/shaneharter/PHP-Daemon"&gt;PHP-Daemon&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、&lt;a href="http://www.ibm.com/developerworks/cn/java/kernel/syscall/part4/"&gt;IBM Developers 系统调用跟我学&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、&lt;a href="http://www.cnblogs.com/leoo2sk/archive/2011/11/09/write-daemon-with-php.html"&gt;如何用PHP编写Daemon Process&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;4、&lt;a href="http://php.net/manual/en/function.exit.php"&gt;Function exit&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;5、&lt;a href="http://phpdaemon.net/"&gt;PHPDaemon&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;6、&lt;a href="http://stackoverflow.com/questions/2270323/stopping-gearman-workers-nicely"&gt;Stoping Gearman worker nicely&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;7、&lt;a href="http://topbit.co.uk/serendipity/archives/22-Doing-the-work-elsewhere-Sidebar-running-the-worker.html"&gt;Doing the worker elsewhere&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2275497.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/12/04/2275497.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/12/04/2275408.html</id><title type="text">Gearman的问题分析与深入研究</title><summary type="text">Gearman作为一个优秀的分布式解决方案，已经被众多的公司或者团队所采用，我在之前的一篇文章中也有过介绍。但是目前对于woker的执行状态和结果监控，特别是放入后台的worker的监控，官方还没有完善的解决方法。最近，为团队内部做了一次分享，我也得以深入的研究了 Gearmand。</summary><published>2011-12-04T06:35:00Z</published><updated>2011-12-04T06:35:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/12/04/2275408.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/12/04/2275408.html"/><content type="html">&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&#xD;
&lt;!--?xml version="1.0" encoding="UTF-8" standalone="no"?--&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;Gearman作为一个优秀的分布式解决方案，已经被众多的公司或者团队所采用，我在之前的&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/08/18/2145144.html"&gt;一篇文章&lt;/a&gt;中也有过介绍。但是目前对于woker的执行状态和结果监控，特别是放入后台的worker的监控，官方还没有完善的解决方法。最近，为团队内部做了一次分享，我也得以深入的研究了 Gearmand。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong style="font-size: 18px; "&gt;Gearman的主要作用：&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、Dispatch 任务调度（无负载调度）&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、Interface 多应用语言间接口&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、Parallel 并行计算&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong style="font-size: 18px; "&gt;Gearmand的安装&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;Gearmand 的安装有多种方式，在 Ubuntu 和 Debian 的系统中已经提供了&lt;a href="http://gearman.org/index.php?id=getting_started"&gt;在线安装的方法&lt;/a&gt;。编译安装的过程也比较简单：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;span style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;span style="border-collapse: separate; color: #000000; font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium; "&gt;&lt;span style="font-family: 'Lucida Grande', Verdana, Lucida, Helvetica, Arial, sans-serif; font-size: 13px; text-align: justify; "&gt;&#xD;
&lt;div style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 63px; "&gt;&#xD;
&lt;pre style="padding-top: 0.5em; padding-right: 0.5em; padding-bottom: 0.5em; padding-left: 0.5em; margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; font-size: 12px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: #000000; border-right-color: #000000; border-bottom-color: #000000; border-left-color: #000000; color: #000000; overflow-x: auto; overflow-y: auto; background-color: #eeeeee; "&gt;tar xzf gearmand-X.Y.tar.gz&#xD;
cd gearmand-X.Y&#xD;
./configure&#xD;
make&#xD;
make install&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;安装需要系统提供了 libevent，如果没有编译就会报错。编译安装完成后的提示如下：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111204-gearman/111.png" border="0" alt="" width="630" height="273" /&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p2934/98bfdb23a58e19f287b27d5dd51d7434.png" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;其中 libsqlite3、lbdrizzle、libmemcached、libpq、tokyocabinet的支持都是对于持久化来说的，如果需要要确保系统中安装了这些数据库。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;安装完成后，gearmand 提供了以下这些配置参数&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111204-gearman/222.jpg" border="0" alt="" width="649" height="669" /&gt;&amp;nbsp;&lt;/p&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p2934/be3115b70c1ce250f17c455ed6f0cb61.png" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong style="font-size: 18px; "&gt;性能的问题：&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;gearmand 中使用到了多线程模型，其线程分为三种：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Listening and management thread 监听和管理线程 － 只有一个：主要负责接受连接请求，并分配给I/O线程&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;I/O Thread I/O 线程 － 可以有很多个：主要负责读写系统调用，解析数据包&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Processing Thread 处理线程 &amp;nbsp;－ 只有一个：负责管理列表和Hash表，管理唯一Key、任务的Handle、函数、任务队列&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;刚才在 &amp;nbsp;gearmand 的参数中看到，-t 可以指定I/O线程的数量。如果 没有指定 t 或者 t = 0，则三个线程合为一个，所有的事情都在一个线程中处理。如果 -t 1 则有一个监听和管理线程、一个I/O和处理线程；如果 -t 2 则每个类别一个线程，如果大于2，则创建更多的I/O线程。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;官方提到，a 16 core Intel machine is able to process upwards of 50k jobs per second。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;strong style="font-size: 18px; "&gt;使用中应当关注的几个问题&lt;/strong&gt;：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、Job Server 的单点问题。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;实际上 Job Server 是存在单点问题的，我们只能通过增加冗余 Job Server 的方式来解决这个问题。就如官方的图例所示，下图：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="text-align: center; font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111204-gearman/333.jpg" border="0" alt="" width="390" height="178" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;我们可以通过配置域名、多个服务器配置列表等方法，在遇到其中一个 Job Server 失败时，将 Client 的请求转向另外的 Job Server。这种情况下，Job Server 中原来存在的任务会发生丢失，除非使用了数据库或其他类似的持久化方法。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、Job Server 重启后，Worker会自动重新注册。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;通过 gearmand -vvvvvvv &amp;nbsp;分析发现，如果 gearmand 关闭并重新启动后，原来的 worker 会马上与 Job Server 建立连接，并询问是否有任务。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111204-gearman/444.jpg" border="0" alt="" width="880" height="162" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、使用持久队列避免任务的丢失&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;因为 Gearmand 的队列是放在内存中的，所以宕机或重启事件会导致队列的丢失。为了避免这种情况，可以使用持久队列，将队列存储在一个相对中立的位置。注意，持久队列只对于后台任务有效。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;4、Gearman Worker 的无缝重启&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;我在实现Worker的过程中，采用了PHP脚本，脚本调用外部的配置文件。如果外部的配置文件修改后，需要重新启动脚本才能够使配置文件中修改的变量生效，所以想要坐到无缝的重启。即脚本Stop、Start的过程不会影响正在进行的业务。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;对于无缝重启的问题，我总结了如下几个思路进行处理，解决的方法：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、每次修改完代码后，Worker需要手工重启（先杀死然后启动）。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、在Worker中设置，单次任务循环完成后，就对Worker进行重启。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、在Worker中添加一个退出函数，如果需要Worker退出的时候，在Client端发送一个优先级比较高的退出调用。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;4、在Worker中检查文件是否发生变化，如果发生了变化，退出并重启自身。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;5、为Worker编写信号控制，接受重启指令，类似于 http restart graceful 指令&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;另外，也可以使用&amp;nbsp;supervisord 。这个工具暂时还没有了解，有兴趣的朋友可以分享一下。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;下面是我在部门内部分享时制作的PPT&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;div style="width:425px" id="__ss_10452050"&gt;&lt;strong style="display:block;margin:12px 0 4px"&gt;&lt;a href="http://www.slideshare.net/Wonwang/gearman-introduction-10452050" title="Gearman Introduction"&gt;Gearman Introduction&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse10452050" width="425" height="355"&gt;&#xD;
&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=20111115gearman-111204003123-phpapp02&amp;stripped_title=gearman-introduction-10452050&amp;userName=Wonwang" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;param name="wmode" value="transparent"/&gt;&lt;embed name="__sse10452050" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=20111115gearman-111204003123-phpapp02&amp;stripped_title=gearman-introduction-10452050&amp;userName=Wonwang" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&#xD;
&lt;div style="padding:5px 0 12px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/Wonwang"&gt;Wonwang&lt;/a&gt;.&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;参考资料：&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;1、&lt;a href="http://william.shallum.net/random-notes/usingmemcachetogetresultsfromagearmanbackgroundjob"&gt;Using memcache to get results from a gearman background job&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、&lt;a href="http://gearman.org/"&gt;Gearman&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、&lt;a href="http://groups.google.com/group/gearman/msg/5314505c52e92b74?dmode=source"&gt;PHP Worker Script Automatically Restart On Crash/Exit&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;4、&lt;a href="http://www.supervisord.org/"&gt;http://www.supervisord.org&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2275408.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/12/04/2275408.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/11/14/2249004.html</id><title type="text">如何使用GunPGP加密Apple Mail的邮件</title><summary type="text">我和火星人也很好奇如何能够更安全的传输邮件，所以决定试一试。他的环境是 Linux Ubuntu ，我的环境是 Mac OS X Lion。GnuPG全称GNU PrivacyGuard，它是基于公钥/私钥体系的加密工具PGP（Pretty Good Privacy）的开源版本它遵循OpenPGP标准。你可以免费使用，自由传播，并可以获得它的源代码。可以用于对Email、文件及其他数据的加密与验证，确保通信数据的保密性、完整性和真实性。PGP原理及规则PGP使用双密匙来加密数据。每个使用PGP加密技术的人都要创建一对密匙，一个叫做公匙，另一个叫做私匙。公匙可被广泛传播，你可以贴在自己的网页上或</summary><published>2011-11-14T14:37:00Z</published><updated>2011-11-14T14:37:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/11/14/2249004.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/11/14/2249004.html"/><content type="html">&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&#xD;
&lt;!--?xml version="1.0" encoding="UTF-8" standalone="no"?--&gt;&#xD;
&lt;span style="font-family: Arial; line-height: normal; font-size: medium; "&gt;我和火星人也很好奇如何能够更安全的传输邮件，所以决定试一试。他的环境是 Linux Ubuntu ，我的环境是 Mac OS X Lion。&lt;/span&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;GnuPG全称GNU PrivacyGuard，它是基于公钥/私钥体系的加密工具PGP（Pretty Good Privacy）的开源版本它遵循OpenPGP标准。你可以免费使用，自由传播，并可以获得它的源代码。可以用于对Email、文件及其他数据的加密与验证，确保通信数据的保密性、完整性和真实性。&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;span style="font-size: 18px; "&gt;&lt;strong&gt;PGP原理及规则&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;&lt;br /&gt;&#xD;
&lt;div&gt;PGP使用双密匙来加密数据。每个使用PGP加密技术的人都要创建一对密匙，一个叫做公匙，另一个叫做私匙。公匙可被广泛传播，你可以贴在自己的网页上或发到专门的公钥管理网站上等等。私匙属于个人信息，绝不应该泄漏给其他人。&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;公匙和私匙相互作用对数据进行加密及解密。被公匙加密的数据只能被私匙解密，被私匙加密的数据也只能被一个公匙解密。这样就可以实现双重认证。&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;例如，A要给B发信息：&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;* A不想信息被其他人看见，怎么办？&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;首先A必须通过某些途径得到B的公钥。&lt;/div&gt;&#xD;
&lt;div&gt;在发送信息前，使用B的公匙对信息进行加密。&lt;/div&gt;&#xD;
&lt;div&gt;这样只有B用对应的私匙才能解密收到的信息。所以就保证了信息传输的安全，这就是PGP所谓的加密(encryption)与解密(decryption)。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;* B收到信息后如何确定这信息是A发的呢？&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;首先A必须通过某种途径把自己的公钥发给B。&lt;/div&gt;&#xD;
&lt;div&gt;在发送信息前，A先用自己的密钥加密信息。&lt;/div&gt;&#xD;
&lt;div&gt;B收到信息后就可以使用A的公钥来对收到的信息进行验证。这样就能确定信息来自A，这就是PGP所谓的签名(signature)与验证(verification)。&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="font-size: 18px; "&gt;&lt;strong&gt;如何在Lion中使用PGP加密你的邮件&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;当前，gpgtools.org 上已经提供了集成的工具包来进行GPG的加密等相关工作。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;1、下载 GPGTools，并进行安装。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;首先从&amp;nbsp;&lt;a href="http://www.gpgtools.org/"&gt;http://www.gpgtools.org/&lt;/a&gt;&amp;nbsp;下载 gpgtools，下载后进行安装。工具包中包括了如下软件：&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;GPGMail、GPG Keychain Access、MacGPG1、MacGPG2、GPGService、GPGPreference、Mobile OpenGPG。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;安装之后，你就可以在 terminal 中看到 gpg 命令已经被安装好了。&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;2、打开 GPG Keychain Access 生成自己的公钥和密钥对。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111115-macgpg/55555.png" border="0" alt="" width="1021" height="641" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;正常情况下，第一次打开的时候，列表中应该是个空白的界面，紧接着会提醒用户生成自己的密钥对。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p2888/3238ff599993c574d5467df292dfc302.png" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111115-macgpg/44444.png" border="0" alt="" width="456" height="349" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;创建密钥对，默认会用你的电脑帐号对应的邮箱，你也可以选择或者输入其他的邮箱。Full name部分注意用户名要大于五个字符，所以中文姓名会有提示。Length 一般选择2048,也可以选择4096这样安全性能够更高一些。完成后，点击 Generate Key，生成自己的密钥对。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;3、将自己的公钥导出并发送给其他人。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;选中自己的密钥对，点击右键，选择导出。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p2888/5f5fa6c82beb577bc9804f14ff7dd3e0.png" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111115-macgpg/33333.png" border="0" alt="" width="419" height="343" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p2888/160200b2b49b1cccca3995828cd9aa35.png" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111115-macgpg/22222.png" border="0" alt="" width="600" height="486" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;导出的格式选项中，选择 binary 的格式。笔者试验了 ASCII 格式好像不能够正确导出。将导出的公钥发送给其他人，同时将别人的公钥 Import 到 GPG keychain Access 中。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;4、最后，就可以在Mail中使用GPG进行邮件加密和签名。&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="http://images.cnblogs.com/cnblogs_com/cocowool/20111115-macgpg/11111.png" border="0" alt="" width="564" height="286" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="file:///Users/shiqiang/Library/Application%20Support/Evernote/data/101370/content/p2888/1c874d7fdd11a9138e543c9d1fd03917.png" alt="" /&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;大功告成！&lt;/div&gt;&#xD;
&lt;div&gt;&lt;br /&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;参考资料：&lt;/div&gt;&#xD;
&lt;div&gt;1、&lt;a href="http://gpgtools.org/"&gt;GpGTools&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;2、&lt;a href="https://github.com/GPGTools/GPGMail/wiki/Not-working-anymore-after-an-OS-update"&gt;GpGMail Not working after an os update&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;3、密码学简介&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;4、&lt;a href="http://lagignition.blog.163.com/blog/static/1287300232009101082517154/"&gt;GPG签名和加密&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;5、&lt;a href="http://blog.sina.com.cn/s/blog_5595d514010008xe.html"&gt;Apple Mail PGP&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div style="font-family: Arial; line-height: normal; font-size: medium; "&gt;6、&lt;a href="http://www.wasuvi.com/?page_id=2368"&gt;Using GNUPG encryption with Mac OS X Mail&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;style type="text/css" isprelink="true"&gt;@import url(http://www.cnblogs.com/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);&lt;/style&gt;&lt;style type="text/css"&gt;@import url(/css/cuteeditor.css);&lt;/style&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2249004.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/11/14/2249004.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/cocowool/archive/2011/11/10/2245108.html</id><title type="text">PHP文件上传中的安全问题</title><summary type="text">在使用PHP进行开发时，经常遇到文件上传的场景。其中会隐藏很多我们平时注意不到的安全问题，我总结了一下，主要有几个方面：1、检查用户传来的文件名，避免 ../etc/passwd 这样的探测2、有些应用使用了用户名做为路径名，那么也需要对用户名进行详细的检查3、有些人提到了文件上传的Dos攻击，这个我觉得主要是依靠网络层面去解决，禁掉频繁访问的IP，但是对于僵尸网络的攻击，貌似没什么好的办法下面这篇文章中介绍的内容有些老，因为现在已经不是PHP3和PHP4的那个时代，虽然如此，关于文件上传中的安全处理，我们还是需要多加注意。正常的表单没有提供文件上传的功能，所以在 RFC 1867 中提出了《</summary><published>2011-11-10T15:31:00Z</published><updated>2011-11-10T15:31:00Z</updated><author><name>Cocowool</name><uri>http://www.cnblogs.com/cocowool/</uri></author><link rel="alternate" href="http://www.cnblogs.com/cocowool/archive/2011/11/10/2245108.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/cocowool/archive/2011/11/10/2245108.html"/><content type="html">在使用PHP进行开发时，经常遇到文件上传的场景。其中会隐藏很多我们平时注意不到的安全问题，我总结了一下，主要有几个方面：&lt;br /&gt;&lt;br /&gt;1、检查用户传来的文件名，避免 ../etc/passwd 这样的探测&lt;br /&gt;2、有些应用使用了用户名做为路径名，那么也需要对用户名进行详细的检查&lt;br /&gt;3、有些人提到了文件上传的Dos攻击，这个我觉得主要是依靠网络层面去解决，禁掉频繁访问的IP，但是对于僵尸网络的攻击，貌似没什么好的办法&lt;br /&gt;&lt;br /&gt;下面这篇文章中介绍的内容有些老，因为现在已经不是PHP3和PHP4的那个时代，虽然如此，关于文件上传中的安全处理，我们还是需要多加注意。&lt;br /&gt;&lt;br /&gt;正常的表单没有提供文件上传的功能，所以在 RFC 1867 中提出了《HTML中基于表单的文件上传》这个规范。看下面的列子：&lt;br /&gt;&lt;br /&gt;&amp;lt;FORM METHOD="POST" ENCTYPE="multipart/form-data"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;INPUT TYPE="FILE" NAME="hello"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="10240"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;INPUT TYPE="SUBMIT"&amp;gt;&lt;br /&gt;&amp;lt;/FORM&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;上面的代码让用户从本地机器选择一个文件，当点击提交后，文件就会被上载到服务器。这显然是很有用的功能，但是PHP的响应方式使这项功能变的不安全。当PHP第一次接到这种请求，甚至在它开始解析被调用的PHP代码之前，它会先接受远程用户的文件，检查文件的长度是否超过 &amp;#8220;$MAX_FILE_SIZE&amp;#8221; 变量定义的值，如果通过这些测试的话，文件就会被存在本地的一个临时目录中。因此，攻击者可以发送任意文件给运行PHP的主机，在PHP程序还没有决定是否接受文件上载时，文件已经被存在服务器上了。这里我就不讨论利用文件上载来对服务器进行DOS攻击的可能性了。&lt;br /&gt;&lt;br /&gt;让我们考虑一下处理文件上载的PHP程序，正如我们上面说的，文件被接收并且存在服务器上（位置是在配置文件中指定的，一般是/tmp），扩展名一般是随机的，类似&amp;#8220;phpxXuoXG&amp;#8221;的形式。PHP程序需要上载文件的信息以便处理它，这可以通过两种方式，一种方式是在PHP 3中已经使用的，另一种是在我们对以前的方法提出安全公告后引入的。&lt;br /&gt;&lt;br /&gt;但是，我们可以肯定的说，问题还是存在的，大多数PHP程序还是使用老的方式来处理上载文件。&lt;br /&gt;PHP设置了四个全局变量来描述上载文件，比如说上面的例子：&lt;br /&gt;&lt;br /&gt;$hello = Filename on local machine (e.g "/tmp/phpxXuoXG")&lt;br /&gt;$hello_size = Size in bytes of file (e.g 1024)&lt;br /&gt;$hello_name = The original name of the file on the remote system (e.g "c:\\temp\\hello.txt")&lt;br /&gt;$hello_type = Mime type of uploaded file (e.g "text/plain")&lt;br /&gt;&lt;br /&gt;然后PHP程序开始处理根据&amp;#8220;$hello&amp;#8221;指定的文件，问题在于&amp;#8220;$hello&amp;#8221;不一定是一个PHP设置的变量，任何远程用户都可以指定它。如果我们使用下面的方式： &lt;br /&gt;http://vulnhost/vuln.php?hello=/etc/passwd&amp;amp;hello_size=10240&amp;amp;hello_type=text/plain&amp;amp;hello_name=hello.txt&lt;br /&gt;就导致了下面的PHP全局变量（当然POST方式也可以（甚至是Cookie））：&lt;br /&gt;&lt;br /&gt;$hello = "/etc/passwd"&lt;br /&gt;$hello_size = 10240&lt;br /&gt;$hello_type = "text/plain"&lt;br /&gt;$hello_name = "hello.txt"&lt;br /&gt;&lt;br /&gt;上面的表单数据正好满足了PHP程序所期望的变量，但是这时PHP程序不再处理上载的文件，而是处理&amp;#8220;/etc/passwd&amp;#8221;（通常会导致内容暴露）。这种攻击可以用于暴露任何敏感文件的内容。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;PHP手册中提到&amp;#8220;PHP 遵从大多数服务器系统中关于文件和目录权限的安全机制。这就使管理员可以控制哪些文件在文件系统内是可读的。必须特别注意的是全局的可读文件，并确保每一个有权限的用户对这些文件的读取动作都是安全的。&amp;#8221; 我们知道，/etc/passwd 是全局可读的&amp;#8230;。&lt;br /&gt;&lt;br /&gt;参考资料：&lt;br /&gt;1、PHP中文件上传中的安全问题&lt;br /&gt;2、RFC1867 HTML中基于表单的文件上传&lt;br /&gt;3、PHP手册，文件系统安全&lt;br /&gt;4、PHP安全基础 表单及URL上传攻击&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.cnblogs.com/cocowool/aggbug/2245108.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/cocowool/archive/2011/11/10/2245108.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
