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

<channel>
	<title>SLJ.me - 申力军</title>
	<atom:link href="http://slj.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://slj.me</link>
	<description>申力军的博客</description>
	<lastBuildDate>Mon, 05 Dec 2011 05:35:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>解决 Linux 用户密码最多支持密码前 8 位的方法</title>
		<link>http://slj.me/2011/12/solve-linux-password-8-chars-limit/</link>
		<comments>http://slj.me/2011/12/solve-linux-password-8-chars-limit/#comments</comments>
		<pubDate>Mon, 05 Dec 2011 05:34:32 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Web Structure]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2283</guid>
		<description><![CDATA[今天登录服务器时意外发现，使用密码前8位就能够登录VPS， 通过一番查找，得知原因： DES算法加密的密码只支持最多8位，结果只要密码前8位对了就能进入系统。 解决方法是： 修改/etc/pam.d/system-auth文件，让系统把密码用MD5加密， 就可以支持不限长度的密码了。文件中的如下1行 password sufficient /lib/security/pam_unix.so nullok use_authtok shadow 把shadow 改为md5就可以了。 最后我担心密码存储发生变化而导致不能登录，我还执行了一次 passwd 把密码给重新写了一遍。呵呵，真是长见识了，如果不修改，这样默认的密码安全性太低了。。。 Other Posts / 其他文章漏嘴空想 之一Zen Coding资源更新PHP 5.3 后被禁止使用的函数我的电脑情缘（流水帐）Apache Rewrite 规则详解]]></description>
			<content:encoded><![CDATA[<p>今天登录服务器时意外发现，使用密码前8位就能够登录VPS，</p>
<h4>通过一番查找，得知原因：</h4>
<blockquote><p>DES算法加密的密码只支持最多8位，结果只要密码前8位对了就能进入系统。</p></blockquote>
<h4>解决方法是：</h4>
<blockquote><p>修改/etc/pam.d/system-auth文件，让系统把密码用MD5加密， 就可以支持不限长度的密码了。文件中的如下1行<br />
password    sufficient    /lib/security/pam_unix.so nullok use_authtok shadow<br />
把shadow 改为md5就可以了。</p></blockquote>
<p>最后我担心密码存储发生变化而导致不能登录，我还执行了一次 passwd 把密码给重新写了一遍。呵呵，真是长见识了，如果不修改，这样默认的密码安全性太低了。。。</p>
<h2  class="related_post_title">Other Posts / 其他文章</h2><ul class="related_post"><li><a href="http://slj.me/2009/05/book-beginingphpandmysql/" title="好书推荐-《PHP与MySQL程序设计（第3版）》">好书推荐-《PHP与MySQL程序设计（第3版）》</a></li><li><a href="http://slj.me/2009/09/utf8-bom-solution-on-webpage/" title="解决怪问题——UTF8 BOM导致的wrap居中失败与顶端空白的解决办法">解决怪问题——UTF8 BOM导致的wrap居中失败与顶端空白的解决办法</a></li><li><a href="http://slj.me/2011/10/mysql-save-query-result-to-a-file/" title="MySQL 把查询结果保存到文件中的方法">MySQL 把查询结果保存到文件中的方法</a></li><li><a href="http://slj.me/2009/12/20-more-beautiful-interactive-website-design-using-jquery/" title="20多个漂亮的使用jQuery交互的网站设计欣赏">20多个漂亮的使用jQuery交互的网站设计欣赏</a></li><li><a href="http://slj.me/2010/01/upgrade-instruction-for-meeplace-2-4/" title="Upgrade instruction for MeePlace 2.4">Upgrade instruction for MeePlace 2.4</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/12/solve-linux-password-8-chars-limit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL 把查询结果保存到文件中的方法</title>
		<link>http://slj.me/2011/10/mysql-save-query-result-to-a-file/</link>
		<comments>http://slj.me/2011/10/mysql-save-query-result-to-a-file/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 10:42:07 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2274</guid>
		<description><![CDATA[执行 mysql -h 主机 -u 用户 -p密码 -P端口 -D库 -Bse &#8220;select house_id,type from 表名 where account_id=123;&#8221;  &#62; /tmp/a.txt Related Posts / 相关文章分享两则我在VPS上执行的sh脚本总结: MySQL主从复制 &#8211; MySQL Replication找出 MySQL 里哪些查询 Query 速度较慢MySQL: group by &#8230; having &#8230;MySql取整函数]]></description>
			<content:encoded><![CDATA[<p>执行</p>
<p>mysql -h 主机 -u 用户 -p密码 -P端口 -D库 -Bse &#8220;select house_id,type from 表名 where account_id=123;&#8221;  &gt; /tmp/a.txt</p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/03/share-bash-script/" title="分享两则我在VPS上执行的sh脚本">分享两则我在VPS上执行的sh脚本</a></li><li><a href="http://slj.me/2011/03/mysql-replication-master-slave/" title="总结: MySQL主从复制 &#8211; MySQL Replication">总结: MySQL主从复制 &#8211; MySQL Replication</a></li><li><a href="http://slj.me/2010/12/find-out-slow-query-in-mysql/" title="找出 MySQL 里哪些查询 Query 速度较慢">找出 MySQL 里哪些查询 Query 速度较慢</a></li><li><a href="http://slj.me/2010/04/mysql-group-by-having/" title="MySQL: group by &#8230; having &#8230;">MySQL: group by &#8230; having &#8230;</a></li><li><a href="http://slj.me/2010/01/mysql%e5%8f%96%e6%95%b4%e5%87%bd%e6%95%b0/" title="MySql取整函数">MySql取整函数</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/10/mysql-save-query-result-to-a-file/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[转] MySQL用left join替换select in结构改善效率</title>
		<link>http://slj.me/2011/10/left-join-select-in/</link>
		<comments>http://slj.me/2011/10/left-join-select-in/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 11:41:33 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[join]]></category>
		<category><![CDATA[left join]]></category>
		<category><![CDATA[select in]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2264</guid>
		<description><![CDATA[今天为客户代维服务器,发现打开WEB速度奇慢,一开始以为是台湾地震,又影响到了海底光缆 客户问我是否要重启下服务器,我说 &#8220;不用,你的服务器负载不重,应该不是这个原因&#8221; 说完,随手top 了下,晕,还真是负载严重的厉害 LOAD AVG 竟然也达到了 15 16 18左右 于是登陆mysql,找原因 发现大量 copy to temp table 的信息,而语句就是 select `id_category` from `ps_category_product` where `id_product` in(select `id_product` from `ps_image` where `date_add`&#62;1 group by `id_product`) group by `id_category` &#160; 下面这个图片是我本机测试的 这条语句用时 0.1383 秒,一条近0.14秒啊&#8230;而我在客户服务器上看到的是 30几秒还有40多秒的&#8230;. 这里用了 select in 这个结构..平时用的很多,还真没发现原来效率这么低&#8230;.客户的服务器上有30多个站,每个站都在不停的使用这条语句进行查询,可想而知负载为什么这么高了 于是,改进,将 select in 结构,替换为 left join 结构 select p.`id_category` [...]]]></description>
			<content:encoded><![CDATA[<p>今天为客户代维服务器,发现打开WEB速度奇慢,一开始以为是台湾地震,又影响到了海底光缆</p>
<p>客户问我是否要重启下服务器,我说 &#8220;不用,你的服务器负载不重,应该不是这个原因&#8221;</p>
<p>说完,随手top 了下,晕,还真是负载严重的厉害</p>
<p><img src="http://slj.me/wp-content/uploads/2011/10/4a7a9004c068615d2de5c30d0da635b520100305143822.jpg" border="0" alt="" /></p>
<p>LOAD AVG 竟然也达到了 15 16 18左右</p>
<p>于是登陆mysql,找原因</p>
<p>发现大量 copy to temp table 的信息,而语句就是</p>
<p><span id="more-2264"></span></p>
<blockquote>
<pre><code><span class="keyword">select</span> <span class="string">`id_category`</span> <span class="keyword">from</span> <span class="string">`ps_category_product`</span>
<span class="keyword">where</span> <span class="string">`id_product`</span>
<span class="keyword">in</span>(<span class="keyword">select</span> <span class="string">`id_product`</span> <span class="keyword">from</span> <span class="string">`ps_image`</span> <span class="keyword">where</span> <span class="string">`date_add`</span>&gt;<span class="number">1</span> <span class="keyword">
group</span> <span class="keyword">by</span> <span class="string">`id_product`</span>)
<span class="keyword">group</span> <span class="keyword">by</span> <span class="string">`id_category`</span></code></pre>
<p>&nbsp;</p></blockquote>
<p>下面这个图片是我本机测试的</p>
<p><img src="http://slj.me/wp-content/uploads/2011/10/4a7a9004c068615d2de5c30d0da635b520100305145222.jpg" border="0" alt="" /></p>
<p>这条语句用时 0.1383 秒,一条近0.14秒啊&#8230;而我在客户服务器上看到的是 30几秒还有40多秒的&#8230;.</p>
<p>这里用了 select in 这个结构..平时用的很多,还真没发现原来效率这么低&#8230;.客户的服务器上有30多个站,每个站都在不停的使用这条语句进行查询,可想而知负载为什么这么高了</p>
<p>于是,改进,将 select in 结构,替换为 left join 结构</p>
<blockquote>
<pre><code><span class="keyword">select</span> p.<span class="string">`id_category`</span> <span class="keyword">from</span> <span class="string">`ps_category_product`</span> p <span class="keyword">
left</span> <span class="keyword">join</span> <span class="string">`ps_image`</span> i <span class="keyword">
on</span> p.<span class="string">`id_product`</span>=i.<span class="string">`id_product`</span>
<span class="keyword">where</span> i.<span class="string">`date_add`</span>&gt;<span class="number">1</span>
<span class="keyword">group</span> <span class="keyword">by</span> p.<span class="string">`id_categor</span></code><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">
</span></pre>
</blockquote>
<pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">替换到服务器,发现负载下降了</span></pre>
<p><img src="http://slj.me/wp-content/uploads/2011/10/thum-4a7a9004c068615d2de5c30d0da635b520100305145553-1.jpg" border="0" alt="" /></p>
<p>mysql 下降到 78.9%,比刚才小了很多,系统的load avg也下降到 2和3左右</p>
<p>下面这个图片是我本机测试这条语句的</p>
<p><img src="http://slj.me/wp-content/uploads/2011/10/4a7a9004c068615d2de5c30d0da635b520100305145856.jpg" border="0" alt="" /></p>
<p>用时 0.0398,仅仅是刚才的 28%,可见,效果非常明显</p>
<p>这里提醒大家,慎用 select in 结构的查询,另外,因为用了两次 group by 也对性能有一定影响</p>
<h2  class="related_post_title">Other Posts / 其他文章</h2><ul class="related_post"><li><a href="http://slj.me/2009/04/jquery-float-menu/" title="一个利用jQuery实现菜单跟随页面滚动而移动的代码">一个利用jQuery实现菜单跟随页面滚动而移动的代码</a></li><li><a href="http://slj.me/2010/04/new-blog-theme-is-coming-up/" title="实习在即，博客即将更新">实习在即，博客即将更新</a></li><li><a href="http://slj.me/2009/07/10%e4%b8%aa%e6%9c%a8%e7%ba%b9%e7%b4%a0%e6%9d%90/" title="10个木纹素材">10个木纹素材</a></li><li><a href="http://slj.me/2010/01/theme-upgrade-advice-for-meeplace-2-4/" title="Theme Upgrade Advice For MeePlace 2.4">Theme Upgrade Advice For MeePlace 2.4</a></li><li><a href="http://slj.me/2009/12/css-shadow/" title="CSS阴影详解">CSS阴影详解</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/10/left-join-select-in/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>疯狂的 Web 应用开源项目</title>
		<link>http://slj.me/2011/08/web-open-source-project/</link>
		<comments>http://slj.me/2011/08/web-open-source-project/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 02:58:10 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[开源]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2249</guid>
		<description><![CDATA[下面是一个Web应用的开源列表。没什么可说的，太疯狂了。尤其是Web 2.0那一堆。我不知道你怎么想，有些开源项目的源码写得挺不好的，尤其是性能方面。或许你会以为改一改他们就可以成为为自己所用，不过，改这些开源的项目还真不容易。玩玩还可以。 数字媒体 相册（Flickr, Picasa） Gallery，基于PHP + MySQL的Web相册。非常易于使用，包括一个配置向导，对于相片的操作包括自动生成缩略图、相片的大小改变、选择、排序等。 Piwigo，基于PHP + MySQL。配备了强大的功能，发布和管理您的照片，可扩展性和智能浏览功能，如类别，标签，或年表。这是网络和照片的标准要求。扩展使Piwigo更可扩展性和可定制的。 UberGallery，一个简单易用的相册。PHP。不需要数据库。 Zenphoto，一个简单的web相册程序,它能够简单的展示你的图片，并含有你所需要的所有功能和特点。可以和Wordpress集成。 视频（YouTube） Flowplayer，一个用Flash开发的在Web上的视频播放器，可以很容易将它集成在任何的网页上。支持HTTP以及流媒体传输。 Plumi，一个建立在Plone 内容管理系统上的视频分享系统，可帮助你轻松建立视频分享网站。 音乐电台社区（last.fm, ulike） Libre.fm，对Last.fm 的克隆。 视频电影社区（netflix, criticker） Filmaster，fileaster.com的源码。 书（LibraryThing, Shelfari, Goodreads） O’Reilly Bookworm，在线电子图书阅读。 期刊参考论文数据库（Emerald Insight, Springer Link） CiteSeerX，采用机器自动识别技术搜集网上以Postscrip和PDF文件格式存在的学术论文，然后依照引文索引方法标引和链接每一篇文章。（其是CiteSeer的换代产品。1997年，CiteSeer引文搜索引擎由NEC公司在美国普林斯顿研究所的三位研究人员Steve Lawrence, Lee Giles和Kurt Bollacker研制开发。它是利用自动引文标引系统ACI（Autonomous Citation Indexing）建立的第一个科学文献数字图书馆（Scientific Literature Digital Library））。 地图（Google Maps） OpenStreetMap，一个可供自由编辑的世界地图，它是由所有的用户创造的。OpenStreetMap允许您查看，编辑或者使用世界各地的地理数据来帮助您。其就像Wikipedia一样，全世界的人都可以编辑，据说其上面的数据超过了政府的数据。当然，目前其参与的人数还不够，大量的地方都是白板。 文件存储 文件共享/同步（DropBox, drop.io, Ubuntu One） Tahoe Least-Authority Filesystem，一个云存储分布式文件系统。 iFolder，一个简单安全的存储解决方案，可在计算机间文件的同步和分享。可以用来随时备份本地的文件。 [...]]]></description>
			<content:encoded><![CDATA[<p>下面是一个Web应用的开源列表。没什么可说的，太疯狂了。尤其是Web 2.0那一堆。我不知道你怎么想，有些开源项目的源码写得挺不好的，尤其是性能方面。或许你会以为改一改他们就可以成为为自己所用，不过，改这些开源的项目还真不容易。玩玩还可以。</p>
<h3><strong>数字媒体</strong></h3>
<p><strong>相册</strong>（Flickr, Picasa）</p>
<ul>
<li><span><a rel="external nofollow" href="http://gallery.menalto.com/">Gallery</a></span>，基于PHP + MySQL的Web相册。非常易于使用，包括一个配置向导，对于相片的操作包括自动生成缩略图、相片的大小改变、选择、排序等。</li>
<li><span><a rel="external nofollow" href="http://piwigo.org/">Piwigo</a></span>，基于PHP + MySQL。配备了强大的功能，发布和管理您的照片，可扩展性和智能浏览功能，如类别，标签，或年表。这是网络和照片的标准要求。扩展使Piwigo更可扩展性和可定制的。</li>
<li><span><a rel="external nofollow" href="http://www.ubergallery.net/">UberGallery</a></span>，一个简单易用的相册。PHP。不需要数据库。</li>
<li><span><a rel="external nofollow" href="http://www.zenphoto.org/">Zenphoto</a></span>，一个简单的web相册程序,它能够简单的展示你的图片，并含有你所需要的所有功能和特点。可以和Wordpress集成。</li>
</ul>
<p><strong>视频</strong>（YouTube）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.flowplayer.org/">Flowplayer</a></span>，一个用Flash开发的在Web上的视频播放器，可以很容易将它集成在任何的网页上。支持HTTP以及流媒体传输。</li>
<li><span><a rel="external nofollow" href="http://blog.plumi.org/">Plumi</a></span>，一个建立在Plone 内容管理系统上的视频分享系统，可帮助你轻松建立视频分享网站。</li>
</ul>
<p><span id="more-2249"></span></p>
<p><strong>音乐电台社区</strong>（last.fm, ulike）</p>
<ul>
<li><span><a rel="external nofollow" href="http://libre.fm/">Libre.fm</a></span>，对Last.fm 的克隆。</li>
</ul>
<p><strong>视频电影社区</strong>（netflix, criticker）</p>
<ul>
<li><span><a rel="external nofollow" href="http://filmaster.com/">Filmaster</a></span>，fileaster.com的源码。</li>
</ul>
<p><strong>书</strong>（LibraryThing, Shelfari, Goodreads）</p>
<ul>
<li><span><a rel="external nofollow" href="http://bookworm.oreilly.com/">O’Reilly Bookworm</a></span>，在线电子图书阅读。</li>
</ul>
<p><strong>期刊参考论文数据库</strong>（Emerald Insight, Springer Link）</p>
<ul>
<li><span><a rel="external nofollow" href="http://citeseerx.ist.psu.edu/">CiteSeerX</a></span>，采用机器自动识别技术搜集网上以Postscrip和PDF文件格式存在的学术论文，然后依照引文索引方法标引和链接每一篇文章。（其是CiteSeer的换代产品。1997年，CiteSeer引文搜索引擎由NEC公司在美国普林斯顿研究所的三位研究人员Steve Lawrence, Lee Giles和Kurt Bollacker研制开发。它是利用自动引文标引系统ACI（Autonomous Citation Indexing）建立的第一个科学文献数字图书馆（Scientific Literature Digital Library））。</li>
</ul>
<p><strong>地图</strong>（Google Maps）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.openstreetmap.org/">OpenStreetMap</a></span>，一个可供自由编辑的世界地图，它是由所有的用户创造的。OpenStreetMap允许您查看，编辑或者使用世界各地的地理数据来帮助您。其就像Wikipedia一样，全世界的人都可以编辑，据说其上面的数据超过了政府的数据。当然，目前其参与的人数还不够，大量的地方都是白板。</li>
</ul>
<h3><strong>文件存储</strong></h3>
<p><strong>文件共享/同步</strong>（DropBox, drop.io, Ubuntu One）</p>
<ul>
<li><span><a rel="external nofollow" href="http://tahoe-lafs.org/trac/tahoe-lafs/">Tahoe Least-Authority Filesystem</a></span>，一个云存储分布式文件系统。</li>
<li><span><a rel="external nofollow" href="http://www.kablink.org/ifolder/">iFolder</a></span>，一个简单安全的存储解决方案，可在计算机间文件的同步和分享。可以用来随时备份本地的文件。</li>
</ul>
<p><strong>存储</strong>（Amazon S3, Imageshack, Box, Variety of models）</p>
<ul>
<li><span><a rel="external nofollow" href="http://search.cpan.org/~jesse/Prophet-0.72/">Jesse Vincent’s Prophet</a></span>，你可以看看他的<span><a rel="external nofollow" href="http://search.cpan.org/~jesse/Prophet-0.72/lib/Prophet/Manual.pod">文档介绍</a></span>吧。</li>
</ul>
<p><strong>在线文件编辑</strong>（Google Docs）</p>
<ul>
<li><span><a rel="external nofollow" href="https://abicollab.net/">AbiCollab</a></span>，基于AbiWord的社群的线上文书处理协作服务。</li>
<li><span><a rel="external nofollow" href="http://etherpad.org/">Etherpad</a></span>，基于开放软体的线上文书处理服务，最大的特色在于多人即时共同协作一份文件，软体组织不直接提供服务，而是透过其他没有连系的组织网站提供。</li>
</ul>
<p><strong>虚拟机供应</strong>（Amazon EC2）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.open.eucalyptus.com/">Eucalyptus (computing)</a></span>，是一用来通过计算集群或工作站群实现弹性的、实用的云计算。它最初是美国加利福尼亚大学 Santa Barbara 计算机科学学院的一个研究项目，现在已经商业化，发展成为了 Eucalyptus Systems Inc。不过，Eucalyptus 仍然按开源项目那样维护和开发。Eucalyptus Systems 还在基于开源的 Eucalyptus 构建额外的产品；它还提供支持服务。</li>
<li><span><a rel="external nofollow" href="http://www.globus.org/">Globus Toolkit</a></span>，Globus项目工具包，其可以在计算机上提供稳定、安全和对等网络的分布式运算，集群和其它高性能系统功能。</li>
<li><span><a rel="external nofollow" href="http://www.opennebula.org/">OpenNebula</a></span>，一个虚拟基础设备引擎， 用来动态布署虚拟机器在一群实体资源上，OpenNEbula 最大的特色在于将虚拟平台从单一实体机器到一群实体资源。</li>
</ul>
<h3><strong>内容服务</strong></h3>
<p><strong>Wiki</strong>（Wikispaces）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.dokuwiki.org/dokuwiki/">Dokuwiki</a></span>，一个针对小公司文件需求而开发的Wiki引擎。DokuWiki是用程序设计语言PHP开发的并以GPL 2发布。DokuWiki基于文本存储，所以不需要数据库，其数据文件在Wiki系统外也是可读的。DokuWiki的功能齐全，支持UTF-8，最新版支持中文链接。能够单独编辑页面中的某个章节，能够自动生成目录，适合中小企业、个人使用，用作资料归档、指南、读书笔记等。DokuWiki安装很简单，默认提供配置工具。</li>
<li><span><a rel="external nofollow" href="http://www.mediawiki.org/wiki/MediaWiki/">Mediawiki</a></span>，是一套基于网络的Wiki引擎，维基媒体基金会的所有项目乃至众多wiki网站皆采用了这一软件。MediaWiki软件最初是为自由内容百科全书维基百科所开发，今日已被一些公司机构部署为内部的知识管理和内容管理系统。Novell甚而还在多个高流量的网站中使用了该软件。</li>
<li><span><a rel="external nofollow" href="https://github.com/rongarret/microWiki/">μWiki</a></span>，一个小巧而功能齐全的wiki，所有的代码才3500行，可通过facebook和openID认证。</li>
</ul>
<p><strong>出版</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://www.topazproject.org/trac/">Topaz</a></span></li>
<li><span><a rel="external nofollow" href="http://www.ambraproject.org/">Ambra</a></span>，是一个期刊管理与发布系统。它具有一个高容量、高效、经济的系统来在所有科学领域发表研究文章。</li>
<li><span><a rel="external nofollow" href="http://pkp.sfu.ca/?q=ojs/">Open Journal Systems</a></span>，简称OJS，此系统是一个开源码的期刊管理与出版软件，由公共知识项目(PKP; Public Knowledge Project)研发与支持。（<span><a rel="external nofollow" href="http://www.chinajol.info/">中国肺癌杂志</a></span>使用了这个系统）</li>
</ul>
<p><strong>Blog</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://wordpress.org/">WordPress</a></span>，这个不用说了吧。</li>
<li><span><a rel="external nofollow" href="http://www.livejournal.com/">LiveJournal</a></span>，一个综合型SNS交友网站，有论坛，博客等功能，Brad Fitzpatrick始建于1999年4月15日，目的是为了与同学保持联系，之后发展为大型网络社区平台，是网友聚集的好地方，LJ支持多国语言，ALEXA综合排名84 ，日均访客可达6,288,000以上</li>
</ul>
<p><strong>微博</strong> （Twitter）</p>
<ul>
<li><span><a rel="external nofollow" href="http://jisko.org/">Jisko</a></span>，界面和Twitter很像，集成Twitter同步功能，它能够自动将你在Jisko平台上发布的内容发表到您的Twitter账户上。也能够自动读取您的Twitter更新，但是并不能将这些内容发布到Jisko平台，只能在自己的好友Timeline里查看。Jisko平台还能够连接您的Jabber/GTalk账户，让您通过IM发帖。并且有数个缩链服务供选择，十分实用。</li>
<li><span><a rel="external nofollow" href="http://www.jaiku.com/">Jaiku Engine</a></span>，Google曾经收购的类Twitter平台Jaiku现在已经完全开源并且切换AppEngine上运行，早前Google曾经宣布停止Jaiku等项目的维护和开发，现在更将Jaiku完全开源提供用户免费下载，所有人都可以在自己的主机上建立和运行自己的Jaiku应用了。</li>
<li><span><a rel="external nofollow" href="http://status.net/">Status.net</a></span>，一个开源微博服务。同时，它又可将信息同步到Twitter。所以我们也可以把它理解为“开源的Twitter客户端”。但它与客户端又有本质的不同：拥有自己的数据库，只是把数据同步到推特而已。</li>
</ul>
<p><strong>网页访问量统计</strong>（Google Analytics）</p>
<ul>
<li><span><a rel="external nofollow" href="http://en.wikipedia.org/wiki/Piwik">Piwik</a></span>，一套基于Php+MySQL技术构建，能够与Google Analytics相媲美的开源网站访问统计系统，前身是phpMyVisites。Piwik可以给你详细的统计信息，比如网页浏览人数, 访问最多的页面, 搜索引擎关键词等等，并且采用了大量的AJAX/Flash技术，使得在操作上更加便易。此外，它还采用了插件扩展及开放API架构，可以让开发人员根据自已的实际需求创建更多的功能．</li>
<li><span><a rel="external nofollow" href="http://www.openwebanalytics.com/">Open Web Analytics</a></span>，一个开源的网站流量统计系统。基于PHP/Open Flash Chart/Ajax技术开发，既可以单独使用也可以与WordPress、Gallery&amp;MediaWiki集成使用。支持多个网站，集成Google Maps，RSS/Atom订阅跟踪等功能。</li>
</ul>
<p><strong>虚拟主机平台</strong>（Google AppEngine）</p>
<ul>
<li><span><a rel="external nofollow" href="http://code.google.com/p/appscale/">AppScale</a></span>，是一个平台，允许用户发布和托管自己的 Google App Engine 的应用程序。支持 Python, Java, and Go Google App Engine 平台。</li>
</ul>
<p><strong>办公</strong>（Google Docs）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.zimbra.com/products/zimbra-open-source.html">Zimbra Collaboration Suite</a></span>，其英文缩写为ZCA。全功能的通信及协作办公应用程序，提供可靠和高效能的邮件、地址簿、效率手册、任务列表以及网络文档制作功能。</li>
<li><span><a rel="external nofollow" href="http://www.phpgroupware.org/">PHPGroupware</a></span>，功能强大，基于Web的Messaging ，Collaboration和企业管理平台。phpGroupWare包含50多个模块可根据你的需求进行搭配与组合。它提供了约50种基于网络的应用，有日历，通讯录，先进的项目经理，待办事项列表，笔记，电子邮件，新闻组和新闻阅读器，一个文件管理器和更多应用。</li>
<li><span><a rel="external nofollow" href="http://fengoffice.com/web/index.php/">OpenGoo,Fengoffice</a></span>，基于ExtJs+XAMP（Apache、PHP、MySQL）开发的开源web office。它具备了主流在线协作系统所应具备的所有功能，包括任务管理、日程管理、文件管理、联系人管理以及email收发功能。其文件管理模块，实现了文件版本管理的功能，能够方便的查找、下载同一文件的不同版本。适用于任何单位或个人创建，共享，协作维护和发布它们所有内部与外部文档。</li>
<li><span><a rel="external nofollow" href="http://crabgrass.riseuplabs.org/">Crabgrass</a></span>，社会网络，小组协作，网络组织的Web应用程序。它由一组协作工具固体套件，如私人维基，任务列表，文件库，和决策工具。程序目前正在做了大量的用户界面改革，更完善的社会网络工具，博客和活动日程，以及更好的协作和决策制定各独立团体的支持。</li>
<li><span><a rel="external nofollow" href="http://etherpad.org/">Etherpad</a></span>，由两位Google 前员工所开发，已被Google 收购成为开放原始码项目。主要功能是让多个使用者透过网路来共同编辑一份文件，与先前介绍过的Sync.in 好用的线上即时文件协作平台类似。EtherPad 无须注册就能使用，建立文件后会产生一个网址，其它用户可以透过该网址与你编辑同一份文件，并标记出不同用户所编辑的位置，也有提供汇入汇出及时间轴等功能。</li>
</ul>
<h3><strong>Groupware群件</strong></h3>
<p><strong>Webmail</strong> (gmail, hotmail)</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.zimbra.com/">Zimbra</a></span>，强大的开源协同办公套件包括WebMail，日历，通信录，Web文档管理和创作。它最大的特色在于其采用Ajax技术模仿CS桌面应用软件的风格开发的客户端兼容Firefox,Safari和IE浏览器。</li>
<li><span><a rel="external nofollow" href="http://roundcube.net/">Roundcube</a></span>，支持多国语言的IMAP客户端，操作界面看起像一个桌面应用程序。它提供一个e-mail客户端应该具备的所有功能包括MIME支持,地址薄，文件夹操作，信息搜索和拼写检查。RoundCube Webmail采用PHP+Ajax开发并且需要MySQL数据库来存储数据。 用户界面采用XHTML+CSS2设计。</li>
<li><span><a rel="external nofollow" href="http://www.conjoon.org/">conjoon</a></span>，基于Ext JS+PHP/MySQL开发的Webmail和RSS客户端阅读器。此外还包含一个联系人管理模块。</li>
<li><span><a rel="external nofollow" href="http://www.tdah.us/">Tdah</a></span>，一个PHP Webmail系统。该系统采用POP3协议收邮件，可以配置使用SMTP、PHP mail、Sendmail或Qmail来发送邮件。T-dah还包含以下几个模块：事件日历、群组聊天、文件夹管理、邮件搜索等。T-dah使用 TinyMCE WYSIWYG编辑器来创建新邮件。</li>
<li><span><a rel="external nofollow" href="https://funambol.com/">Funambol</a></span>，世界领先的开源云同步和PUSHMAIL工具，支持诸多手提移动设备，包括苹果、黑莓、Android、Windows Mobile、索爱、三星、诺基亚等20余款。</li>
<li><span><a rel="external nofollow" href="http://www.hastymail.org/">Hastymail</a></span>，一个使用方便快捷、安全，跨平台的IMAP/SMTP客户端。采用PHP语言编写，运行于PHP+MYSQL平台环境。提供一个简洁的Web界面来发送和读取E-mail。</li>
<li><span><a rel="external nofollow" href="http://www.xuheki.com/">Xuheki</a></span>，一个很快的IMAP 使用AJAX 技术开发的客户端。你能想到的功能它基本上都有了。</li>
<li><span><a rel="external nofollow" href="http://www.claros.org/">Claros</a></span>，一个比较简单的，采用pop3/smtp收发邮件的webMail系统。不需要数据库的支持。提供一个独立于SMTP服务器的垃圾邮件过滤机制。</li>
</ul>
<p><strong>Email 服务器</strong>（MS Exchange）</p>
<ul>
<li><span><a rel="external nofollow" href="http://archiveopteryx.org/">Archiveopteryx</a></span>，一个互联网归档邮件服务器，支持强大的归档功能。可以运行在Linux, FreeBSD, NetBSD, OpenBSD 和 Mac OS X。</li>
<li><span><a rel="external nofollow" href="http://roundcube.net/">Roundcube</a></span>，提供一个e-mail客户端应该具备的所有功能包括MIME支持,地址薄，文件夹操作，信息搜索和拼写检查。RoundCube Webmail采用PHP+Ajax开发并且需要MySQL数据库来存储数据。 用户界面采用XHTML+CSS2设计。</li>
<li><span><a rel="external nofollow" href="http://www.squirrelmail.org/">Squirrelmail</a></span>，一款由PHP语言编写，基于标准的webmail软件包。它包括内建的纯PHP支持的IMAP和SMTP协议，所生成的页面绝对支持HTML4.0标准(无需JavaScript支持)，这样可以运行在更多的平台和更多的浏览器上。它的系统安装要求非常低，但是非常容易安装和配置。SquirrelMail拥有你的客户端邮件程序所拥有的一切，比如增强型的MIME支持、地址薄、文件夹操作等等功能。</li>
<li><span><a rel="external nofollow" href="http://www.horde.org/">Horde Groupware Suite</a></span>，一个强大的邮件办公套件。</li>
</ul>
<p><strong>邮件列表</strong> （Google Groups, Yahoo Groups）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.freelists.org/">Freelists</a></span></li>
<li><span><a rel="external nofollow" href="http://www.gnu.org/software/mailman/index.html">Mailman</a></span>，管理电子信箱讨论和自由软件电子通讯清单。 支持内置的归档，自动退回处理，内容过滤，消化交货，垃圾邮件过滤器等。</li>
</ul>
<p><strong>论坛</strong> （vBulletin）（注：国内的主要是用Discuz!）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.phpbb.com/">phpBB</a></span>，中文的在这里<span><a rel="external nofollow" href="http://www.phpbbchina.com/">http://www.phpbbchina.com</a></span></li>
<li><span><a rel="external nofollow" href="http://www.phorum.org/">Phorum</a></span>，基于PHP+MySQL开发的开源论坛项目。它的特点是速度快，功能强大，面向模块化设计，安装简单。此外Phorum还集成电子报。</li>
<li><span><a rel="external nofollow" href="http://www.vanillaforums.org/">Vanilla</a></span>，是很多外国牛人都在用的一款开源论坛程序，它不像我们熟知的phpBB之类的或是类似我国discuz，phpwind的模式，而是采取了全新的内核和界面，界面类似于stackflow，所以用它来做一个社交性的问答网站也是个不错的选择。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/ospo/">Ospo</a></span>，是一项开源社交门户站点方案。它拥有标准功能（添加、删除好友，前十排行榜），论坛整合、音乐模块（带有艺术家目录的专辑和歌曲）、广播心情整合、日志（添加、删除、修改、检查）等等众多功能。</li>
</ul>
<p><strong>日历</strong>（cf, 30boxes, Google calendars, ScheduleWorld）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.zimbra.com/products/zimbra-open-source.html">Zimbra Collaboration Suite</a></span>，功能的通信及协作办公应用程序，提供可靠和高效能的邮件、地址簿、效率手册、任务列表以及网络文档制作功能。</li>
<li><span><a rel="external nofollow" href="http://www.k5n.us/webcalendar.php/">Web Calendar</a></span>，一款漂亮的Flash日历，可以添加在网页上，它可以高亮显示事件，会议，节假日的日期。</li>
<li><span><a rel="external nofollow" href="https://www.forge.funambol.org/DomainHome.html">Funambol</a></span>，世界领先的开源云同步和PUSHMAIL工具，支持诸多手提移动设备，包括苹果、黑莓、Android、Windows Mobile、索爱、三星、诺基亚等20余款。</li>
<li><span><a rel="external nofollow" href="https://dev.joyent.com/projects/connector/wiki/Connector/">Joyent Connector</a></span>，免费提供Office 2.0的功能，如团队电子邮件、日程安排、相互联系、文档和书签。</li>
<li><span><a rel="external nofollow" href="http://www.horde.org/apps/kronolith/">Horde Groupware Suite</a></span>，协同办公套件。</li>
</ul>
<p><strong>会议和评审管理</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://www.openconf.com/">Openconf</a></span>，开源的会议管理系统，主要提供以下功能：电子提交、评审、论文答辩，以及会议主席对整个过程的管理等。</li>
<li><span><a rel="external nofollow" href="http://myreview.lri.fr/">MyReview</a></span>，学术会议的论文提交和论文评审。</li>
<li><span><a rel="external nofollow" href="http://www.easychair.org/">EasyChair</a></span>，会议管理系统。</li>
<li><span><a rel="external nofollow" href="http://borbala.com/cyberchair/">CyberChair</a></span>，论文提交和评审系统。</li>
<li><span><a rel="external nofollow" href="http://lasecwww.epfl.ch/iChair/">iChair</a></span>，会议系统，支持论文提交，评审，讨论等。</li>
<li><span><a rel="external nofollow" href="http://indico-software.org/">Indico</a></span>，会议计划，组织，支持从简单到复杂的会议。</li>
<li><span><a rel="external nofollow" href="http://www.oschina.net/p/icecore">ICEcore</a></span>，开放团队合作软件使用社交联网统一团队工作空间、实时网络会议、项目管理、实践团体以及远程操作。</li>
</ul>
<p><strong>反馈</strong>（Pollmonkey, Google Forms）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.limesurvey.org/">Limesurvey</a></span>，前身为PHPSurveyor）是一款在线问卷调查程序，它用PHP语言编写并可以使用MySQL，PostgreSQL或者MSSQL等多种数据库，它集成了调查程序开发、调查问卷的发布以及数据收集等功能，使用它，用户不必了解这些功能的编程细节。</li>
</ul>
<p><strong>其它</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://www.barnraiser.org/aroundme/">AROUNDMe</a></span>，可以创建像Ning, Myspace, Yahoo or Google groups一样的合作网站。每个群组可以创建多个网页，网页上包括留言簿、博客、论坛、维基百科等功能。每个群组还可以通过xHTML, CSS, JavaScript and PHP来进行自定义。</li>
<li><span><a rel="external nofollow" href="http://interactome.org/">InteractOLE</a></span>，是一款网络学习的递交和支持平台。与其他在线学习平台不同，InteractOLE致力于教学与学习的社交和互动方面，而不是向学生们学习内容的提供。</li>
</ul>
<h3><strong>纯Web 2.0服务</strong></h3>
<p><strong>Feed操作</strong>（Yahoo Pipes）</p>
<ul>
<li><span><a rel="external nofollow" href="http://pipes.deri.org/">Deri Pipes</a></span>，像Yahoo Pipes一样，可视化的在线编程工具，它是一个用于过滤、转换和聚合网页内容的服务。</li>
</ul>
<p><strong>Feed 聚合</strong>（Bloglines, Google Reader）</p>
<ul>
<li><span><a rel="external nofollow" href="http://newsblur.com/">Newsblur</a></span>，像Google Reader一样的一个RSS在线阅读器。</li>
<li><span><a rel="external nofollow" href="http://rsslounge.aditu.de/">rsslounge</a></span>，基于PHP+MySQL开发的RSS供稿阅读器。可以分类，过滤供稿，设置优先权。除标准的供稿项目之外，还支持图片/照片。</li>
<li><span><a rel="external nofollow" href="http://tt-rss.org/redmine/">Tiny Tiny RSS</a></span>，基于Web的RSS/Atom新闻聚合器。它的UI基于Ajax技术开发所以看起非常像一个桌面应用程序。</li>
<li><span><a rel="external nofollow" href="http://getlilina.org/">Lilina</a></span>，一个开源的RSS新闻聚合器实现，功能强大，方便易用，而且最大的好处是不需要数据库支持。</li>
<li><span><a rel="external nofollow" href="http://openwebreader.org/">OpenWebReader</a></span>，多用户的RSS聚合阅读。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/gregarius/">Gregarius</a></span>，RSS/RDF/ATOM新闻聚合器支持OPML导入/导出，XHTML/CSS输出。它包含一个基于Ajax的itemtagging系统。</li>
<li><span><a rel="external nofollow" href="http://cheetah-news.com/">Cheetah News</a></span>，利用AJAX技术构建的RSS阅读器，完美支持中文。</li>
<li><span><a rel="external nofollow" href="http://www.oschina.net/p/memephage">Memephage</a></span>，是一种自动化网络日志。它能搜集并总结从不同地方收集来的连接，目前是从IRC, 社交MUD，邮件和浏览器中搜集，并使用POE多任务处理和网络框架。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/ozcode/">Ozcode</a></span>，是Ozmozr.com背后的源代码, 一个微型RSS聚合器，可以进行网络社交、信息分享、身份聚合与展示的网站。</li>
</ul>
<p><strong>社区聚合</strong>（FriendFeed）</p>
<ul>
<li><span><a rel="external nofollow" href="http://identi.ca/">Identi.ca</a></span>，一个新的微网志服务, 其实现在微博服务真的是很多了, 不过这个比较特别一点的是, identi.ca 用PHP 开发, 可以用jabber/GTalk, 也可以用openid 来登录，主要的是，其是开源项目。</li>
<li><span><a rel="external nofollow" href="http://noserub.com/">Noserub</a></span>，提供的建站程序，可以创建属于你的微型门户，包括 Blog、网络摘录、图片分享、视频、Twitter 等等的，都可以罗列出来，并且通过 RSS 实时更新内容，你的朋友们可以方便的获知你在网络里经常去哪里，最近在关注一些什么，做些什么，想些什么。</li>
</ul>
<p><strong>社区新闻</strong>（digg）</p>
<ul>
<li><span><a rel="external nofollow" href="http://meneame.net/">Meneame</a></span>，程序是类似Digg的西班牙程序，网址是<span><a rel="external nofollow" href="http://websvn.meneame.net/">http://websvn.meneame.net/</a></span></li>
<li><span><a rel="external nofollow" href="http://pligg.com/">Pligg</a></span>，最灵活的类似Digg的Web2.0 CMS系统！网页设计师可以使用Pligg做他(她)想做的任何事情。稍微懂一些PHP和Mysql的知识即可安装Pligg。</li>
<li><span><a rel="external nofollow" href="http://drupal.org/project/drigg/">Drigg</a></span>，基于Drupal 构建的PHP的Digg网站系统。</li>
<li><span><a rel="external nofollow" href="http://www.reddit.com/">Reddit</a></span>，其源码和文档在这里：<span><a rel="external nofollow" href="https://github.com/reddit/reddit">https://github.com/reddit/reddit</a></span></li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/communitynews/">CommunityNews</a></span>，通过使用社交书签和贝叶斯定理技术向博客定期提供记录。用户可以通过投票支持或反对RSS来源以支持那些受欢迎的资源。</li>
<li><span><a rel="external nofollow" href="http://opensource.newscloud.com/">NewsCloud</a></span>，是一款基于NewsCloud.com专为平民新闻业和社会新闻网络设计的开源传媒平台。</li>
<li><span><a rel="external nofollow" href="http://jamss.sourceforge.net/">Jamss</a></span>，是基于Digg.com的社交新闻网站, 其通过PHP/MySQL运行。.Jamss 考虑到了行内意见和网络文章的评论，还可以灵活适应多种主题。</li>
</ul>
<p><strong>社区网络</strong>（Facebook, Twitter）</p>
<ul>
<li><span><a rel="external nofollow" href="http://portal.friendika.com/">Friendika</a></span>，一个由PHP+MySQL的免费应用程式(Open Source)，提供使用者一个单一的界面来控制社群网路服务。支援的社群网路应用服务包括Facebook，Twitter、WordPress、Blogger、Identi.ca、RSS订阅与电子邮件等等的整合服务。</li>
<li><span><a rel="external nofollow" href="https://joindiaspora.com/">Diaspora</a></span>，让你将您的关系分成多个视图（Google+的圈子），每个视图是您生活的不同部分。这是Diaspora首创，用来确保您的照片、经历和笑话，只与您所希望分享的人分享。</li>
<li><span><a rel="external nofollow" href="http://buddypress-es.com/">Buddypress</a></span>，是 WordPress 母公司的一个全新的开源程序，BuddyPress 从本质上说其实是 WordPress 的插件。BuddyPress 把 WordPress的关注点从博客转移到了社区。当然，用户还是能够使用WordPress的所有的博客功能，只是当用户使用 BuddyPress 时，第一要做的是创建他们个人档案，第二才是写博客。</li>
<li><span><a rel="external nofollow" href="http://foocorp.org/projects/social/">GNU Social</a></span>，GNU的SNS。</li>
<li><span><a rel="external nofollow" href="http://www.elgg.org/">Elgg</a></span>，一款免费开源的社会性网络脚本程序(php/mysql)，以BLOG为中心实现社会网络化，从社会性来讲：Elgg以兴趣为核心的社交平台。它包括网络日志、资料存储、RSS集合、个人档案、FOAF功能等等。</li>
<li><span><a rel="external nofollow" href="http://www.socialengine.net/index_vivalogo.php">SocialEngine</a></span>，是一款由PHP和Zend控制的网络软件，其脚本让你可以轻松地创建属于你自己社交网站或是在线社区，包括自定义群组、相册、消息、用户档案、视频、新闻订阅，拖放群集邮箱服务器等等功能。</li>
<li><span><a rel="external nofollow" href="http://www.isocial.in/">iSocial</a></span>，是一款免费社交网络脚本平台，你可以用它建立像Friendster和Orkut那样可以一键使用书签，约会和建立群组的社交网站。</li>
<li><span><a rel="external nofollow" href="http://mahara.org/">Mahara</a></span>，有着电子档案、网络日志、简历编辑工具、联系用户的社交网络系统以及建立在线社区的齐全功能。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/peepagg/">The PeopleAggregator</a></span>，是全新一代的社交网站系统，它力求应用开放的标准、密切的网络互动和强大的灵活性。</li>
<li><span><a rel="external nofollow" href="http://opensource.appleseedproject.org/">Appleseed</a></span>，是一款类似Friendster的社交网站软件。网站运行appleseed将互通，形成Appleseed的社交网站。该软件发展的重点是对隐私和安全，以及易用的配置。</li>
<li><span><a rel="external nofollow" href="http://www.mugshots.com/">Mugshot</a></span>，则通过一系列的WEB CRM、照片、日志等等让你时刻了解朋友们的最新动态。</li>
<li><span><a rel="external nofollow" href="http://code.google.com/p/clonesumating/">Clonesumating</a></span>，是<span><a rel="external nofollow" href="http://consumating.com/">CONSUMATING.COM</a></span>代码的开源版本， 其功能有用户档案、用户标签、配对并发现古怪标签合并、团队活动（比如每周照片评选、博客问答）、事件日历、PSS订阅等等。</li>
<li><span><a rel="external nofollow" href="http://www.bevolunteer.org/trac/">BeWelcom Rox</a></span>，是<span><a rel="external nofollow" href="http://www.bewelcome.org/">www.bewelcome.org</a></span>等其他社交网站的运作平台，它将人们真实地聚集了在一起。在那里人们了解全球村庄以及其他文化，分享自己的所在地，组织旅游，写旅游博客等等。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/openpne/">OpenPNE</a></span>，是由PHP写成的网络社交服务引擎，其功能有好友管理、好友邀请、日记、博客、订收件箱等等。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/worldspace/">WorldSpace</a></span>，是一款用户可拓展的共享虚拟空间，它致力于成为新一代的社交网络系统。</li>
<li><span><a rel="external nofollow" href="http://zoints.com/">Zoints</a></span>，这一款软件熟知在线社区是互联网中最重要的一部分，它所正是为帮助解决论坛版主所面临的三大问题（即获得会员，保留会员和盈利）而设计的。</li>
</ul>
<p><strong>社区书签</strong>（Delicious）</p>
<ul>
<li><span><a rel="external nofollow" href="http://en.wikipedia.org/wiki/Scuttle">Scuttle</a></span>，开源Web书签系统，允许多个用户在线存储，共享和Tag他们喜欢的链接。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/semanticscuttle/">Semantic Scuttle</a></span>，是一款基于Scuttle的社交书签工具。它可以试验像层次化标签、合作描述、OpenID认证这样的全新功能。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/sabrosus/">Sabros.us</a></span>，一个基于互联网的书签系统。它与del.icio.us 是相似，您能在网上处理您的书签, 或者自己建立一个网站。</li>
<li><span><a rel="external nofollow" href="http://www.connotea.org/">Connotea</a></span>，是 NGP(Nature Publishing Group) 旗下的网站，借鉴当前流行的 del.icio.us 等社会书签的创意，专注于科研领域，并可导入桌面文献管理软件的数据，是当前比较流行的一款在线文献管理工具。</li>
<li><span><a rel="external nofollow" href="https://github.com/alx/pressmark/">Pressmark</a></span></li>
<li><span><a rel="external nofollow" href="http://www.shiftspace.org/">Shiftspace</a></span>，让你的Wordpress成为像?<span><a rel="external nofollow" href="http://del.icio.us/">del.icio.us</a></span>,?<span><a rel="external nofollow" href="http://sabros.us/">sabros.us</a></span>这样的站点。</li>
<li><span><a rel="external nofollow" href="http://wwwhatsnew.com/2006/02/02/magnolia-algo-grande-llega-desde-el-mundo-de-los-bookmarks/">Ma.gnolia 2</a></span>，基于Ruby开发。它的界面比较漂亮，但速度比较慢，另外搜索仅限于tag。</li>
<li><span><a rel="external nofollow" href="http://sourceforge.net/projects/akarru">Akarru</a></span>，是一款用来建立像<span><a rel="external nofollow" href="http://www.blogmemes.com/">www.blogmemes.com</a></span>网站的社交书签引擎。用户可以通过投票系统在首页上张贴链接并推销链接。</li>
<li><span><a rel="external nofollow" href="http://www.shokk.com/blog/articles/category/monkeychow/">Monkey Chow</a></span>，是一款带有社交书签、主题文章、来源标签、OPML、文章搜索、编辑来源属性等等众多功能的新闻聚合浏览器。</li>
<li><span><a rel="external nofollow" href="http://feedmelinks.com/">Feed Me Links</a></span>，可以将你的书签存储在网上以便随时随地使用，输入你最喜爱的网址并和好友们分享，加标签来管理不同链接，还有更多新鲜事物等待你来发现。</li>
</ul>
<p><strong>短网址服务</strong>（TinyURL）</p>
<ul>
<li><span><a rel="external nofollow" href="https://gitorious.org/mencey/tinyull">tinyULL</a></span>，不是tinyURL，别看错了。</li>
</ul>
<h3><strong>身份和安全</strong></h3>
<p><strong>域名</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://www.namecoin.us/">Namecoin</a></span>/<span><a rel="external nofollow" href="http://dot-bit.org/">.bit</a></span>，基于bitcoin技术的分散、开放DNS系统。.bit域名到底靠不靠谱啊，是不是有P2P网络存在，.bit网站就能永远访问？会不会被墙？我们不得而之。</li>
<li><span><a rel="external nofollow" href="http://www.socialdns.net/">Social DNS</a></span></li>
<li><span><a rel="external nofollow" href="http://distributeddns.sourceforge.net/">Distributed DNS</a></span></li>
</ul>
<p><strong>身份凭证</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://wiki.openid.net/w/page/12995176/Libraries/">OpenID</a></span>，一个去中心化的网上身份认证系统。对于支持OpenID的网站，用户不需要记住像用户名和密码这样的传统验证标记。取而代之的是，他们只需要预先在一个作为OpenID身份提供者（identity provider, IdP）的网站上注册。OpenID是去中心化的，任何网站都可以使用OpenID来作为用户登录的一种方式，任何网站也都可以作为OpenID身份提供者。OpenID既解决了问题而又不需要依赖于中心性的网站来确认数字身份。OpenID正在被越来越多的大网站采用</li>
<li><span><a rel="external nofollow" href="http://oauth.net/code/">OAuth</a></span>，（开放授权）是一个开放标准，允许用户让第三方应用访问该用户在某一网站上存储的私密的资源（如照片，视频，联系人列表），而无需将用户名和密码提供给第三方应用。</li>
</ul>
<p><strong>加密</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://www.cacert.org/">CACert</a></span>，想给自己申请一份电子邮件证书或者给自己的<span><a rel="external nofollow" href="http://blog.mop.name/category/%e8%b6%a3%e7%ab%99">网站</a></span>、服务器申请一个SSL证书是很不容易的，你每年都得给CA（证书颁发验证组织）缴纳不少的证书申请费。有了CAcert，国外一个<span><a rel="external nofollow" href="http://blog.mop.name/category/free">免费</a></span>的数字证书颁发组织，你可以<span><a rel="external nofollow" href="http://blog.mop.name/category/free">免费</a></span>注册成为用户，申领个人证书和服务器证书等。证书被各种浏览器、邮件客户端所支持。</li>
</ul>
<h3><strong>其它</strong></h3>
<p><strong>翻译</strong>（Google Translator）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.apertium.org/">Apertium</a></span>，一个机器翻译平台，由西班牙政府和加泰罗尼亚自治政府拨款支持阿利坎特大学开发。</li>
</ul>
<p><strong>桌面</strong>（iGoogle, netbives）</p>
<ul>
<li><span><a rel="external nofollow" href="http://www.eyeos.org/">EyeOS</a></span>，一款web桌面环境, 俗称Web Operating System (Web OS)或者Web Office. eyeOS是一个开源的软件, 用户可以自由下载或者在eyeOS的服务器 eyeOS server 上使用. 基本的系统附带一些办公软件和 PIM 应用, 并且在官方<a rel="external nofollow" href="http://eyeos.org/">http://eyeos.org</a>可以找到完整的程序代码。其开发哲学是：Taking Your Life Everywhere!</li>
<li>CorneliOS，一款运行在服务器端、基于网络的网络虚拟操作系统，本身通过HTML和（或）XHTML为用户提供各种服务，这也就意味着用户只需要使用普通浏览器即可连接并使用这款操作系统。非常类似 eyeOS。</li>
</ul>
<p><strong>3D库</strong>（Google SketchUp 3D Warehouse, Google O3D API）</p>
<ul>
<li><span><a rel="external nofollow" href="https://wiki.mozilla.org/Canvas:3D">Mozilla Canvas 3D</a></span>，OpenGL 3D Web。</li>
<li><span><a rel="external nofollow" href="http://www.doogal.co.uk/KmlViewer.php/">Web KML Viewer</a></span>。</li>
</ul>
<p><strong>参考</strong></p>
<ul>
<li><span><a rel="external nofollow" href="http://en.wikipedia.org/wiki/List_of_free_software_for_Web_2.0_services">Wikipedia</a></span></li>
<li><span><a rel="external nofollow" href="http://www.dasheyin.com/da_jian_ni_zi_ji_de_she_jiao_wang_luo_kai_yuan_she_jiao_wang_luo_cheng_xu_ji_he.html">搭建你自己的社交网络：开源社交网络程序集合</a></span></li>
<li>From?<a rel="external nofollow" href="http://coolshell.cn/articles/5132.html">http://coolshell.cn/articles/5132.html</a></li>
</ul>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/06/php-daemon-notice/" title="[转] 代替bash，书写 PHP daemon 后台程序">[转] 代替bash，书写 PHP daemon 后台程序</a></li><li><a href="http://slj.me/2011/04/xdebug-for-php/" title="Xdebug for php 一个实用的PHP调试扩展">Xdebug for php 一个实用的PHP调试扩展</a></li><li><a href="http://slj.me/2011/02/php-share-session-between-servers/" title="PHP 实现多服务器共享 SESSION 数据">PHP 实现多服务器共享 SESSION 数据</a></li><li><a href="http://slj.me/2010/12/php-ini_set-fail-reason/" title="PHP ini_set() 无效的原因">PHP ini_set() 无效的原因</a></li><li><a href="http://slj.me/2010/12/centos-php5-2-yum/" title="CentOS 用 yum 官方源安裝 PHP5.2.x">CentOS 用 yum 官方源安裝 PHP5.2.x</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/08/web-open-source-project/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>[转] 代替bash，书写 PHP daemon 后台程序</title>
		<link>http://slj.me/2011/06/php-daemon-notice/</link>
		<comments>http://slj.me/2011/06/php-daemon-notice/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 07:16:08 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[daemon]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2236</guid>
		<description><![CDATA[最近在雅虎的一个朋友和我说，以前用bash csh 写脚本, 它现在都在用PHP 写后台程序，觉得PHP的函数最全，而且很容易用 shell_exec 很容易调用系统内核。 我和他交流了一下写后台程序的一些原则，归纳如下。 首先，要去掉以前写网页脚本的一些思维习惯。网页脚本运行一次以后，就马上释放内存。而daemon 程序不一样，它会一直运行一年，甚至几年。 作为一个好的习惯，一定要在while (1) {} 这样一个死循环里面运行代码。这样，只要代码不出状况，脚本就不会停止。 echo 不能用，而是用log 代替。用写日志的方法代替echo。因为echo 是 向 屏幕输出一个字符，如果没有任何输出的对象，就会报一个致命错误。 如果MYSQL，要每次重新连接MYSQL。 function connnect() { global $db; if (is_resource($db)) { mysqli_close($db); } $db = mysqli_connect("123.1.2.3", 'dbuser', 'dbpsw', 'dbname'); } 上面就是连接的一个例子。这个代码曾经被一个高手狠狠的批评了一顿。这个主要是为了防止下面的事情： mysql 重启了，$db 变量肯定还是个资源，但是这个资源已经无效了。如果再执行代码就会发生： mysql has go away 这样的错误。这个会向屏幕输出，即时关闭错误报告也一样会输出。这样导致整个 脚本运行错误，和echo 产生的错误一样。 虽然每次连接数据库有些浪费，但是也只能宁可错杀1000，也不放过一个。这个错误，是大多数朋友都会犯的 错误，很多人和我说这个是mysql的bug，因为，本来写文件好好的，后来连接带mysql就出错了。 其实不是mysql的bug。 新产生的变量，如果不是自动释放的，要马上释放。否则日积月累，程序就要崩溃。很多PHP程序员没有一点 内存管理的概念，觉得内存是无限的，随便用，写后台程序一定要注意内存的管理。 如果要访问文件，首先要 clearstatcache, 否则很有可能会不精确的统计，或者 判断文件是否存在变的不准确了。更要命的是，如果你频繁打开文件，文件的handle 值会 不断增加，等到超过整数的最大值，程序就无法打开文件。很多人的程序，3个月挂一次， 没有出现错误，也没有出现内存问题，很有可能就是每次操作文件前，没有清除statcache。 附：运行的时候sh脚本可以是： #!/bin/sh daemon [...]]]></description>
			<content:encoded><![CDATA[<p>    最近在雅虎的一个朋友和我说，以前用bash csh 写脚本, 它现在都在用PHP 写后台程序，觉得PHP的函数最全，而且很容易用 shell_exec 很容易调用系统内核。<br />
我和他交流了一下写后台程序的一些原则，归纳如下。<br />
首先，要去掉以前写网页脚本的一些思维习惯。网页脚本运行一次以后，就马上释放内存。而daemon 程序不一样，它会一直运行一年，甚至几年。<br />
<span id="more-2236"></span>
<ol>
<li>作为一个好的习惯，一定要在while (1) {} 这样一个死循环里面运行代码。这样，只要代码不出状况，脚本就不会停止。</li>
<li>echo 不能用，而是用log 代替。用写日志的方法代替echo。因为echo 是 向 屏幕输出一个字符，如果没有任何输出的对象，就会报一个致命错误。</li>
<li> 如果MYSQL，要每次重新连接MYSQL。
<pre class="php" name="code">
function connnect()
{
global $db;
if (is_resource($db)) {
mysqli_close($db);
}
$db = mysqli_connect("123.1.2.3", 'dbuser', 'dbpsw', 'dbname');
}
</pre>
<p>上面就是连接的一个例子。这个代码曾经被一个高手狠狠的批评了一顿。这个主要是为了防止下面的事情：<br />
mysql 重启了，$db 变量肯定还是个资源，但是这个资源已经无效了。如果再执行代码就会发生：<br />
mysql has go away 这样的错误。这个会向屏幕输出，即时关闭错误报告也一样会输出。这样导致整个<br />
脚本运行错误，和echo 产生的错误一样。<br />
虽然每次连接数据库有些浪费，但是也只能宁可错杀1000，也不放过一个。这个错误，是大多数朋友都会犯的<br />
错误，很多人和我说这个是mysql的bug，因为，本来写文件好好的，后来连接带mysql就出错了。<br />
其实不是mysql的bug。
</li>
<li>新产生的变量，如果不是自动释放的，要马上释放。否则日积月累，程序就要崩溃。很多PHP程序员没有一点<br />
内存管理的概念，觉得内存是无限的，随便用，写后台程序一定要注意内存的管理。
</li>
<li>如果要访问文件，首先要 clearstatcache, 否则很有可能会不精确的统计，或者<br />
判断文件是否存在变的不准确了。更要命的是，如果你频繁打开文件，文件的handle 值会<br />
不断增加，等到超过整数的最大值，程序就无法打开文件。很多人的程序，3个月挂一次，<br />
没有出现错误，也没有出现内存问题，很有可能就是每次操作文件前，没有清除statcache。
</li>
</ol>
<p>附：运行的时候sh脚本可以是：</p>
<blockquote><p>
#!/bin/sh<br />
daemon &#8211;respawn &#8211;pidfile=/data/abc.pid &#8211;output=/data/abc/log/output.log &#8211;stderr=/data/abc/log/error.log &#8211;name=abcd &#8212; /usr/local/php/bin/php /data/abc/abc.class.php</p></blockquote>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/08/web-open-source-project/" title="疯狂的 Web 应用开源项目">疯狂的 Web 应用开源项目</a></li><li><a href="http://slj.me/2011/04/xdebug-for-php/" title="Xdebug for php 一个实用的PHP调试扩展">Xdebug for php 一个实用的PHP调试扩展</a></li><li><a href="http://slj.me/2011/03/share-bash-script/" title="分享两则我在VPS上执行的sh脚本">分享两则我在VPS上执行的sh脚本</a></li><li><a href="http://slj.me/2011/02/php-share-session-between-servers/" title="PHP 实现多服务器共享 SESSION 数据">PHP 实现多服务器共享 SESSION 数据</a></li><li><a href="http://slj.me/2010/12/php-ini_set-fail-reason/" title="PHP ini_set() 无效的原因">PHP ini_set() 无效的原因</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/06/php-daemon-notice/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SCPlugin &#8211; 在MacOS下像Windows中TortoiseSVN一样来操作SVN</title>
		<link>http://slj.me/2011/04/introduce-to-scplugin/</link>
		<comments>http://slj.me/2011/04/introduce-to-scplugin/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 12:44:08 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2231</guid>
		<description><![CDATA[今天来推荐一个在MacOS下图形化的SVN工具。 虽然MacOS下已经整合了subversion命令行，但是对于不熟悉命令的人来说，有一个图形化的管理工具还是很重要的。 废话不多说，上图： 项目地址： http://scplugin.tigris.org/ Related Posts / 相关文章分享两则我在VPS上执行的sh脚本关于CVS和SVN]]></description>
			<content:encoded><![CDATA[<p>今天来推荐一个在MacOS下图形化的SVN工具。</p>
<p>虽然MacOS下已经整合了subversion命令行，但是对于不熟悉命令的人来说，有一个图形化的管理工具还是很重要的。</p>
<p>废话不多说，上图：<br />
<a href="http://slj.me/wp-content/uploads/2011/04/contextual_menu.png"><img src="http://slj.me/wp-content/uploads/2011/04/contextual_menu-300x291.png" alt="" title="contextual_menu" width="300" height="291" class="alignnone size-medium wp-image-2232" /></a></p>
<p>项目地址：<br />
<a href="http://scplugin.tigris.org/" rel='external nofollow'>http://scplugin.tigris.org/</a></p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/03/share-bash-script/" title="分享两则我在VPS上执行的sh脚本">分享两则我在VPS上执行的sh脚本</a></li><li><a href="http://slj.me/2009/03/cvs-svn-compare/" title="关于CVS和SVN">关于CVS和SVN</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/04/introduce-to-scplugin/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Xdebug for php 一个实用的PHP调试扩展</title>
		<link>http://slj.me/2011/04/xdebug-for-php/</link>
		<comments>http://slj.me/2011/04/xdebug-for-php/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 03:02:52 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[xdebug]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2226</guid>
		<description><![CDATA[Xdebug简介 Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具)，可以用来跟踪，调试和分析PHP程序的运行状况。Xdebug现在的最新版本是Xdebug 2.1.0, release日期 2010-6-29，支持PHP4/PHP5。 xdebug for php安装 首先去官网下载新版的xdebug http://www.xdebug.org/docs/install linux下解压xdebug包。 进入xdebug,在这个目录下先运行php目录下面的bin/phpize； 一定要先运行这个，不然不可以./configure 执行 ./configure  --enable-xdebug  --with-php-config=/你php的bin路径/php-config  ; make 好了，结束了。这是时候会在xdebug的目录下生成 目录modules，目录下有xdebug.so文件，把xdebug.so复制到你想放的目录。 在php的配置文件后面加上 zend_extension = &#8220;/路径/xdebug.so&#8221; 重启，看phpinfo();    或者 命令行里 ./php -m &#124;grep debug  有结果就成了。 Related Posts / 相关文章疯狂的 Web 应用开源项目[转] 代替bash，书写 PHP daemon 后台程序PHP 实现多服务器共享 SESSION 数据PHP ini_set() 无效的原因CentOS 用 yum 官方源安裝 PHP5.2.x]]></description>
			<content:encoded><![CDATA[<h3>Xdebug简介</h3>
<p>Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具)，可以用来跟踪，调试和分析PHP程序的运行状况。Xdebug现在的最新版本是Xdebug 2.1.0, release日期 2010-6-29，支持PHP4/PHP5。<br />
<span id="more-2226"></span></p>
<h3>xdebug for php安装</h3>
<p>首先去官网下载新版的xdebug<br />
<a href="http://www.xdebug.org/docs/install" target="_blank">http://www.xdebug.org/docs/install</a></p>
<p>linux下解压xdebug包。</p>
<ol>
<li> 进入xdebug,在这个目录下先运行php目录下面的bin/phpize；<br />
一定要先运行这个，不然不可以./configure</li>
<li> 执行<br />
<code>./configure  --enable-xdebug  --with-php-config=/你php的bin路径/php-config  ;</code></li>
<li>make<br />
好了，结束了。这是时候会在xdebug的目录下生成 目录modules，目录下有xdebug.so文件，把xdebug.so复制到你想放的目录。</li>
<li>在php的配置文件后面加上<br />
zend_extension = &#8220;/路径/xdebug.so&#8221;</li>
<li>重启，看phpinfo();    或者 命令行里 ./php -m |grep debug  有结果就成了。</li>
</ol>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/08/web-open-source-project/" title="疯狂的 Web 应用开源项目">疯狂的 Web 应用开源项目</a></li><li><a href="http://slj.me/2011/06/php-daemon-notice/" title="[转] 代替bash，书写 PHP daemon 后台程序">[转] 代替bash，书写 PHP daemon 后台程序</a></li><li><a href="http://slj.me/2011/02/php-share-session-between-servers/" title="PHP 实现多服务器共享 SESSION 数据">PHP 实现多服务器共享 SESSION 数据</a></li><li><a href="http://slj.me/2010/12/php-ini_set-fail-reason/" title="PHP ini_set() 无效的原因">PHP ini_set() 无效的原因</a></li><li><a href="http://slj.me/2010/12/centos-php5-2-yum/" title="CentOS 用 yum 官方源安裝 PHP5.2.x">CentOS 用 yum 官方源安裝 PHP5.2.x</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/04/xdebug-for-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>phpredis－一个Redis的PHP扩展</title>
		<link>http://slj.me/2011/04/phpredis-extension-of-php/</link>
		<comments>http://slj.me/2011/04/phpredis-extension-of-php/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 13:34:47 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[NoSQL]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2219</guid>
		<description><![CDATA[介绍一个开源扩展：phpredis，这个扩展能让你的PHP操作redis 项目地址：https://github.com/nicolasff/phpredis 安装： phpize ./configure make &#38;&#38; make install make install 以后复制 redis.so 到恰当的位置，但在 PHP 配置文件中把这个扩展给启用了。修改 php.ini 或者新建一个 redis.ini 到 /etc/php5/conf.d (你自己的路径) 内容是 extension=redis.so 详细参看项目地址 在MacOS上安装： MACOSX_DEPLOYMENT_TARGET=10.6 CFLAGS="-arch i386 -arch x86_64 -g -Os -pipe -no-cpp-precomp" CCFLAGS="-arch i386 -arch x86_64 -g -Os -pipe" CXXFLAGS="-arch i386 -arch x86_64 -g -Os -pipe" LDFLAGS="-arch i386 -arch x86_64 -bind_at_load" export CFLAGS CXXFLAGS [...]]]></description>
			<content:encoded><![CDATA[<p>介绍一个开源扩展：phpredis，这个扩展能让你的PHP操作redis</p>
<p>项目地址：<a href="https://github.com/nicolasff/phpredis" target="_blank">https://github.com/nicolasff/phpredis</a></p>
<h3>安装：</h3>
<blockquote>
<pre>phpize
./configure
make &amp;&amp; make install</pre>
</blockquote>
<p><code>make install</code> 以后复制 <code>redis.so</code> 到恰当的位置，但在 PHP 配置文件中把这个扩展给启用了。修改 php.ini 或者新建一个 redis.ini 到 <code>/etc/php5/conf.d (你自己的路径) 内容是 </code> <code>extension=redis.so 详细参看项目地址</code></p>
<h3><span id="more-2219"></span>在MacOS上安装：</h3>
<blockquote>
<pre>MACOSX_DEPLOYMENT_TARGET=10.6
CFLAGS="-arch i386 -arch x86_64 -g -Os -pipe -no-cpp-precomp"
CCFLAGS="-arch i386 -arch x86_64 -g -Os -pipe"
CXXFLAGS="-arch i386 -arch x86_64 -g -Os -pipe"
LDFLAGS="-arch i386 -arch x86_64 -bind_at_load"
export CFLAGS CXXFLAGS LDFLAGS CCFLAGS MACOSX_DEPLOYMENT_TARGET</pre>
</blockquote>
<h3>相关类的操作</h3>
<p>相关的PHP中的类操作就参看<a href="https://github.com/nicolasff/phpredis" target="_blank">项目地址</a>吧，太多了，懒得翻译了 :P</p>
<h2  class="related_post_title">Other Posts / 其他文章</h2><ul class="related_post"><li><a href="http://slj.me/2009/06/google-pr%e6%9b%b4%e6%96%b0%e4%ba%86/" title="GOOGLE PR更新了">GOOGLE PR更新了</a></li><li><a href="http://slj.me/2009/06/zend-framework-start/" title="Zend Framework 入门">Zend Framework 入门</a></li><li><a href="http://slj.me/2009/04/recent/" title="我的近况">我的近况</a></li><li><a href="http://slj.me/2009/12/css-shadow/" title="CSS阴影详解">CSS阴影详解</a></li><li><a href="http://slj.me/2010/03/%e6%bc%8f%e5%98%b4%e7%bd%91%e5%8d%b3%e5%b0%86%e4%b8%8a%e7%ba%bf/" title="漏嘴网即将上线">漏嘴网即将上线</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/04/phpredis-extension-of-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Redis] redis-cli 命令总结</title>
		<link>http://slj.me/2011/04/redis-cli-commands/</link>
		<comments>http://slj.me/2011/04/redis-cli-commands/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 13:12:21 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[redis]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2211</guid>
		<description><![CDATA[Redis提供了丰富的命令（command）对数据库和各种数据类型进行操作，这些command可以在Linux终端使用。在编程时，比如使用Redis 的Java语言包，这些命令都有对应的方法。下面将Redis提供的命令做一总结。 官网命令列表：http://redis.io/commands （英文） 1、连接操作相关的命令 quit：关闭连接（connection） auth：简单密码认证 2、对value操作的命令 exists(key)：确认一个key是否存在 del(key)：删除一个key type(key)：返回值的类型 keys(pattern)：返回满足给定pattern的所有key randomkey：随机返回key空间的一个key rename(oldname, newname)：将key由oldname重命名为newname，若newname存在则删除newname表示的key dbsize：返回当前数据库中key的数目 expire：设定一个key的活动时间（s） ttl：获得一个key的活动时间 select(index)：按索引查询 move(key, dbindex)：将当前数据库中的key转移到有dbindex索引的数据库 flushdb：删除当前选择数据库中的所有key flushall：删除所有数据库中的所有key 3、对String操作的命令 set(key, value)：给数据库中名称为key的string赋予值value get(key)：返回数据库中名称为key的string的value getset(key, value)：给名称为key的string赋予上一次的value mget(key1, key2,…, key N)：返回库中多个string（它们的名称为key1，key2…）的value setnx(key, value)：如果不存在名称为key的string，则向库中添加string，名称为key，值为value setex(key, time, value)：向库中添加string（名称为key，值为value）同时，设定过期时间time mset(key1, value1, key2, value2,…key N, value N)：同时给多个string赋值，名称为key i的string赋值value i msetnx(key1, value1, key2, value2,…key N, value N)：如果所有名称为key i的string都不存在，则向库中添加string，名称key [...]]]></description>
			<content:encoded><![CDATA[<p>Redis提供了丰富的命令（command）对数据库和各种数据类型进行操作，这些command可以在Linux终端使用。在编程时，比如使用Redis 的Java语言包，这些命令都有对应的方法。下面将Redis提供的命令做一总结。</p>
<p>官网命令列表：<a href="http://redis.io/commands" target="_blank">http://redis.io/commands</a> （英文）</p>
<h3>1、连接操作相关的命令</h3>
<ul>
<li>quit：关闭连接（connection）</li>
<li>auth：简单密码认证</li>
</ul>
<h3>2、对value操作的命令</h3>
<ul>
<li>exists(key)：确认一个key是否存在</li>
<li>del(key)：删除一个key</li>
<li>type(key)：返回值的类型</li>
<li>keys(pattern)：返回满足给定pattern的所有key</li>
<li>randomkey：随机返回key空间的一个key</li>
<li>rename(oldname, newname)：将key由oldname重命名为newname，若newname存在则删除newname表示的key</li>
<li>dbsize：返回当前数据库中key的数目</li>
<li>expire：设定一个key的活动时间（s）</li>
<li>ttl：获得一个key的活动时间</li>
<li>select(index)：按索引查询</li>
<li>move(key, dbindex)：将当前数据库中的key转移到有dbindex索引的数据库</li>
<li>flushdb：删除当前选择数据库中的所有key</li>
<li>flushall：删除所有数据库中的所有key</li>
</ul>
<h3><span id="more-2211"></span>3、对String操作的命令</h3>
<ul>
<li>set(key, value)：给数据库中名称为key的string赋予值value</li>
<li>get(key)：返回数据库中名称为key的string的value</li>
<li>getset(key, value)：给名称为key的string赋予上一次的value</li>
<li>mget(key1, key2,…, key N)：返回库中多个string（它们的名称为key1，key2…）的value</li>
<li>setnx(key, value)：如果不存在名称为key的string，则向库中添加string，名称为key，值为value</li>
<li>setex(key, time, value)：向库中添加string（名称为key，值为value）同时，设定过期时间time</li>
<li>mset(key1, value1, key2, value2,…key N, value N)：同时给多个string赋值，名称为key i的string赋值value i</li>
<li>msetnx(key1, value1, key2, value2,…key N, value N)：如果所有名称为key i的string都不存在，则向库中添加string，名称key i赋值为value i</li>
<li>incr(key)：名称为key的string增1操作</li>
<li>incrby(key, integer)：名称为key的string增加integer</li>
<li>decr(key)：名称为key的string减1操作</li>
<li>decrby(key, integer)：名称为key的string减少integer</li>
<li>append(key, value)：名称为key的string的值附加value</li>
<li>substr(key, start, end)：返回名称为key的string的value的子串</li>
</ul>
<h3>4、对List操作的命令</h3>
<ul>
<li>rpush(key, value)：在名称为key的list尾添加一个值为value的元素</li>
<li>lpush(key, value)：在名称为key的list头添加一个值为value的 元素</li>
<li>llen(key)：返回名称为key的list的长度</li>
<li>lrange(key, start, end)：返回名称为key的list中start至end之间的元素（下标从0开始，下同）</li>
<li>ltrim(key, start, end)：截取名称为key的list，保留start至end之间的元素</li>
<li>lindex(key, index)：返回名称为key的list中index位置的元素</li>
<li>lset(key, index, value)：给名称为key的list中index位置的元素赋值为value</li>
<li>lrem(key, count, value)：删除count个名称为key的list中值为value的元素。count为0，删除所有值为value的元素，count&gt;0从头至尾删除count个值为value的元素，count&lt;0从尾到头删除|count|个值为value的元素。 lpop(key)：返回并删除名称为key的list中的首元素 rpop(key)：返回并删除名称为key的list中的尾元素 blpop(key1, key2,… key N, timeout)：lpop命令的block版本。即当timeout为0时，若遇到名称为key i的list不存在或该list为空，则命令结束。如果timeout&gt;0，则遇到上述情况时，等待timeout秒，如果问题没有解决，则对keyi+1开始的list执行pop操作。</li>
<li>brpop(key1, key2,… key N, timeout)：rpop的block版本。参考上一命令。</li>
<li>rpoplpush(srckey, dstkey)：返回并删除名称为srckey的list的尾元素，并将该元素添加到名称为dstkey的list的头部</li>
</ul>
<h3>5、对Set操作的命令</h3>
<ul>
<li>sadd(key, member)：向名称为key的set中添加元素member</li>
<li>srem(key, member) ：删除名称为key的set中的元素member</li>
<li>spop(key) ：随机返回并删除名称为key的set中一个元素</li>
<li>smove(srckey, dstkey, member) ：将member元素从名称为srckey的集合移到名称为dstkey的集合</li>
<li>scard(key) ：返回名称为key的set的基数</li>
<li>sismember(key, member) ：测试member是否是名称为key的set的元素</li>
<li>sinter(key1, key2,…key N) ：求交集</li>
<li>sinterstore(dstkey, key1, key2,…key N) ：求交集并将交集保存到dstkey的集合</li>
<li>sunion(key1, key2,…key N) ：求并集</li>
<li>sunionstore(dstkey, key1, key2,…key N) ：求并集并将并集保存到dstkey的集合</li>
<li>sdiff(key1, key2,…key N) ：求差集</li>
<li>sdiffstore(dstkey, key1, key2,…key N) ：求差集并将差集保存到dstkey的集合</li>
<li>smembers(key) ：返回名称为key的set的所有元素</li>
<li>srandmember(key) ：随机返回名称为key的set的一个元素</li>
</ul>
<h3>6、对zset（sorted set）操作的命令</h3>
<ul>
<li>zadd(key, score, member)：向名称为key的zset中添加元素member，score用于排序。如果该元素已经存在，则根据score更新该元素的顺序。</li>
<li>zrem(key, member) ：删除名称为key的zset中的元素member</li>
<li>zincrby(key, increment, member) ：如果在名称为key的zset中已经存在元素member，则该元素的score增加increment；否则向集合中添加该元素，其score的值为increment</li>
<li>zrank(key, member) ：返回名称为key的zset（元素已按score从小到大排序）中member元素的rank（即index，从0开始），若没有member元素，返回“nil”</li>
<li>zrevrank(key, member) ：返回名称为key的zset（元素已按score从大到小排序）中member元素的rank（即index，从0开始），若没有member元素，返回“nil”</li>
<li>zrange(key, start, end)：返回名称为key的zset（元素已按score从小到大排序）中的index从start到end的所有元素</li>
<li>zrevrange(key, start, end)：返回名称为key的zset（元素已按score从大到小排序）中的index从start到end的所有元素</li>
<li>zrangebyscore(key, min, max)：返回名称为key的zset中score &gt;= min且score &lt;= max的所有元素 zcard(key)：返回名称为key的zset的基数 zscore(key, element)：返回名称为key的zset中元素element的score zremrangebyrank(key, min, max)：删除名称为key的zset中rank &gt;= min且rank &lt;= max的所有元素 zremrangebyscore(key, min, max) ：删除名称为key的zset中score &gt;= min且score &lt;= max的所有元素</li>
<li>zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX)：对N个zset求并集和交集，并将最后的集合保存在dstkeyN中。对于集合中每一个元素的score，在进行AGGREGATE运算前，都要乘以对于的WEIGHT参数。如果没有提供WEIGHT，默认为1。默认的AGGREGATE是SUM，即结果集合中元素的score是所有集合对应元素进行SUM运算的值，而MIN和MAX是指，结果集合中元素的score是所有集合对应元素中最小值和最大值。</li>
</ul>
<h3>7、对Hash操作的命令</h3>
<ul>
<li>hset(key, field, value)：向名称为key的hash中添加元素field&lt;—&gt;value</li>
<li>hget(key, field)：返回名称为key的hash中field对应的value</li>
<li>hmget(key, field1, …,field N)：返回名称为key的hash中field i对应的value</li>
<li>hmset(key, field1, value1,…,field N, value N)：向名称为key的hash中添加元素field i&lt;—&gt;value i</li>
<li>hincrby(key, field, integer)：将名称为key的hash中field的value增加integer</li>
<li>hexists(key, field)：名称为key的hash中是否存在键为field的域</li>
<li>hdel(key, field)：删除名称为key的hash中键为field的域</li>
<li>hlen(key)：返回名称为key的hash中元素个数</li>
<li>hkeys(key)：返回名称为key的hash中所有键</li>
<li>hvals(key)：返回名称为key的hash中所有键对应的value</li>
<li>hgetall(key)：返回名称为key的hash中所有的键（field）及其对应的value</li>
</ul>
<h3>8、持久化</h3>
<ul>
<li>save：将数据同步保存到磁盘</li>
<li>bgsave：将数据异步保存到磁盘</li>
<li>lastsave：返回上次成功将数据保存到磁盘的Unix时戳</li>
<li>shundown：将数据同步保存到磁盘，然后关闭服务</li>
</ul>
<h3>9、远程服务控制</h3>
<ul>
<li>info：提供服务器的信息和统计</li>
<li>monitor：实时转储收到的请求</li>
<li>slaveof：改变复制策略设置</li>
<li>config：在运行时配置Redis服务器</li>
</ul>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2010/12/redis-misunderstood/" title="[转] Redis几个认识误区">[转] Redis几个认识误区</a></li><li><a href="http://slj.me/2010/12/php-memcached-permission-denied/" title="PHP无法操作memcached提示Permission denied的解决方法">PHP无法操作memcached提示Permission denied的解决方法</a></li><li><a href="http://slj.me/2010/12/compile-memcache-so-for-php-in-mac-os/" title="Mac OS 中为PHP编译memcache.so">Mac OS 中为PHP编译memcache.so</a></li><li><a href="http://slj.me/2010/12/memcache-basic/" title="Memcache 基础">Memcache 基础</a></li><li><a href="http://slj.me/2010/12/install-memcache-on-centos/" title="安装memcache到CentOS（另附yum法）">安装memcache到CentOS（另附yum法）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/04/redis-cli-commands/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>分享21Andy的CentOS的repo</title>
		<link>http://slj.me/2011/03/21andy-centos-repo/</link>
		<comments>http://slj.me/2011/03/21andy-centos-repo/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 03:37:15 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Web Structure]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[repo]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2202</guid>
		<description><![CDATA[21Andy为我们创建了一个cents5的repo点，可以很方便的用yum安装nginx, memcached等等官方源没有的软件。感谢21Andy。按下面的配置后就可以用yum直接安装软件了。 先新建一个 repo # vi /etc/yum.repos.d/centos.21andy.com.repo 放入如下内容 [21Andy.com] name=21Andy.com Packages for Enterprise Linux 5 - $basearch baseurl=http://www.21andy.com/centos/5/$basearch/ enabled=1 gpgcheck=0 protect=1 启用 EPEL repo i386 rpm -ihv http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm x86_64 rpm -ihv http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm 接着导入key rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL Related Posts / 相关文章CentOS 用 yum 官方源安裝 PHP5.2.xCentOS 安装 Apache 后其他机器无法访问的解决方法PHP无法操作memcached提示Permission denied的解决方法安装memcache到CentOS（另附yum法）]]></description>
			<content:encoded><![CDATA[<p>21Andy为我们创建了一个cents5的repo点，可以很方便的用yum安装nginx, memcached等等官方源没有的软件。感谢21Andy。按下面的配置后就可以用yum直接安装软件了。</p>
<p>先新建一个 repo</p>
<blockquote><p><code><br />
# vi /etc/yum.repos.d/centos.21andy.com.repo</code></p></blockquote>
<p>放入如下内容</p>
<blockquote><p><code><br />
[21Andy.com]<br />
name=21Andy.com Packages for Enterprise Linux 5 - $basearch<br />
baseurl=http://www.21andy.com/centos/5/$basearch/<br />
enabled=1<br />
gpgcheck=0<br />
protect=1</code></p></blockquote>
<p>启用 EPEL repo<br />
<span id="more-2202"></span>i386</p>
<blockquote><p><code><br />
rpm -ihv http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm</code></p></blockquote>
<p>x86_64</p>
<blockquote><p><code><br />
rpm -ihv http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm</code></p></blockquote>
<p>接着导入key</p>
<blockquote><p><code><br />
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL</code></p></blockquote>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2010/12/centos-php5-2-yum/" title="CentOS 用 yum 官方源安裝 PHP5.2.x">CentOS 用 yum 官方源安裝 PHP5.2.x</a></li><li><a href="http://slj.me/2010/12/centos-apache-firewall-settings/" title="CentOS 安装 Apache 后其他机器无法访问的解决方法">CentOS 安装 Apache 后其他机器无法访问的解决方法</a></li><li><a href="http://slj.me/2010/12/php-memcached-permission-denied/" title="PHP无法操作memcached提示Permission denied的解决方法">PHP无法操作memcached提示Permission denied的解决方法</a></li><li><a href="http://slj.me/2010/12/install-memcache-on-centos/" title="安装memcache到CentOS（另附yum法）">安装memcache到CentOS（另附yum法）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/03/21andy-centos-repo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>经典转载：程序员那些悲催的事儿</title>
		<link>http://slj.me/2011/03/confessions-of-your-worst-wtf-moment/</link>
		<comments>http://slj.me/2011/03/confessions-of-your-worst-wtf-moment/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 07:20:18 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[life]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2196</guid>
		<description><![CDATA[今天公司的大力同学推荐了一篇很经典的文章，就转载了。正文如下： 在StakeOverflow上有这样一个贴子叫“Confessions of your worst WTF moment”（WTF就是What the fuck的缩写），挺有意思的，我摘几个小故事过来，希望大家在笑过之后能从中学到什么——所有的经验都是从错误中来的（我在其中加了一些点评） 我们公司的软件是给警察局用的，那是一个对用来处理被逮捕的人的系统，此系统还需要收集脸部特征和指纹信息，并且，这个系 统和会向FBI的系统提交这些信息。当我们在测试这个系统的时候，我们一般都是用我们自己的指纹，当然，数据库联着的是我们的测试数据库。不过，有一次， 在我们测试完后，我们忘了把系统切换回生产库，于是我们的测试数据库就联上了生产环境，于是我们的指纹信息和照片就散布到了其它系统中……清除我们警察局 这边的还好办，但是，你需要波士顿警察局警司去法院签字才能从FBI的数据库中清除我们的信息。 点评：测试环境和生产环境的数据不要混在一起。 有一次，我需要向新系统中导入一堆数据，因为数据量太大，需要5个小时，只能在夜里来干，在系统需要正式使用前2个小时， 数据导完了，此时是凌晨4点。随后，我需要删除一些数据，于是我在SQL命令地上输入了“DELETE from important_table; where id=4”。是的，我没有看到哪里还有个分号，天啊。 点评：这就是加班工作的恶果。另，在delete之前最好先做一次select。 我把我的管理员口令提交到了一个开源软件的源码里。 点评：1）版本管理器里的东西是删不掉的。2）一些用户和口令要hard code在代码里，所以，不要混用代码使用的权限和管理员的权限，小心管理程序的运行权限，为其注册专门的用户。 我为一个很大的银行开发软件，在我的代码里，我为一段理论上根本不可能执行到的代码加了一个报错信息。有一天，不可思异的 事发生了，这条报错信息显示在了该银行的1800个分行的超过10000个终端上——“如果你看到这个信息，说明整个系统被Fuck了，回家吧，祝你过得 愉快！” 点评：“假设是恶魔”，Assume意为Ass – u – me，意为——搞砸你和我。对于一些关键东西，永远不要做假设。小心你言语中的——“可能、应该、觉得、不应该”等词语，程序可不认这些东西。 我远程登录到服务器上加几个防火墙规则。第一件我想干的事是在不允许任何人的任何连接，第二件是，为某个端口打开访问权限。不过，我在做完第一件事后就把配置保存了，结果其生效了…… 点评：这样的事经常发生，做远程网络管理的人多少会有那么几次发生这样的错误。在你将你的网络配置生效前，你得想一想，断线了你是否还能登得上去。改配置不要太冲动，生效前检查几次。 我们的代码中有一个模块完美地工作了很多年了，只是代码太乱了。我说服了我的老板，我可以重写这个模块，于是我花了三个星 期来重写这个模块。今天 ，我还记得，我的老板站在我的后面看着我，而我在在流着斗大的法汗珠去fix被我重写的“超级漂亮”的那个模块中一个接一个的bug。从那以后，我再也不 重写代码了，除非有重大的利益。 点评：这就所谓的屠宰式编程。这个案例告诉我们两个道理，1）维护代码要用最最最保守的方法来进行。2）重构代码前要像一个商人一样学会计算利益。当然，ThoughtWorks的咨询师一定会告诉你TDD，结对，极限等等方法告诉你如果实践重构。但我想告诉你，一个程序在生产环境里运行好几个年能没有问题是一件很不容易的事，那怕其中的代码再烂，你再看不过去，你都要有一个清醒的头脑明白这几点，1）软件的运行质量是远远大于代码质量的，2）你的测试案例是远远小于生产环境的，3）软件的完美的质量，是靠长时间的运行、测试和错误堆出来的，而不是某种方法论。 ———————————————— 相信大家做程序员这一生中也有很多发生在自己身上的悲催的事儿，欢迎分享。我先分享几个我亲身经历过的事。 一个发生在我的领导身上。 我98年刚参加工作的时候，在某单位网络部门，一次，我们整个部门去给下属单位培训Cisco路由器，结果我们发现带去培 训地点的设备少带了集线器HUB，设备连不起来。于是领导很不高兴，质问我们为什么没有带集线器？那几个对领导平时就不满的老员工说办公室里没有集线器 了，都借给别的部门了。领导想了想，问我：“陈皓，我记得上次我给过你个集线器”，我说，“好像没有吧，我记不起来了，什么牌的？几口的？”，领导说： “什么牌子想不起来了，不过我记得那个集线器是一个口的”。“一个口的？！”，我心里嘀咕着，“真敢说啊”。但我不敢接话了。那几个老员工来劲了——“哪有一个口的HUB啊，一个口的怎么联两台电脑啊？”，领导说：“用两个一个口的不就行了”。领导这话一出，全场一片寂静，无言以对…… 后来：我们所有的组员都离开了我们的这个领导，我们的这个领导今天还在那里工作。我想告诉大家，很多时候该走的是领导（包括外企，我上一东家正在裁人，不过我觉得该被裁掉的应该是那些经理）。我们的领导经常出这样或那样的笑话，这让我随时随地地警醒自己——“不要当一个被人笑话的经理”，于是，今天我还在努力地学习技术。 另一个发生在我身上 刚刚接触Linux的时候，还不是很懂，那时的PC还只有奔3，编译公司的程序好慢啊，有时候为了调查一个问题，需要不断 地打log，来来回回地编译，很不爽。直到有一天，硬盘不够了，df一下，发现/dev/shm还有空间。于是，把全部程序copy了过去，发现编译起程 序超快无比，爽得不行。于是就把工作环境放在/dev/shm下了，连开发都放在这里了。这一天，开发一个功能，改了十来个文件，加班很晚，觉得基本搞 定，大喜，回家睡觉。第二天一来，发现/dev/shm下空了，一个文件都没有了，问同事，同事不知，同事还安慰我说，上次他的文件也不知道被 谁删了，于是我大怒，告老板！老板也怒，发邮件到整个公司质问大家谁删了陈皓的程序，无人应答。IT部门答，“昨晚唯一的操作就是重启了linux服务 器，什么也没干，不过我们天天备份服务器，可以恢复”，IT部门问我丢的文件在哪个目录下？于是，我reply to [...]]]></description>
			<content:encoded><![CDATA[<p>今天公司的大力同学推荐了一篇很经典的文章，就转载了。正文如下：</p>
<p>在StakeOverflow上有这样一个贴子叫“<a href="http://stackoverflow.com/questions/63668/confessions-of-your-worst-wtf-moment" rel="external nofollow">Confessions of your worst WTF moment</a>”（WTF就是What the fuck的缩写），挺有意思的，我摘几个小故事过来，希望大家在笑过之后能从中学到什么——所有的经验都是从错误中来的（我在其中加了一些点评）</p>
<p>我们公司的软件是给警察局用的，那是一个对用来处理被逮捕的人的系统，此系统还需要收集脸部特征和指纹信息，并且，这个系 统和会向FBI的系统提交这些信息。当我们在测试这个系统的时候，我们一般都是用我们自己的指纹，当然，数据库联着的是我们的测试数据库。不过，有一次， 在我们测试完后，我们忘了把系统切换回生产库，于是我们的测试数据库就联上了生产环境，于是我们的指纹信息和照片就散布到了其它系统中……清除我们警察局 这边的还好办，但是，你需要波士顿警察局警司去法院签字才能从FBI的数据库中清除我们的信息。<br />
<span id="more-2196"></span></p>
<blockquote><p>点评：测试环境和生产环境的数据不要混在一起。</p></blockquote>
<p>有一次，我需要向新系统中导入一堆数据，因为数据量太大，需要5个小时，只能在夜里来干，在系统需要正式使用前2个小时， 数据导完了，此时是凌晨4点。随后，我需要删除一些数据，于是我在SQL命令地上输入了“DELETE from important_table; where id=4”。是的，我没有看到哪里还有个分号，天啊。</p>
<blockquote><p>点评：这就是加班工作的恶果。另，在delete之前最好先做一次select。</p></blockquote>
<p>我把我的管理员口令提交到了一个开源软件的源码里。</p>
<blockquote><p>点评：1）版本管理器里的东西是删不掉的。2）一些用户和口令要hard code在代码里，所以，不要混用代码使用的权限和管理员的权限，小心管理程序的运行权限，为其注册专门的用户。</p></blockquote>
<p>我为一个很大的银行开发软件，在我的代码里，我为一段理论上根本不可能执行到的代码加了一个报错信息。有一天，不可思异的 事发生了，这条报错信息显示在了该银行的1800个分行的超过10000个终端上——“如果你看到这个信息，说明整个系统被Fuck了，回家吧，祝你过得 愉快！”</p>
<blockquote><p>点评：“假设是恶魔”，Assume意为Ass – u – me，意为——搞砸你和我。对于一些关键东西，永远不要做假设。小心你言语中的——“可能、应该、觉得、不应该”等词语，程序可不认这些东西。</p></blockquote>
<p>我远程登录到服务器上加几个防火墙规则。第一件我想干的事是在不允许任何人的任何连接，第二件是，为某个端口打开访问权限。不过，我在做完第一件事后就把配置保存了，结果其生效了……</p>
<blockquote><p>点评：这样的事经常发生，做远程网络管理的人多少会有那么几次发生这样的错误。在你将你的网络配置生效前，你得想一想，断线了你是否还能登得上去。改配置不要太冲动，生效前检查几次。</p></blockquote>
<p>我们的代码中有一个模块完美地工作了很多年了，只是代码太乱了。我说服了我的老板，我可以重写这个模块，于是我花了三个星 期来重写这个模块。今天 ，我还记得，我的老板站在我的后面看着我，而我在在流着斗大的法汗珠去fix被我重写的“超级漂亮”的那个模块中一个接一个的bug。从那以后，我再也不 重写代码了，除非有重大的利益。</p>
<blockquote><p>点评：这就所谓的屠宰式编程。这个案例告诉我们两个道理，1）维护代码要用最最最保守的方法来进行。2）重构代码前要像一个商人一样学会计算利益。当然，<a href="http://coolshell.cn/articles/3745.html" rel="external nofollow">ThoughtWorks的咨询师</a>一定会告诉你TDD，结对，极限等等方法告诉你如果实践重构。但我想告诉你，一个程序在生产环境里运行好几个年能没有问题是一件很不容易的事，那怕其中的代码再烂，你再看不过去，你都要有一个清醒的头脑明白这几点，1）软件的运行质量是远远大于代码质量的，2）你的测试案例是远远小于生产环境的，3）软件的完美的质量，是靠长时间的运行、测试和错误堆出来的，而不是某种方法论。</p></blockquote>
<p>————————————————</p>
<p>相信大家做程序员这一生中也有很多发生在自己身上的悲催的事儿，欢迎分享。我先分享几个我亲身经历过的事。</p>
<p>一个发生在我的领导身上。</p>
<p>我98年刚参加工作的时候，在某单位网络部门，一次，我们整个部门去给下属单位培训Cisco路由器，结果我们发现带去培 训地点的设备少带了集线器HUB，设备连不起来。于是领导很不高兴，质问我们为什么没有带集线器？那几个对领导平时就不满的老员工说办公室里没有集线器 了，都借给别的部门了。领导想了想，问我：“陈皓，我记得上次我给过你个集线器”，我说，“好像没有吧，我记不起来了，什么牌的？几口的？”，领导说： “什么牌子想不起来了，不过我记得那个集线器是一个口的”。“一个口的？！”，我心里嘀咕着，“真敢说啊”。但我不敢接话了。那几个老员工来劲了——“哪有一个口的HUB啊，一个口的怎么联两台电脑啊？”，领导说：“用两个一个口的不就行了”。领导这话一出，全场一片寂静，无言以对……</p>
<blockquote><p>后来：我们所有的组员都离开了我们的这个领导，我们的这个领导今天还在那里工作。我想告诉大家，很多时候该走的是领导（包括外企，我上一东家正在裁人，不过我觉得该被裁掉的应该是那些经理）。我们的领导经常出这样或那样的笑话，这让我随时随地地警醒自己——“不要当一个被人笑话的经理”，于是，今天我还在努力地学习技术。</p></blockquote>
<p>另一个发生在我身上</p>
<p>刚刚接触Linux的时候，还不是很懂，那时的PC还只有奔3，编译公司的程序好慢啊，有时候为了调查一个问题，需要不断 地打log，来来回回地编译，很不爽。直到有一天，硬盘不够了，df一下，发现/dev/shm还有空间。于是，把全部程序copy了过去，发现编译起程 序超快无比，爽得不行。于是就把工作环境放在/dev/shm下了，连开发都放在这里了。这一天，开发一个功能，改了十来个文件，加班很晚，觉得基本搞 定，大喜，回家睡觉。第二天一来，发现/dev/shm下空了，一个文件都没有了，问同事，同事不知，同事还安慰我说，上次他的文件也不知道被 谁删了，于是我大怒，告老板！老板也怒，发邮件到整个公司质问大家谁删了陈皓的程序，无人应答。IT部门答，“昨晚唯一的操作就是重启了linux服务 器，什么也没干，不过我们天天备份服务器，可以恢复”，IT部门问我丢的文件在哪个目录下？于是，我reply to all – “在/dev/shm下……”，哎，人丢大发了……</p>
<blockquote><p>后来：我很感谢我以前犯的这个错，从那天以后，我开始立志学好Linux，这个错误让我努力，让我发奋。所以，我想告诉大家——尤其是刚出道的程序员，你们要多多犯错，要犯错那种丢死人的错，这样你才会知耻而勇。</p></blockquote>
<p>再来一个发生在我同事身上的</p>
<p>01年，我们开发银行系统，在AIX上开发，RICS6000很贵，只能在客户那里开发，开发进度很紧张，慢慢地硬盘就不 够用了，系统中有大量的垃圾文件，于是需要清除一些文件，于是有一个同事写了一个脚本，可以自动清除的各种不重要的文件，里面有一条命令大致是这个样子“ rm -rf ${app_log_dir}/*”，意为清除程序运行的日志。为了使用这个脚本，需要在root用户下运行，一开始还不错。直到有一天，某人一运行，整 个根就没了。搞得整个团队只能用一周前的备份重写已写好的代码。后来，才发现原因是${app_log_dir}变量为空，于是成了“rm -rf /*”……</p>
<blockquote><p>后来：这个事后，我的那个同事，把rm命令改了名，并自己写了一个rm命令，把删除的文件先放到一个临时目录下。而我也因为这个事情，到今天，每次当我在root目录下使用rm时，敲击回车的手都是抖的。（另，rm时永远使用绝对路径）这里，我想告诉大家——犯错不可怕，可怕的是不会从中总结教训，同一个错犯两次。</p></blockquote>
<p>欢迎分享发生在你身上那些悲催的事。</p>
<h2  class="related_post_title">Other Posts / 其他文章</h2><ul class="related_post"><li><a href="http://slj.me/2009/05/scalable-inman-flash-replacement/" title="谈谈sIFR &#8211; 可伸缩Inman Flash替换">谈谈sIFR &#8211; 可伸缩Inman Flash替换</a></li><li><a href="http://slj.me/2009/06/css-tutorial-resource/" title="【经典】CSS技巧教程资源大全">【经典】CSS技巧教程资源大全</a></li><li><a href="http://slj.me/2011/04/redis-cli-commands/" title="[Redis] redis-cli 命令总结">[Redis] redis-cli 命令总结</a></li><li><a href="http://slj.me/2010/12/redis-misunderstood/" title="[转] Redis几个认识误区">[转] Redis几个认识误区</a></li><li><a href="http://slj.me/2009/07/javascript-%e5%9b%be%e7%89%87%e5%88%87%e5%89%b2%e6%95%88%e6%9e%9c/" title="JavaScript 图片切割效果 ">JavaScript 图片切割效果 </a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/03/confessions-of-your-worst-wtf-moment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>分享两则我在VPS上执行的sh脚本</title>
		<link>http://slj.me/2011/03/share-bash-script/</link>
		<comments>http://slj.me/2011/03/share-bash-script/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 06:45:51 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Web Structure]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[crontab]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2189</guid>
		<description><![CDATA[自从有了VPS，感觉自由多了。今天整理东西，分享两则我用在自己vps上自我感觉实用的sh脚本。 第一则的效果是，每当有用户登录服务器的ssh，就会发邮件到特定邮箱通知 第二则是穷人用的，没有钱买备份服务怎么办？那就申请一个免费的svn服务，我的是在unfuddle上。设置cron每日执行一次mysqldump并commit到svn库上去。出了问题手工去库里拣来恢复就是了。 &#160; 第一则：登录ssh后自动发提醒邮件 在/etc/bashrc文件中添加 存有以下脚本的可执行权限的文件的地址。 #!/bin/sh sendmail -t &#62;/dev/null 2&#62;&#38;1 &#60;&#60;EOF To: 接本邮件的地址@domain.com From: 随便@domain.com Subject:$USER@`hostname` login from ${SSH_CLIENT%% *} EOF 第二则：每日自动备份MySQL中全部数据库并同步到svn库中实现异地拥有版本库的备份 进 crontab -e 添加 存有以下脚本的可执行权限的文件的地址。 #!/bin/sh db_user=&#8221;root&#8221; db_passwd=&#8221;你的数据库密码&#8221; db_host=&#8221;localhost&#8221; backup_dir=&#8221;/var/备份文件存放目录带斜杠/&#8221; MYSQL=&#8221;$(which &#8211;skip-alias mysql)&#8221; MYSQLDUMP=&#8221;$(which &#8211;skip-alias mysqldump)&#8221; SVN=&#8221;$(which &#8211;skip-alias svn)&#8221; test ! -w $backup_dir &#38;&#38; echo &#8220;Error: $backup_dir is un-writeable.&#8221; &#38;&#38; exit [...]]]></description>
			<content:encoded><![CDATA[<p>自从有了VPS，感觉自由多了。今天整理东西，分享两则我用在自己vps上自我感觉实用的sh脚本。</p>
<p>第一则的效果是，每当有用户登录服务器的ssh，就会发邮件到特定邮箱通知</p>
<p>第二则是穷人用的，没有钱买备份服务怎么办？那就申请一个免费的svn服务，我的是在unfuddle上。设置cron每日执行一次mysqldump并commit到svn库上去。出了问题手工去库里拣来恢复就是了。</p>
<p>&nbsp;</p>
<h3>第一则：登录ssh后自动发提醒邮件</h3>
<p>在/etc/bashrc文件中添加 存有以下脚本的可执行权限的文件的地址。</p>
<blockquote><p>#!/bin/sh</p>
<p>sendmail -t &gt;/dev/null 2&gt;&amp;1 &lt;&lt;EOF</p>
<p>To: 接本邮件的地址@domain.com</p>
<p>From: 随便@domain.com</p>
<p>Subject:$USER@`hostname` login from ${SSH_CLIENT%% *}</p>
<p>EOF</p></blockquote>
<h3>第二则：每日自动备份MySQL中全部数据库并同步到svn库中实现异地拥有版本库的备份</h3>
<p>进 crontab -e 添加 存有以下脚本的可执行权限的文件的地址。</p>
<p><span id="more-2189"></span></p>
<blockquote><p>#!/bin/sh</p>
<p>db_user=&#8221;root&#8221;</p>
<p>db_passwd=&#8221;你的数据库密码&#8221;</p>
<p>db_host=&#8221;localhost&#8221;</p>
<p>backup_dir=&#8221;/var/备份文件存放目录带斜杠/&#8221;</p>
<p>MYSQL=&#8221;$(which &#8211;skip-alias mysql)&#8221;</p>
<p>MYSQLDUMP=&#8221;$(which &#8211;skip-alias mysqldump)&#8221;</p>
<p>SVN=&#8221;$(which &#8211;skip-alias svn)&#8221;</p>
<p>test ! -w $backup_dir &amp;&amp; echo &#8220;Error: $backup_dir is un-writeable.&#8221; &amp;&amp; exit 0</p>
<p>all_db=&#8221;$($MYSQL -u $db_user -h $db_host -p$db_passwd -Bse &#8216;show databases&#8217;)&#8221;</p>
<p>for db in $all_db</p>
<p>do</p>
<p>$MYSQLDUMP -u $db_user -h $db_host -p$db_passwd $db &gt; &#8220;$backup_dir/$db.sql&#8221;</p>
<p>done</p>
<p>$SVN add &#8220;$backup_dir&#8221;/*</p>
<p>$SVN ci -m &#8220;mysqldump&#8221; $backup_dir</p>
<p>exit 0;</p></blockquote>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/10/mysql-save-query-result-to-a-file/" title="MySQL 把查询结果保存到文件中的方法">MySQL 把查询结果保存到文件中的方法</a></li><li><a href="http://slj.me/2011/06/php-daemon-notice/" title="[转] 代替bash，书写 PHP daemon 后台程序">[转] 代替bash，书写 PHP daemon 后台程序</a></li><li><a href="http://slj.me/2011/04/introduce-to-scplugin/" title="SCPlugin &#8211; 在MacOS下像Windows中TortoiseSVN一样来操作SVN">SCPlugin &#8211; 在MacOS下像Windows中TortoiseSVN一样来操作SVN</a></li><li><a href="http://slj.me/2011/03/mysql-replication-master-slave/" title="总结: MySQL主从复制 &#8211; MySQL Replication">总结: MySQL主从复制 &#8211; MySQL Replication</a></li><li><a href="http://slj.me/2010/12/find-out-slow-query-in-mysql/" title="找出 MySQL 里哪些查询 Query 速度较慢">找出 MySQL 里哪些查询 Query 速度较慢</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/03/share-bash-script/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>总结: MySQL主从复制 &#8211; MySQL Replication</title>
		<link>http://slj.me/2011/03/mysql-replication-master-slave/</link>
		<comments>http://slj.me/2011/03/mysql-replication-master-slave/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 14:14:49 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[master]]></category>
		<category><![CDATA[replication]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2180</guid>
		<description><![CDATA[记： 最近在测试MySQL在高并发下连接失败的方法。在修改 max_connections 等等的方法后没有本质的提升，在PHP中的连接方法尝试retry也没有明显提升，用多个实例来分摊其实也是在同一个机器上抢占资源。只能从硬件方面学习了。一个有效的解决方法就是MySQL的主从replication. 在咨询过羽同学后得出以下结论：从服务器会异步从主服务器单向同步数据。update，insert等操作应在主服务器上进行。对于生产环境中实时性比较高的select操作应在主服务器上执行，其他select操作都在从服务器上进行。 &#160; ==下面是转载== MySQL支持单向、异步复制，复制过程中一个服务器充当主服务器，而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件，并维护日志文件的一个索引以跟踪日志循环。当一个从服务器连接到主服务器时，它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新，然后封锁并等待主服务器通知下一次更新。 为什么使用主从复制？ 1、主服务器/从服务器设置增加了健壮性。主服务器出现问题时，你可以切换到从服务器作为备份。 2、通过在主服务器和从服务器之间切分处理客户查询的负荷，可以得到更好的客户响应时间。但是不要同时在主从服务器上进行更新，这样可能引起冲突。 3、使用复制的另一个好处是可以使用一个从服务器执行备份，而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。 MySQL使用3个线程来执行复制功能(其中1个在主服务器上，另两个在从服务器上。当发出START SLAVE时，从服务器创建一个I/O线程，以连接主服务器并让主服务器发送二进制日志。主服务器创建一个线程将二进制日志中的内容发送到从服务器。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中，即中继日志。第3个线程是SQL线程，从服务器使用此线程读取中继日志并执行日志中包含的更新。SHOW PROCESSLIST语句可以查询在主服务器上和从服务器上发生的关于复制的信息。 默认中继日志使用host_name-relay-bin.nnnnnn形式的文件名，其中host_name是从服务器主机名，nnnnnn是序列号。用连续序列号来创建连续中继日志文件，从000001开始。从服务器跟踪中继日志索引文件来识别目前正使用的中继日志。默认中继日志索引文件名为host_name-relay-bin.index。在默认情况，这些文件在从服务器的数据目录中被创建。中继日志与二进制日志的格式相同，并且可以用mysqlbinlog读取。当SQL线程执行完中继日志中的所有事件后，中继日志将会被自动删除。 从服务器在数据目录中另外创建两个状态文件&#8211;master.info和relay-log.info。状态文件保存在硬盘上，从服务器关闭时不会丢失。下次从服务器启动时，读取这些文件以确定它已经从主服务器读取了多少二进制日志，以及处理自己的中继日志的程度。 设置主从复制： 1、确保在主服务器和从服务器上安装的MySQL版本相同，并且最好是MySQL的最新稳定版本。 2、在主服务器上为复制设置一个连接账户。该账户必须授予REPLICATION SLAVE权限。如果账户仅用于复制(推荐这样做)，则不需要再授予任何其它权限。 mysql&#62; GRANT REPLICATION SLAVE ON *.* -&#62; TO &#8216;replication&#8217;@'%.yourdomain.com&#8217; IDENTIFIED BY &#8216;slavepass&#8217;; 3、执行FLUSH TABLES WITH READ LOCK语句清空所有表和块写入语句： mysql&#62; FLUSH TABLES WITH READ LOCK； 保持mysql客户端程序不要退出。开启另一个终端对主服务器数据目录做快照。 shell&#62; cd /usr/local/mysql/ shell&#62; tar -cvf /tmp/mysql-snapshot.tar ./data 如果从服务器的用户账户与主服务器的不同，你可能不想复制mysql数据库。在这种情况下，应从归档中排除该数据库。你也不需要在归档中包括任何日志文件或者master.info或relay-log.info文件。 [...]]]></description>
			<content:encoded><![CDATA[<h3>记：</h3>
<p>最近在测试MySQL在高并发下连接失败的方法。在修改 max_connections 等等的方法后没有本质的提升，在PHP中的连接方法尝试retry也没有明显提升，用多个实例来分摊其实也是在同一个机器上抢占资源。只能从硬件方面学习了。一个有效的解决方法就是MySQL的主从replication.</p>
<p>在咨询过羽同学后得出以下结论：从服务器会异步从主服务器单向同步数据。update，insert等操作应在主服务器上进行。对于生产环境中实时性比较高的select操作应在主服务器上执行，其他select操作都在从服务器上进行。</p>
<p>&nbsp;</p>
<h3>==下面是转载==</h3>
<p>MySQL支持单向、异步复制，复制过程中一个服务器充当主服务器，而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件，并维护日志文件的一个索引以跟踪日志循环。当一个从服务器连接到主服务器时，它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新，然后封锁并等待主服务器通知下一次更新。<br />
<span id="more-2180"></span></p>
<h3>为什么使用主从复制？</h3>
<p>1、主服务器/从服务器设置增加了健壮性。主服务器出现问题时，你可以切换到从服务器作为备份。</p>
<p>2、通过在主服务器和从服务器之间切分处理客户查询的负荷，可以得到更好的客户响应时间。但是不要同时在主从服务器上进行更新，这样可能引起冲突。</p>
<p>3、使用复制的另一个好处是可以使用一个从服务器执行备份，而不会干扰主服务器。在备份过程中主服务器可以继续处理更新。</p>
<p>MySQL使用3个线程来执行复制功能(其中1个在主服务器上，另两个在从服务器上。当发出START SLAVE时，从服务器创建一个I/O线程，以连接主服务器并让主服务器发送二进制日志。主服务器创建一个线程将二进制日志中的内容发送到从服务器。从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中，即中继日志。第3个线程是SQL线程，从服务器使用此线程读取中继日志并执行日志中包含的更新。SHOW PROCESSLIST语句可以查询在主服务器上和从服务器上发生的关于复制的信息。</p>
<p>默认中继日志使用host_name-relay-bin.nnnnnn形式的文件名，其中host_name是从服务器主机名，nnnnnn是序列号。用连续序列号来创建连续中继日志文件，从000001开始。从服务器跟踪中继日志索引文件来识别目前正使用的中继日志。默认中继日志索引文件名为host_name-relay-bin.index。在默认情况，这些文件在从服务器的数据目录中被创建。中继日志与二进制日志的格式相同，并且可以用mysqlbinlog读取。当SQL线程执行完中继日志中的所有事件后，中继日志将会被自动删除。</p>
<p>从服务器在数据目录中另外创建两个状态文件&#8211;master.info和relay-log.info。状态文件保存在硬盘上，从服务器关闭时不会丢失。下次从服务器启动时，读取这些文件以确定它已经从主服务器读取了多少二进制日志，以及处理自己的中继日志的程度。</p>
<h3>设置主从复制：</h3>
<p>1、确保在主服务器和从服务器上安装的MySQL版本相同，并且最好是MySQL的最新稳定版本。</p>
<p>2、在主服务器上为复制设置一个连接账户。该账户必须授予REPLICATION SLAVE权限。如果账户仅用于复制(推荐这样做)，则不需要再授予任何其它权限。</p>
<p>mysql&gt; GRANT REPLICATION SLAVE ON *.*</p>
<p>-&gt; TO &#8216;replication&#8217;@'%.yourdomain.com&#8217; IDENTIFIED BY &#8216;slavepass&#8217;;</p>
<p>3、执行FLUSH TABLES WITH READ LOCK语句清空所有表和块写入语句：</p>
<p>mysql&gt; FLUSH TABLES WITH READ LOCK；</p>
<p>保持mysql客户端程序不要退出。开启另一个终端对主服务器数据目录做快照。</p>
<p>shell&gt; cd /usr/local/mysql/</p>
<p>shell&gt; tar -cvf /tmp/mysql-snapshot.tar ./data</p>
<p>如果从服务器的用户账户与主服务器的不同，你可能不想复制mysql数据库。在这种情况下，应从归档中排除该数据库。你也不需要在归档中包括任何日志文件或者master.info或relay-log.info文件。</p>
<p>当FLUSH TABLES WITH READ LOCK所置读锁定有效时（即mysql客户端程序不退出)，读取主服务器上当前的二进制日志名和偏移量值：</p>
<p>mysql &gt; SHOW MASTER STATUS;</p>
<p>+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+</p>
<p>| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |</p>
<p>+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+</p>
<p>| mysql-bin.003 | 73       | test         | manual,mysql     |</p>
<p>+&#8212;&#8212;&#8212;&#8212;&#8212;+&#8212;&#8212;&#8212;-+&#8212;&#8212;&#8212;&#8212;&#8211;+&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;+</p>
<p>File列显示日志名，而Position显示偏移量。在该例子中，二进制日志值为mysql-bin.003，偏移量为73。记录该值。以后设置从服务器时需要使用这些值。它们表示复制坐标，从服务器应从该点开始从主服务器上进行新的更新。</p>
<p>如果主服务器运行时没有启用&#8211;logs-bin，SHOW MASTER STATUS显示的日志名和位置值为空。在这种情况下，当以后指定从服务器的日志文件和位置时需要使用的值为空字符串(&#8221;)和4.</p>
<p>取得快照并记录日志名和偏移量后，回到前一中端重新启用写活动：</p>
<p>mysql&gt; UNLOCK TABLES；</p>
<p>4、确保主服务器主机上my.cnf文件的[mysqld]部分包括一个log-bin选项。该部分还应有一个server-id=Master_id选项，其中master_id必须为1到232–1之间的一个正整数值。例如：</p>
<p>[mysqld]</p>
<p>log-bin</p>
<p>server-id=1</p>
<p>如果没有提供那些选项，应添加它们并重启服务器。</p>
<p>5、停止从服务器上的mysqld服务并在其my.cnf文件中添加下面的行：</p>
<p>[mysqld]</p>
<p>server-id=2</p>
<p>slave_id值同Master_id值一样，必须为1到232–1之间的一个正整数值。并且，从服务器的ID必须与主服务器的ID不相同。</p>
<p>6、将数据备据目录中。确保对这些文件和目录的权限正确。服务器 MySQL运行的用户必须能够读写文件，如同在主服务器上一样。</p>
<p>Shell&gt; chown -R mysql:mysql /usr/local/mysql/data</p>
<p>7、启动从服务器。在从服务器上执行下面的语句，用你的系统的实际值替换选项值：</p>
<pre>        mysql&gt; CHANGE MASTER TO

            -&gt; MASTER_HOST='master_host_name',

            -&gt; MASTER_USER='replication_user_name',

            -&gt; MASTER_PASSWORD='replication_password',

            -&gt; MASTER_LOG_FILE='recorded_log_file_name',

            -&gt; MASTER_LOG_POS=recorded_log_position;</pre>
<p>8、启动从服务器线程：</p>
<pre>        mysql&gt; START SLAVE；</pre>
<p>执行这些程序后，从服务器应连接主服务器，并补充自从快照以来发生的任何更新。</p>
<p>9、如果出现复制错误，从服务器的错误日志（HOSTNAME.err）中也会出现错误消息。</p>
<p>10、从服务器复制时，会在其数据目录中发现文件master.info和HOSTNAME- relay-log.info。从服务器使用这两个文件跟踪已经处理了多少主服务器的二进制日志。不要移除或编辑这些文件，除非你确切知你正在做什么并完全理解其意义。即使这样，最好是使用CHANGE MASTER TO语句。</p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/10/mysql-save-query-result-to-a-file/" title="MySQL 把查询结果保存到文件中的方法">MySQL 把查询结果保存到文件中的方法</a></li><li><a href="http://slj.me/2011/03/share-bash-script/" title="分享两则我在VPS上执行的sh脚本">分享两则我在VPS上执行的sh脚本</a></li><li><a href="http://slj.me/2010/12/find-out-slow-query-in-mysql/" title="找出 MySQL 里哪些查询 Query 速度较慢">找出 MySQL 里哪些查询 Query 速度较慢</a></li><li><a href="http://slj.me/2010/04/mysql-group-by-having/" title="MySQL: group by &#8230; having &#8230;">MySQL: group by &#8230; having &#8230;</a></li><li><a href="http://slj.me/2010/01/mysql%e5%8f%96%e6%95%b4%e5%87%bd%e6%95%b0/" title="MySql取整函数">MySql取整函数</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/03/mysql-replication-master-slave/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>转: 10款iOS高效开发必备的Objective-C类库</title>
		<link>http://slj.me/2011/03/10-essential-efficient-object-c-library/</link>
		<comments>http://slj.me/2011/03/10-essential-efficient-object-c-library/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 13:17:05 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[iPhone/Android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[objective c]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2174</guid>
		<description><![CDATA[因为iOS SDK相对比较底层，所以开发者就得受累多做一些体力活。不过幸运的是，有很多第三方的类库可以用来简化很多不必要的工作.经过作者团队的慎重讨论，他们 评选出了10款能够极大提高iOS开发效率的类库，根据原文作者的评价来看，基本上有了这10款工具，做iOS开发就真的跟泡Cocoa一样了。 MBProgressHUD——进展指示符库 苹果的应用程序一般都会用一种优雅的，半透明的进度显示效果，不过这个API是不公开的，因此你要是用了，很可能被清除出AppStore。而 MBProgressHUD提供了一个替代方案，而且在用户角度上，实现的效果根本看不出和官方程序有什么差别。同时还提供了其他附加功能，比如虚拟进展 指示符，以及完成提示信息。整合到项目里也很容易，这里不细谈了。 ASIHttpRequest——HTTP Network库 iPhone当然也有自己的HTTP Network API，那为什么要用ASIHttpRequest呢？因为官方的API简直跟话痨似的，太罗嗦了！ASIHttpRequest库极大的简化了网络通 信，提供更先进的工具，什么文件上传工具，重定向处理工具、验证工具、等等。只要你手头的东西跟HTTP有关，用这个绝对能让你感觉道生活有美好！先看一 段代码就体会到了。 (void) loadAppDevMag { NSURL *url = [NSURL URLWithString:@"http://www.appdevmag.com"]; ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; [request setDelegate:self]; [request startAsynchronous]; } - (void)requestFinished:(ASIHTTPRequest *)request { // Use when fetching text data NSString *responseString = [request responseString]; } JSON Framework——JSON支持 如果你做的应用和网站服务器有交互，那就得用到JSON了。但事实上，iOS平台的原生类库根本就不支持JSON，这就略犀利了吧？不过JSON框 架满足了你的所有需求，包括一个解析器将JSON字符串解析成对象；以及一个生成器从对象生成字符串。这个库根本就是太流行了，JSON提过很多次了，具 体特点就不多讲了，所谓“一段代码胜千言”，下面用一段代码演示一下吧。 // JSON [...]]]></description>
			<content:encoded><![CDATA[<p>因为iOS   SDK相对比较底层，所以开发者就得受累多做一些体力活。不过幸运的是，有很多第三方的类库可以用来简化很多不必要的工作.经过作者团队的慎重讨论，他们  评选出了10款能够极大提高iOS开发效率的类库，根据原文作者的评价来看，基本上有了这10款工具，做iOS开发就真的跟泡Cocoa一样了。</p>
<p><a href="http://github.com/jdg/MBProgressHUD" target="_blank"><strong>MBProgressHUD</strong></a><strong>——进展指示符库</strong></p>
<p>苹果的应用程序一般都会用一种优雅的，半透明的进度显示效果，不过这个API是不公开的，因此你要是用了，很可能被清除出AppStore。而  MBProgressHUD提供了一个替代方案，而且在用户角度上，实现的效果根本看不出和官方程序有什么差别。同时还提供了其他附加功能，比如虚拟进展  指示符，以及完成提示信息。整合到项目里也很容易，这里不细谈了。</p>
<p><span id="more-2174"></span><a href="http://allseeing-i.com/ASIHTTPRequest/" target="_blank"><strong>ASIHttpRequest</strong></a><strong>——HTTP Network库</strong></p>
<p>iPhone当然也有自己的HTTP Network   API，那为什么要用ASIHttpRequest呢？因为官方的API简直跟话痨似的，太罗嗦了！ASIHttpRequest库极大的简化了网络通  信，提供更先进的工具，什么文件上传工具，重定向处理工具、验证工具、等等。只要你手头的东西跟HTTP有关，用这个绝对能让你感觉道生活有美好！先看一  段代码就体会到了。</p>
<pre class="c">(void) loadAppDevMag
{
NSURL *url = [NSURL URLWithString:@"http://www.appdevmag.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
}</pre>
<p><a href="http://github.com/stig/json-framework/" target="_blank"><strong>JSON Framework</strong></a><strong>——JSON支持</strong></p>
<p>如果你做的应用和网站服务器有交互，那就得用到JSON了。但事实上，iOS平台的原生类库根本就不支持JSON，这就略犀利了吧？不过JSON框   架满足了你的所有需求，包括一个解析器将JSON字符串解析成对象；以及一个生成器从对象生成字符串。这个库根本就是太流行了，JSON提过很多次了，具  体特点就不多讲了，所谓“一段代码胜千言”，下面用一段代码演示一下吧。</p>
<pre class="pre">// JSON string -&gt; NSDictionary
NSString *jsonString = @"{\"foo\": \"bar\"}";
NSDictionary *dictionary = [jsonString JSONValue];
NSLog(@"Dictionary value for \"foo\" is \"%@\"", [dictionary objectForKey:@"foo"]);
// NSDictionary -&gt; JSON string
NSString *newJsonString = [dictionary JSONRepresentation];</pre>
<p><a href="http://www.flurry.com/product/analytics/index.html"><strong>Flurry</strong></a><strong>——详尽的使用统计</strong></p>
<p>通过Furry你可以得到应用的用户人数，用户活跃度，用户来源等统计信息。但是他最厉害的地方是，你可以追踪应用本身的事件和错误记录，所有这些  数据都会在一个类似Google   Analytics的界面上显示，这样就很容易掌握用户的行为和出现的问题。当然，这个星球上很多统计工具，但是这款是作者个人比较推崇的解决方案。</p>
<div><img src="http://slj.me/wp-content/uploads/2011/03/8_110318140901_1.jpg" border="0" alt="" width="480" height="382" /></div>
<p><a href="http://regexkit.sourceforge.net/RegexKitLite/" target="_blank"><strong>RegexKitLite</strong></a><strong>——正则表达式支持</strong></p>
<p>正则表达式大家都知道。但是iPhone SDK居然当他不存在？这怎么能忍啊！果断用RegexKitLite。虽然叫的是Lite，但是功能很full。示例代码。</p>
<pre class="pre">// finds phone number in format nnn-nnn-nnnn
NSString *regEx = @"[0-9]{3}-[0-9]{3}-[0-9]{4}";
for(NSString *match in [textView.text componentsMatchedByRegex:regEx]) {
NSLog(@"Phone number is %@", match);
}</pre>
<p><a href="http://github.com/facebook/facebook-ios-sdk" target="_blank"><strong>Facebook iOS SDK</strong></a><strong>——Facebook API类库</strong></p>
<p>大体来讲就是iPhone上的Facebook login，完全支持Facebook Graph API和the older REST api。如果你的应用跟Facebook有关，相信我，用这个吧。</p>
<div><img src="http://slj.me/wp-content/uploads/2011/03/8_110318141824_1.png" border="0" alt="" width="200" height="300" /></div>
<p><a href="http://github.com/rs/SDWebImage" target="_blank"><strong>SDWebImage</strong></a><strong>——简化网络图片处理</strong></p>
<p>用SDWebImage调用网站上的图片，跟本地调用内置在应用包里的图片一样简单。操作也很简单，举例说明</p>
<p>[imageView setImageWithURL:[NSURL URLWithString:@&#8221;http://examp</p>
<p>类似的功能在Three20里也有，这个过会儿再说。相比而言，SDWebImage主要是提供一个小而精的简捷方便的解决方案</p>
<p><a href="http://code.google.com/p/gdata-objectivec-client/" target="_blank"><strong>GData client</strong></a><strong>——iPhone上所有Google相关服务的类库</strong></p>
<p>名字就说明一切了。跟Google相关的，值得一提的是，这个项目很开放。有很多示例程序供下载。</p>
<p><a href="http://code.google.com/p/core-plot/" target="_blank"><strong>CorePlot</strong></a><strong>——2D图形绘图仪</strong></p>
<p>CorePlot有很多解决方案将你的数据可视。，同时也会提供各种迷人的图形效果，比如棒状图、饼状图、线状图等等，在他们网站上也提供了大量的范例图形，很多股票价格应用，游戏分数，个人财务管理都在用。</p>
<p><a href="http://github.com/facebook/three20" target="_blank"><strong>Three20</strong></a><strong>——通用iOS库</strong></p>
<p>Three20类库是Facebook自己做的，大而全是他最大的特色。把他整合到已有的项目中可能得费点周折，不过如果一开始你就用上了Three20，尤其是牵扯到很多web相关的项目的时候，你就能深刻体会到神马叫给力了。</p>
<p>&nbsp;</p>
<div><img src="http://slj.me/wp-content/uploads/2011/03/8_110318142044_1.jpg" border="0" alt="" width="250" height="402" /></div>
<p><strong>转自 </strong><a href="http://mobile.csdn.net/a/20110317/294018.html" target="_blank"><strong>http://mobile.csdn.net/a/20110317/294018.html</strong></a></p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2010/11/ios-library-collection/" title="推荐几个经典 iOS 开源类库及工具">推荐几个经典 iOS 开源类库及工具</a></li><li><a href="http://slj.me/2010/10/debug-and-release-iphone-app/" title="如何联机调试和发布 iPhone App">如何联机调试和发布 iPhone App</a></li><li><a href="http://slj.me/2010/10/50-open-source-iphone-apps-for-iphone-developers/" title="50款经典iPhone开源应用及源码">50款经典iPhone开源应用及源码</a></li><li><a href="http://slj.me/2010/06/new-features-for-ios4/" title="iOS4 新特性简介">iOS4 新特性简介</a></li><li><a href="http://slj.me/2010/04/open-source-iphone-app-store-apps/" title="23个iPhone App Store中的开源App及其源码">23个iPhone App Store中的开源App及其源码</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/03/10-essential-efficient-object-c-library/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>博客顺利搬家linode，博客升级到wordpress3.1</title>
		<link>http://slj.me/2011/03/migrate-to-linode/</link>
		<comments>http://slj.me/2011/03/migrate-to-linode/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 14:11:22 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2157</guid>
		<description><![CDATA[昨天终于是买下了linode的VPS，今天把博客移过来，用nginx + mysql + memcache组合，无拘束的感觉真是爽，还通过slow query日志把那个虚拟主机上查不到的涉及慢查询统计插件给删了！同时也把wp给升级到了3.0，解决了一些BOM产生的markup错乱后，大家有没有觉得现在的速度比以前快很多呢？ PS，当然，vps要发挥最大用处，建了一个PPTP VPS给自己偶尔用以用，哈哈。 最近工作很忙，很久都没发博客了，有兴趣的同学倒可以follow me： 新浪围脖@申力军 由于某些不开心的经历已经结束了与美国的合作。 至于新计划，以后再公布吧。 Other Posts / 其他文章CSS Sprites 技巧 jQuery Rater Star Plugin投票打星星插件CSS在Internet Explorer 6, 7 和8中的差别Base64 javascript encode decode 另一种不错的方法注册漏嘴网]]></description>
			<content:encoded><![CDATA[<p>昨天终于是买下了linode的VPS，今天把博客移过来，用nginx + mysql + memcache组合，无拘束的感觉真是爽，还通过slow query日志把那个虚拟主机上查不到的涉及慢查询统计插件给删了！同时也把wp给升级到了3.0，解决了一些BOM产生的markup错乱后，大家有没有觉得现在的速度比以前快很多呢？</p>
<p>PS，当然，vps要发挥最大用处，建了一个PPTP VPS给自己偶尔用以用，哈哈。</p>
<p>最近工作很忙，很久都没发博客了，有兴趣的同学倒可以follow me：</p>
<p><a href="http://t.sina.com.cn/sicaboy" target="_blank">新浪围脖@申力军</a></p>
<p>由于某些不开心的经历已经结束了与美国的合作。 至于新计划，以后再公布吧。</p>
<h2  class="related_post_title">Other Posts / 其他文章</h2><ul class="related_post"><li><a href="http://slj.me/2009/04/php-quebec-2009-ppt-download/" title="PHP Quebec 2009 PHP全球聚会PPT下载">PHP Quebec 2009 PHP全球聚会PPT下载</a></li><li><a href="http://slj.me/2011/12/solve-linux-password-8-chars-limit/" title="解决 Linux 用户密码最多支持密码前 8 位的方法">解决 Linux 用户密码最多支持密码前 8 位的方法</a></li><li><a href="http://slj.me/2009/10/15-css-framework/" title="精选15个国外CSS框架">精选15个国外CSS框架</a></li><li><a href="http://slj.me/2009/09/yui-2-8-0-released/" title="YUI 2.8.0 发布">YUI 2.8.0 发布</a></li><li><a href="http://slj.me/2010/03/css3-please-the-cross-browser-css3-rule-generator/" title="CSS3, Please! The Cross-Browser CSS3 Rule Generator">CSS3, Please! The Cross-Browser CSS3 Rule Generator</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/03/migrate-to-linode/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PHP 实现多服务器共享 SESSION 数据</title>
		<link>http://slj.me/2011/02/php-share-session-between-servers/</link>
		<comments>http://slj.me/2011/02/php-share-session-between-servers/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 15:33:59 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Structure]]></category>
		<category><![CDATA[session]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2152</guid>
		<description><![CDATA[PHP 实现多服务器共享 SESSION 数据 一、问题起源 稍大一些的网站，通常都会有好几个服务器，每个服务器运行着不同功能的模块，使用不同的二级域名，而一个整体性强的网站，用户系统是统一的，即一套用户名、密码在整个网站的各个模块中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的，只需要在后端放个数据库服务器，各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题，就是用户在这个服务器登录之后，进入另一个服务器的别的模块时，仍然需要重新登录，这就是一次登录，全部通行的问题，映射到技术上，其实就是各个服务器之间如何实现共享 SESSION 数据的问题。 二、PHP SESSION 的工作原理 在解决问题之前，先来了解一下 PHP SESSION 的工作原理。在客户端（如浏览器）登录网站时，被访问的 PHP 页面可以使用 session_start() 打开 SESSION，这样就会产生客户端的唯一标识 SESSION ID（此 ID 可通过函数 session_id() 获取/设置）。SESSION ID 可以通过两种方式保留在客户端，使得请求不同的页面时，PHP 程序可以获知客户端的 SESSION ID；一种是将 SESSION ID 自动加入到 GET 的 URL 中，或者 POST 的表单中，默认情况下，变量名为 PHPSESSID；另一种是通过 COOKIE，将 SESSION ID 保存在 COOKIE 中，默认情况下，这个 COOKIE 的名字为 PHPSESSID。这里我们主要以 COOKIE 方式进行说明，因为应用比较广泛。 那么 SESSION 的数据保存在哪里呢？当然是在服务器端，但不是保存在内存中，而是保存在文件或数据库中。默认情况下，php.ini [...]]]></description>
			<content:encoded><![CDATA[<p>PHP 实现多服务器共享 SESSION 数据</p>
<p>一、问题起源</p>
<p>稍大一些的网站，通常都会有好几个服务器，每个服务器运行着不同功能的模块，使用不同的二级域名，而一个整体性强的网站，用户系统是统一的，即一套用户名、密码在整个网站的各个模块中都是可以登录使用的。各个服务器共享用户数据是比较容易实现的，只需要在后端放个数据库服务器，各个服务器通过统一接口对用户数据进行访问即可。但还存在一个问题，就是用户在这个服务器登录之后，进入另一个服务器的别的模块时，仍然需要重新登录，这就是一次登录，全部通行的问题，映射到技术上，其实就是各个服务器之间如何实现共享 SESSION 数据的问题。</p>
<p><span id="more-2152"></span>二、PHP SESSION 的工作原理</p>
<p>在解决问题之前，先来了解一下 PHP SESSION 的工作原理。在客户端（如浏览器）登录网站时，被访问的 PHP 页面可以使用 session_start() 打开 SESSION，这样就会产生客户端的唯一标识 SESSION ID（此 ID 可通过函数 session_id() 获取/设置）。SESSION ID 可以通过两种方式保留在客户端，使得请求不同的页面时，PHP 程序可以获知客户端的 SESSION ID；一种是将 SESSION ID 自动加入到 GET 的 URL 中，或者 POST 的表单中，默认情况下，变量名为 PHPSESSID；另一种是通过 COOKIE，将 SESSION ID 保存在 COOKIE 中，默认情况下，这个 COOKIE 的名字为 PHPSESSID。这里我们主要以 COOKIE 方式进行说明，因为应用比较广泛。</p>
<p>那么 SESSION 的数据保存在哪里呢？当然是在服务器端，但不是保存在内存中，而是保存在文件或数据库中。默认情况下，php.ini 中设置的 SESSION 保存方式是 files（session.save_handler = files），即使用读写文件的方式保存 SESSION 数据，而 SESSION 文件保存的目录由 session.save_path 指定，文件名以 sess_ 为前缀，后跟 SESSION ID，如：sess_c72665af28a8b14c0fe11afe3b59b51b。文件中的数据即是序列化之后的 SESSION 数据了。如果访问量大，可能产生的 SESSION 文件会比较多，这时可以设置分级目录进行 SESSION 文件的保存，效率会提高很多，设置方法为：session.save_path=”N;/save_path”，N 为分级的级数，save_path 为开始目录。当写入 SESSION 数据的时候，PHP 会获取到客户端的 SESSION_ID，然后根据这个 SESSION ID 到指定的 SESSION 文件保存目录中找到相应的 SESSION 文件，不存在则创建之，最后将数据序列化之后写入文件。读取 SESSION 数据是也是类似的操作流程，对读出来的数据需要进行解序列化，生成相应的 SESSION 变量。</p>
<p>三、多服务器共享 SESSION 的主要障碍及解决办法</p>
<p>通过了解 SESSION 的工作原理，我们可以发现，在默认情况下，各个服务器会各自分别对同一个客户端产生 SESSION ID，如对于同一个用户浏览器，A 服务器产生的 SESSION ID 是 30de1e9de3192ba6ce2992d27a1b6a0a，而 B 服务器生成的则是 c72665af28a8b14c0fe11afe3b59b51b。另外，PHP 的 SESSION 数据都是分别保存在本服务器的文件系统中。如下图所示：</p>
<p>确定了问题所在之后，就可以着手进行解决了。想要共享 SESSION 数据，那就必须实现两个目标：一个是各个服务器对同一个客户端产生的 SESSION ID 必须相同，并且可通过同一个 COOKIE 进行传递，也就是说各个服务器必须可以读取同一个名为 PHPSESSID 的 COOKIE；另一个是 SESSION 数据的存储方式/位置必须保证各个服务器都能够访问到。简单地说就是多服务器共享客户端的 SESSION ID，同时还必须共享服务器端的 SESSION 数据。</p>
<p>第一个目标的实现其实很简单，只需要对 COOKIE 的域（domain）进行特殊地设置即可，默认情况下，COOKIE 的域是当前服务器的域名/IP 地址，而域不同的话，各个服务器所设置的 COOKIE 是不能相互访问的，如 www.aaa.com 的服务器是不能读写 www.bbb.com 服务器设置的 COOKIE 的。</p>
<p>这里我们所说的同一网站的服务器有其特殊性，那就是他们同属于同一个一级域，如：aaa.infor96.com 和 www.infor96.com 都属于域 .infor96.com，那么我们就可以设置 COOKIE 的域为 .infor96.com，这样 aaa.infor96.com、www.infor96.com 等等都可以访问此 COOKIE。PHP 代码中的设置方法如下：</p>
<div class="hl-surround">
<div class="hl-main"><span style="color: blue;">&lt;?php</span><span style="color: gray;"><br />
</span><span style="color: blue;">ini_set</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">session.cookie_domain</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">.infor96.com</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">;</span><span style="color: gray;"><br />
?&gt;</span></div>
</div>
<p>这样各个服务器共享同一客户端 SESSION ID 的目的就达到了。</p>
<p>第二个目标的实现可以使用文件共享方式，如 NFS 方式，但设置、操作上有些复杂。我们可以参考先前所说的统一用户系统的方式，即使用数据库来保存 SESSION 数据，这样各个服务器就可以方便地访问同一个数据源，获取相同的 SESSION 数据了。</p>
<p>解决办法如下图所示：</p>
<p>四、代码实现</p>
<p>首先创建数据表，MySQL 的 SQL 语句如下：</p>
<p>CREATE TABLE `sess` (</p>
<p>`sesskey` varchar(32) NOT NULL default ”,</p>
<p>`expiry` bigint(20) NOT NULL default ‘0′,</p>
<p>`data` longtext NOT NULL,</p>
<p>PRIMARY KEY  (`sesskey`),</p>
<p>KEY `expiry` (`expiry`)</p>
<p>) TYPE=MyISAM</p>
<p>sesskey 为 SESSION ID，expiry 为 SESSION 过期时间，data 用于保存 SESSION 数据。</p>
<p>默认情况下 SESSION 数据是以文件方式保存，想要使用数据库方式保存，就必须重新定义 SESSION 各个操作的处理函数。PHP 提供了session_set_save_handle() 函数，可以用此函数自定义 SESSION 的处理过程，当然首先要先将 session.save_handler 改成 user，可在 PHP 中进行设置：</p>
<div class="hl-surround">
<div class="hl-main"><span style="color: blue;">&lt;?php</span><span style="color: gray;"><br />
</span><span style="color: blue;">session_module_name</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">user</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">;</span><span style="color: gray;"><br />
?&gt;</span></div>
</div>
<p>接下来着重讲一下 session_set_save_handle() 函数，此函数有六个参数：</p>
<p>session_set_save_handler ( string open, string close, string read, string write, string destroy, string gc )</p>
<p>各个参数为各项操作的函数名，这些操作依次是：打开、关闭、读取、写入、销毁、垃圾回收。PHP 手册中有详细的例子，在这里我们使用 OO 的方式来实现这些操作，详细代码如下：</p>
<div class="hl-surround">
<div class="hl-main"><span style="color: blue;">&lt;?php</span><span style="color: gray;"><br />
</span><span style="color: green;">define</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">MY_SESS_TIME</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: maroon;">3600</span><span style="color: olive;">)</span><span style="color: gray;">; </span><span style="color: #ffa500;">//SESSION 生存时长</span><span style="color: gray;"><br />
</span><span style="color: #ffa500;">//类定义</span><span style="color: gray;"><br />
</span><span style="color: green;">class</span><span style="color: gray;"> </span><span style="color: blue;">My_Sess</span><span style="color: gray;"><br />
</span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">init</span><span style="color: olive;">()</span><span style="color: gray;"><br />
</span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$domain</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">.infor96.com</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//不使用 GET/POST 变量方式</span><span style="color: gray;"><br />
</span><span style="color: blue;">ini_set</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">session.use_trans_sid</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: maroon;">0</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//设置垃圾回收最大生存时间</span><span style="color: gray;"><br />
</span><span style="color: blue;">ini_set</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">session.gc_maxlifetime</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: blue;">MY_SESS_TIME</span><span style="color: olive;">)</span><span style="color: gray;">;</p>
<p></span><span style="color: #ffa500;">//使用 COOKIE 保存 SESSION ID 的方式</span><span style="color: gray;"><br />
</span><span style="color: blue;">ini_set</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">session.use_cookies</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: maroon;">1</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: blue;">ini_set</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">session.cookie_path</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">/</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//多主机共享保存 SESSION ID 的 COOKIE</span><span style="color: gray;"><br />
</span><span style="color: blue;">ini_set</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">session.cookie_domain</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #00008b;">$domain</span><span style="color: olive;">)</span><span style="color: gray;">;</p>
<p></span><span style="color: #ffa500;">//将 session.save_handler 设置为 user，而不是默认的 files</span><span style="color: gray;"><br />
</span><span style="color: blue;">session_module_name</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">user</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//定义 SESSION 各项操作所对应的方法名：</span><span style="color: gray;"><br />
</span><span style="color: blue;">session_set_save_handler</span><span style="color: olive;">(</span><span style="color: gray;"><br />
</span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">My_Sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">open</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">, </span><span style="color: #ffa500;">//对应于静态方法 My_Sess::open()，下同。</span><span style="color: gray;"><br />
</span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">My_Sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">close</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">,<br />
</span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">My_Sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">read</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">,<br />
</span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">My_Sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">write</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">,<br />
</span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">My_Sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">destroy</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">,<br />
</span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">My_Sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">gc</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;"><br />
</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"></p>
<p></span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">open</span><span style="color: olive;">(</span><span style="color: #00008b;">$save_path</span><span style="color: gray;">, </span><span style="color: #00008b;">$session_name</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: green;">true</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"></p>
<p></span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">close</span><span style="color: olive;">()</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">global</span><span style="color: gray;"> </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">;</p>
<p></span><span style="color: green;">if</span><span style="color: gray;"> </span><span style="color: olive;">(</span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"> </span><span style="color: #ffa500;">//关闭数据库连接</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Close</span><span style="color: olive;">()</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"><br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: green;">true</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"></p>
<p></span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">read</span><span style="color: olive;">(</span><span style="color: #00008b;">$sesskey</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">global</span><span style="color: gray;"> </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">;</p>
<p></span><span style="color: #00008b;">$sql</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">SELECT data FROM sess WHERE sesskey=</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> . </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">qstr</span><span style="color: olive;">(</span><span style="color: #00008b;">$sesskey</span><span style="color: olive;">)</span><span style="color: gray;"> . </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;"> AND expiry&gt;=</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> . </span><span style="color: blue;">time</span><span style="color: olive;">()</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$rs</span><span style="color: gray;"> =&amp; </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Execute</span><span style="color: olive;">(</span><span style="color: #00008b;">$sql</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: green;">if</span><span style="color: gray;"> </span><span style="color: olive;">(</span><span style="color: #00008b;">$rs</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">if</span><span style="color: gray;"> </span><span style="color: olive;">(</span><span style="color: #00008b;">$rs</span><span style="color: gray;">-&gt;</span><span style="color: blue;">EOF</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: #8b0000;">&#8221;</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: green;">else</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"> </span><span style="color: #ffa500;">//读取到对应于 SESSION ID 的 SESSION 数据</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$v</span><span style="color: gray;"> = </span><span style="color: #00008b;">$rs</span><span style="color: gray;">-&gt;</span><span style="color: blue;">fields</span><span style="color: olive;">[</span><span style="color: maroon;">0</span><span style="color: olive;">]</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$rs</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Close</span><span style="color: olive;">()</span><span style="color: gray;">;<br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: #00008b;">$v</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end if</span><span style="color: gray;"><br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end if</span><span style="color: gray;"><br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: #8b0000;">&#8221;</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"></p>
<p></span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">write</span><span style="color: olive;">(</span><span style="color: #00008b;">$sesskey</span><span style="color: gray;">, </span><span style="color: #00008b;">$data</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">global</span><span style="color: gray;"> </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">;</p>
<p></span><span style="color: #00008b;">$qkey</span><span style="color: gray;"> = </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">qstr</span><span style="color: olive;">(</span><span style="color: #00008b;">$sesskey</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$expiry</span><span style="color: gray;"> = </span><span style="color: blue;">time</span><span style="color: olive;">()</span><span style="color: gray;"> + </span><span style="color: blue;">My_SESS_TIME</span><span style="color: gray;">; </span><span style="color: #ffa500;">//设置过期时间</span><span style="color: gray;"></p>
<p></span><span style="color: #ffa500;">//写入 SESSION</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$arr</span><span style="color: gray;"> = </span><span style="color: green;">array</span><span style="color: olive;">(</span><span style="color: gray;"><br />
</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">sesskey</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> =&gt; </span><span style="color: #00008b;">$qkey</span><span style="color: gray;">,<br />
</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">expiry</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> =&gt; </span><span style="color: #00008b;">$expiry</span><span style="color: gray;">,<br />
</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">data</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> =&gt; </span><span style="color: #00008b;">$data</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Replace</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #00008b;">$arr</span><span style="color: gray;">, </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">sesskey</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">, </span><span style="color: #00008b;">$autoQuote</span><span style="color: gray;"> = </span><span style="color: green;">true</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: green;">true</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"></p>
<p></span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">destroy</span><span style="color: olive;">(</span><span style="color: #00008b;">$sesskey</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">global</span><span style="color: gray;"> </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">;</p>
<p></span><span style="color: #00008b;">$sql</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">DELETE FROM sess WHERE sesskey=</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> . </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">qstr</span><span style="color: olive;">(</span><span style="color: #00008b;">$sesskey</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$rs</span><span style="color: gray;"> =&amp; </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Execute</span><span style="color: olive;">(</span><span style="color: #00008b;">$sql</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: green;">true</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"></p>
<p></span><span style="color: green;">function</span><span style="color: gray;"> </span><span style="color: blue;">gc</span><span style="color: olive;">(</span><span style="color: #00008b;">$maxlifetime</span><span style="color: gray;"> = </span><span style="color: green;">null</span><span style="color: olive;">)</span><span style="color: gray;"> </span><span style="color: olive;">{</span><span style="color: gray;"><br />
</span><span style="color: green;">global</span><span style="color: gray;"> </span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">;</p>
<p></span><span style="color: #00008b;">$sql</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">DELETE FROM sess WHERE expiry&lt; </span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;"> . </span><span style="color: blue;">time</span><span style="color: olive;">()</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Execute</span><span style="color: olive;">(</span><span style="color: #00008b;">$sql</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//由于经常性的对表 sess 做删除操作，容易产生碎片，</span><span style="color: gray;"><br />
</span><span style="color: #ffa500;">//所以在垃圾回收中对该表进行优化操作。</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$sql</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">OPTIMIZE TABLE sess</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$MY_SESS_CONN</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Execute</span><span style="color: olive;">(</span><span style="color: #00008b;">$sql</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: green;">return</span><span style="color: gray;"> </span><span style="color: green;">true</span><span style="color: gray;">;<br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">//end function</span><span style="color: gray;"><br />
</span><span style="color: olive;">}</span><span style="color: gray;"> </span><span style="color: #ffa500;">///:~</span><span style="color: gray;"></p>
<p></span><span style="color: #ffa500;">//使用 ADOdb 作为数据库抽象层。</span><span style="color: gray;"><br />
</span><span style="color: green;">require_once</span><span style="color: olive;">(</span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">adodb/adodb.inc.php</span><span style="color: #8b0000;">&#8216;</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//数据库配置项，可放入配置文件中（如：config.inc.php）。</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$db_type</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">mysql</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$db_host</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">192.168.212.1</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$db_user</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">sess_user</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$db_pass</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">sess_pass</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$db_name</span><span style="color: gray;"> = </span><span style="color: #8b0000;">&#8216;</span><span style="color: red;">sess_db</span><span style="color: #8b0000;">&#8216;</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//创建数据库连接，这是一个全局变量。</span><span style="color: gray;"><br />
</span><span style="color: #00008b;">$GLOBALS</span><span style="color: olive;">[</span><span style="color: #8b0000;">'</span><span style="color: red;">MY_SESS_CONN</span><span style="color: #8b0000;">'</span><span style="color: olive;">]</span><span style="color: gray;"> =&amp; </span><span style="color: blue;">ADONewConnection</span><span style="color: olive;">(</span><span style="color: #00008b;">$db_type</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #00008b;">$GLOBALS</span><span style="color: olive;">[</span><span style="color: #8b0000;">'</span><span style="color: red;">MY_SESS_CONN</span><span style="color: #8b0000;">'</span><span style="color: olive;">]</span><span style="color: gray;">-&gt;</span><span style="color: blue;">Connect</span><span style="color: olive;">(</span><span style="color: gray;"> </span><span style="color: #00008b;">$db_host</span><span style="color: gray;">, </span><span style="color: #00008b;">$db_user</span><span style="color: gray;">, </span><span style="color: #00008b;">$db_pass</span><span style="color: gray;">, </span><span style="color: #00008b;">$db_name</span><span style="color: olive;">)</span><span style="color: gray;">;<br />
</span><span style="color: #ffa500;">//初始化 SESSION 设置，必须在 session_start() 之前运行！！</span><span style="color: gray;"><br />
</span><span style="color: blue;">My_Sess</span><span style="color: gray;">::</span><span style="color: blue;">init</span><span style="color: olive;">()</span><span style="color: gray;">;</span><span style="color: gray;"><br />
?&gt;</span></div>
</div>
<p>五、遗留问题</p>
<p>如果网站的访问量很大的话，SESSION 的读写会频繁地对数据库进行操作，这样效率就会明显降低。考虑到 SESSION 数据一般不会很大，可以尝试用 C/Java 写个多线程的程序，用 HASH 表保存 SESSION 数据，并通过 socket 通信进行数据读写，这样 SESSION 就保存在内存中，读写速度应该会快很多。另外还可以通过负载均衡来分担服务器负载。不过这些都只是我自己的一些想法和假设，并没有实践过</p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/08/web-open-source-project/" title="疯狂的 Web 应用开源项目">疯狂的 Web 应用开源项目</a></li><li><a href="http://slj.me/2011/06/php-daemon-notice/" title="[转] 代替bash，书写 PHP daemon 后台程序">[转] 代替bash，书写 PHP daemon 后台程序</a></li><li><a href="http://slj.me/2011/04/xdebug-for-php/" title="Xdebug for php 一个实用的PHP调试扩展">Xdebug for php 一个实用的PHP调试扩展</a></li><li><a href="http://slj.me/2010/12/php-ini_set-fail-reason/" title="PHP ini_set() 无效的原因">PHP ini_set() 无效的原因</a></li><li><a href="http://slj.me/2010/12/centos-php5-2-yum/" title="CentOS 用 yum 官方源安裝 PHP5.2.x">CentOS 用 yum 官方源安裝 PHP5.2.x</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/02/php-share-session-between-servers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>转购买安装Godaddy SSL证书以及Nginx配置HTTPS方法</title>
		<link>http://slj.me/2011/02/install-godaddy-ssl-https-on-nginx/</link>
		<comments>http://slj.me/2011/02/install-godaddy-ssl-https-on-nginx/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 07:44:09 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Apache/Nginx]]></category>
		<category><![CDATA[Web Structure]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2147</guid>
		<description><![CDATA[一、购买 Godaddy SSL 证书 我买的是最便宜的一款，用优惠码 cjcssl12t2 以后 12.99 美元一年 ，购买地址： http://www.godaddy.com/gdshop/ssl/ssl.asp?isc=cjcssl12t2 二、生成服务器的 CSR 文件 用 root 权限进入服务器，输入： openssl genrsa -des3 -out &#60;name of your certificate&#62;.key 2048 openssl req -new -key &#60;name of your certificate&#62;.key -out &#60;name of your certificate&#62;.csr （必须是 2048 ，Godaddy 规定如此） 按照要求填写正确的信息 （Godaddy 帮助页面有相关帮助：http://help.godaddy.com/topic/746/article/5269） 还可以参考以下文章： http://www.kuaissl.cn/Support/CSRgen/Apache_CSR.htm 三、验证 CSR 文件 进入购买的 SSL 证书页面，此时没有绑定任何 CSR [...]]]></description>
			<content:encoded><![CDATA[<h2>一、购买 Godaddy SSL 证书</h2>
<p>我买的是最便宜的一款，用优惠码 <strong>cjcssl12t2 </strong>以后 12.99 美元一年 ，购买地址： <a title="http://www.godaddy.com/gdshop/ssl/ssl.asp?isc=cjcssl12t2" href="http://www.godaddy.com/gdshop/ssl/ssl.asp?isc=cjcssl12t2">http://www.godaddy.com/gdshop/ssl/ssl.asp?isc=cjcssl12t2</a></p>
<h2>二、生成服务器的 CSR 文件</h2>
<p>用 root 权限进入服务器，输入：</p>
<blockquote><p>openssl genrsa -des3 -out &lt;name of your certificate&gt;.key 2048</p></blockquote>
<blockquote><p>openssl req -new -key &lt;name of your certificate&gt;.key -out &lt;name of your certificate&gt;.csr</p></blockquote>
<p>（必须是 2048 ，Godaddy 规定如此）</p>
<p>按照要求填写正确的信息</p>
<p>（Godaddy 帮助页面有相关帮助：<a title="http://help.godaddy.com/topic/746/article/5269" href="http://help.godaddy.com/topic/746/article/5269">http://help.godaddy.com/topic/746/article/5269</a>）</p>
<p><span id="more-2147"></span>还可以参考以下文章：</p>
<p><a title="http://www.kuaissl.cn/Support/CSRgen/Apache_CSR.htm" href="http://www.kuaissl.cn/Support/CSRgen/Apache_CSR.htm">http://www.kuaissl.cn/Support/CSRgen/Apache_CSR.htm</a></p>
<h2>三、验证 CSR 文件</h2>
<p>进入购买的 SSL 证书页面，此时没有绑定任何 CSR ，Godaddy 会要求你输入 CSR 文件里的内容，直接复制过去即可，类似于这样的代码：</p>
<blockquote><p>&#8212;&#8211;BEGIN CERTIFICATE REQUEST&#8212;&#8211; MIIBzDCCATUCAQAwgYsxHDAaBgNVBAMTE3d3dy50aGlzaXNhdGVzdC5jb20xCzAJ BgNVBAYTAlpBMRkwFwYDVQQIExBXZXN0ZXJuIFByb3ZpbmNlMRIwEAYDVQQHEwlD YXBlIFRvd24xEjAQBgNVBAoTCVRlc3QgQ29ycDEbMBkGA1UECxMSVGVzdGluZyBE ZXBhcnRtZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVzfmv7vJ9bOyQ dxMLlgtDIEFz7MWsOUoZOPTq3qsTTXPW61q01jY8eQfs96I5xPjxALPeT4m74cce UtYxldG7pLJiB3SGU94yvyvHDiyV+6mV/e++KWT2ql0Jv1emmobmAGdUxdx2pW9C Epr0DmcVny6VGWAI36bG0NdYrNix4QIDAQABoAAwDQYJKoZIhvcNAQEEBQADgYEA BfSHgDr9Vc460YG+lAiWuVWEife8B4QOojiV8oUxJJDqbA2CEEmXLWfa7/mfUtd5 EQd6voLDT8axpXPbOrmwa3kzEZvQZhg+QvKEyIfncqdWbDUk71tO0fVafBKwRQfE 73J/THmVABZuz9T6X3+KWGxGDiYw0sY3bE7OjBCwr14=</p>
<p>&#8212;&#8211;END CERTIFICATE REQUEST&#8212;&#8211;</p></blockquote>
<p>接着直接 Order， 输入相关信息，接着就是等待 Godaddy 审核的时间。</p>
<h2>四、Godaddy 审核</h2>
<p>Godaddy 审核貌似需要几个钟头，我等了一下午，终于告诉我， Whois 上的 email 和实际 email 不符，囧…… .im 域名的whois 上是不显示 email 的……</p>
<p>接着，Godaddy 会告诉你一个代码，几个字母和数字的组合，比如XXX123，你只需要增加一个Cname，比如 xxx123.yourdomain.com. 解析到 yourdomain.com 即可，然后手工审核之（Godaddy 的邮件里都有告诉你方法，可惜当时我没截图，说的糊里糊涂的，邮件里很详细告诉你方法了）</p>
<h2>五、Nginx 平台安装</h2>
<p>需要以下几步：</p>
<h3>一、Nginx安装</h3>
<p>安装的时候需要注意加上 &#8211;with-http_ssl_module，因为http_ssl_module不属于Nginx的基本模块。</p>
<p>Nginx安装方法：</p>
<p>./configure &#8211;user=username &#8211;group=groupname &#8211;prefix=/usr/local/nginx &#8211;with-http_stub_status_module &#8211;with-http_ssl_module</p>
<p>make &amp;&amp; make install</p>
<h3>二、生成证书(如果没有godaddy证书的就用这个方法自己办法)</h3>
<p>可以使用openssl或ca.ssl生成，结果生成如下两个文件：</p>
<p>server.crt</p>
<p>server.key</p>
<p>如果是apache，直接将这两个文件引入到httpd.conf中，而Nginx需要的是.pem文件。.pem的生成方法很简单，就是合并server.crt、server.key的内容。</p>
<p>详细看这里：http://brucectl.javaeye.com/blog/455182</p>
<h3>三、修改Nginx配置：</h3>
<blockquote><p>server</p>
<p>{</p>
<p>listen 443;</p>
<p>server_name test.sina.com.cn;</p>
<p>ssl on;</p>
<p>ssl_certificate /tmp/server.pem;</p>
<p>ssl_certificate_key /tmp/server.key;</p>
<p>ssl_session_timeout 5m;</p>
<p>ssl_protocols SSLv2 SSLv3 TLSv1;</p>
<p>ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;</p>
<p>ssl_prefer_server_ciphers on;</p>
<p>}</p></blockquote>
<h3>3、重启服务即可</h3>
<p>具体可以参考这篇文章：《<a href="http://blog.tianya.cn/blogger/post_show.asp?BlogID=311462&amp;PostID=16867861&amp;idWriter=0&amp;Key=0" target="_blank">用Nginx配置https加密站点</a>》、《<a href="http://www.lostk.com/blog/nginx_ssl_config/" target="_blank">Nginx SSL 配置</a>》</p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/02/top-7-myths-about-https/" title="转载：HTTPS的七个误解（译文）">转载：HTTPS的七个误解（译文）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/02/install-godaddy-ssl-https-on-nginx/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>转载：HTTPS的七个误解（译文）</title>
		<link>http://slj.me/2011/02/top-7-myths-about-https/</link>
		<comments>http://slj.me/2011/02/top-7-myths-about-https/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 07:22:07 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[Web Structure]]></category>
		<category><![CDATA[https]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2131</guid>
		<description><![CDATA[开发网页的时候，往往需要观察HTTP通信。我使用的工具主要有两个，在Firefox中是Firebug，在IE中是Fiddler。但是，一直听别人说，付费软件HttpWatch是这方面最好的工具。 前几天，HttpWatch的官方网志刊登了一篇好文章，澄清了一些HTTPS协议容易产生误解的地方。学习之后，我增长了不少网页加密通信的知识。 我觉得这篇文章很实用，值得留作参考，就翻译了出来。 HTTPS的七个误解 误解七：HTTPS无法缓存 许多人以为，出于安全考虑，浏览器不会在本地保存HTTPS缓存。实际上，只要在HTTP头中使用特定命令，HTTPS是可以缓存的。 微软的IE项目经理Eric Lawrence写道： &#8220;说来也许令人震惊，只要HTTP头允许这样做，所有版本的IE都缓存HTTPS内容。比如，如果头命令是Cache-Control: max-age=600，那么这个网页就将被IE缓存10分钟。IE的缓存策略，与是否使用HTTPS协议无关。（其他浏览器在这方面的行为不一致，取决于你使用的版本，所以这里不加以讨论。）&#8221; Firefox默认只在内存中缓存HTTPS。但是，只要头命令中有Cache-Control: Public，缓存就会被写到硬盘上。下面的图片显示，Firefox的硬盘缓存中有HTTPS内容，头命令正是Cache-Control:Public。 误解六：SSL证书很贵 如果你在网上搜一下，就会发现很多便宜的SSL证书，大概10美元一年，这和一个.com域名的年费差不多。而且事实上，还能找到免费的SSL证书。 在效力上，便宜的证书当然会比大机构颁发的证书差一点，但是几乎所有的主流浏览器都接受这些证书。 误解五：HTTPS站点必须有独享的IP地址 由于IPv4将要分配完毕，所以很多人关心这个问题。每个IP地址只能安装一张SSL证书，这是毫无疑问的。但是，如果你使用子域名通配符SSL证书（wildcard SSL certificate，价格大约是每年125美元），就能在一个IP地址上部署多个HTTPS子域名。比如，https://www.httpwatch.com和https://store.httpwatch.com，就共享同一个IP地址。 另外，UCC（统一通信证书，Unified Communications Certificate）支持一张证书同时匹配多个站点，可以是完全不同的域名。SNI（服务器名称指示，Server Name Indication）允许一个IP地址上多个域名安装多张证书。服务器端，Apache和Nginx支持该技术，IIS不支持；客户端，IE 7+、Firefox 2.0+、Chrome 6+、Safari 2.1+和Opera 8.0+支持。 误解四：转移服务器时要购买新证书 部署SSL证书，需要这样几步 1. 在你的服务器上，生成一个CSR文件（SSL证书请求文件，SSL Certificate Signing Request）。 2. 使用CSR文件，购买SSL证书。 3. 安装SSL证书。 这些步骤都经过精心设计，保证传输的安全，防止有人截取或非法获得证书。结果就是，你在第二步得到的证书不能用在另一台服务器上。如果你需要这样做，就必须以其他格式输出证书。 比如，IIS的做法是生成一个可以转移的.pfx文件，并加以密码保护。 将这个文件传入其他服务器，将可以继续使用原来的SSL证书了。 误解三：HTTPS太慢 使用HTTPS不会使你的网站变得更快（实际上有可能，请看下文），但是有一些技巧可以大大减少额外开销。 首先，只要压缩文本内容，就会降低解码耗用的CPU资源。不过，对于当代CPU来说，这点开销不值一提。 其次，建立HTTPS连接，要求额外的TCP往返，因此会新增一些发送和接收的字节。但是，从下图可以看到，新增的字节是很少的。 第一次打开网页的时候，HTTPS协议会比HTTP协议慢一点，这是因为读取和验证SSL证书的时间。下面是一张HTTP网页打开时间的瀑布图。 同一张网页使用HTTPS协议之后，打开时间变长了。 建立连接的部分，大约慢了10%。但是，一旦有效的HTTPS连接建立起来，再刷新网页，两种协议几乎没有区别。先是HTTP协议的刷新表现： 然后是HTTPS协议： 某些用户可能发现，HTTPS比HTTP更快一点。这会发生在一些大公司的内部局域网，因为通常情况下，公司的网关会截取并分析所有的网络通信。但是，当它遇到HTTPS连接时，它就只能直接放行，因为HTTPS无法被解读。正是因为少了这个解读的过程，所以HTTPS变得比较快。 误解二：有了HTTPS，Cookie和查询字符串就安全了 虽然无法直接从HTTPS数据中读取Cookie和查询字符串，但是你仍然需要使它们的值变得难以预测。 比如，曾经有一家英国银行，直接使用顺序排列的数值表示session [...]]]></description>
			<content:encoded><![CDATA[<p>开发网页的时候，往往需要观察HTTP通信。我使用的工具主要有两个，在Firefox中是Firebug，在IE中是Fiddler。但是，一直听别人说，付费软件HttpWatch是这方面最好的工具。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904550.png" alt="" /></p>
<p>前几天，HttpWatch的官方网志刊登了一篇好文章，澄清了一些HTTPS协议容易产生误解的地方。学习之后，我增长了不少网页加密通信的知识。</p>
<p>我觉得这篇文章很实用，值得留作参考，就翻译了出来。</p>
<p><strong>HTTPS的七个误解</strong></p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904551.jpg" alt="" /></p>
<p><strong>误解七：HTTPS无法缓存</strong></p>
<p>许多人以为，出于安全考虑，浏览器不会在本地保存HTTPS缓存。实际上，只要在HTTP头中使用特定命令，HTTPS是可以缓存的。</p>
<p><span id="more-2131"></span></p>
<p>微软的IE项目经理Eric Lawrence写道：</p>
<table style="table-layout: fixed; border: #0099cc 1px solid;" border="0" cellspacing="0" cellpadding="6" width="95%" align="center">
<tbody>
<tr>
<td style="word-wrap: break-word;" bgcolor="#ddedfb">&#8220;说来也许令人震惊，只要HTTP头允许这样做，所有版本的IE都缓存HTTPS内容。比如，如果头命令是Cache-Control: max-age=600，那么这个网页就将被IE缓存10分钟。IE的缓存策略，与是否使用HTTPS协议无关。（其他浏览器在这方面的行为不一致，取决于你使用的版本，所以这里不加以讨论。）&#8221;</td>
</tr>
</tbody>
</table>
<p>Firefox默认只在内存中缓存HTTPS。但是，只要头命令中有Cache-Control: Public，缓存就会被写到硬盘上。下面的图片显示，Firefox的硬盘缓存中有HTTPS内容，头命令正是Cache-Control:Public。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904552.png" alt="" /></p>
<p><strong>误解六：SSL证书很贵</strong></p>
<p>如果你在网上搜一下，就会发现很多便宜的SSL证书，大概10美元一年，这和一个.com域名的年费差不多。而且事实上，还能找到免费的SSL证书。</p>
<p>在效力上，便宜的证书当然会比大机构颁发的证书差一点，但是几乎所有的主流浏览器都接受这些证书。</p>
<p><strong>误解五：HTTPS站点必须有独享的IP地址</strong></p>
<p>由于IPv4将要分配完毕，所以很多人关心这个问题。每个IP地址只能安装一张SSL证书，这是毫无疑问的。但是，如果你使用子域名通配符SSL证书（wildcard SSL certificate，价格大约是每年125美元），就能在一个IP地址上部署多个HTTPS子域名。比如，https://www.httpwatch.com和https://store.httpwatch.com，就共享同一个IP地址。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904553.png" alt="" /></p>
<p>另外，UCC（统一通信证书，Unified Communications Certificate）支持一张证书同时匹配多个站点，可以是完全不同的域名。SNI（服务器名称指示，Server Name Indication）允许一个IP地址上多个域名安装多张证书。服务器端，Apache和Nginx支持该技术，IIS不支持；客户端，IE 7+、Firefox 2.0+、Chrome 6+、Safari 2.1+和Opera 8.0+支持。</p>
<p><strong>误解四：转移服务器时要购买新证书</strong></p>
<p>部署SSL证书，需要这样几步</p>
<p>1. 在你的服务器上，生成一个CSR文件（SSL证书请求文件，SSL Certificate Signing Request）。</p>
<p>2. 使用CSR文件，购买SSL证书。</p>
<p>3. 安装SSL证书。</p>
<p>这些步骤都经过精心设计，保证传输的安全，防止有人截取或非法获得证书。结果就是，你在第二步得到的证书不能用在另一台服务器上。如果你需要这样做，就必须以其他格式输出证书。</p>
<p>比如，IIS的做法是生成一个可以转移的.pfx文件，并加以密码保护。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904554.png" alt="" /></p>
<p>将这个文件传入其他服务器，将可以继续使用原来的SSL证书了。</p>
<p><strong>误解三：HTTPS太慢</strong></p>
<p>使用HTTPS不会使你的网站变得更快（实际上有可能，请看下文），但是有一些技巧可以大大减少额外开销。</p>
<p>首先，只要压缩文本内容，就会降低解码耗用的CPU资源。不过，对于当代CPU来说，这点开销不值一提。</p>
<p>其次，建立HTTPS连接，要求额外的TCP往返，因此会新增一些发送和接收的字节。但是，从下图可以看到，新增的字节是很少的。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904555.png" alt="" /></p>
<p>第一次打开网页的时候，HTTPS协议会比HTTP协议慢一点，这是因为读取和验证SSL证书的时间。下面是一张HTTP网页打开时间的瀑布图。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904556.png" alt="" /></p>
<p>同一张网页使用HTTPS协议之后，打开时间变长了。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904557.png" alt="" /></p>
<p>建立连接的部分，大约慢了10%。但是，一旦有效的HTTPS连接建立起来，再刷新网页，两种协议几乎没有区别。先是HTTP协议的刷新表现：</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904558.png" alt="" /></p>
<p>然后是HTTPS协议：</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/0904559.png" alt="" /></p>
<p>某些用户可能发现，HTTPS比HTTP更快一点。这会发生在一些大公司的内部局域网，因为通常情况下，公司的网关会截取并分析所有的网络通信。但是，当它遇到HTTPS连接时，它就只能直接放行，因为HTTPS无法被解读。正是因为少了这个解读的过程，所以HTTPS变得比较快。</p>
<p><strong>误解二：有了HTTPS，Cookie和查询字符串就安全了</strong></p>
<p>虽然无法直接从HTTPS数据中读取Cookie和查询字符串，但是你仍然需要使它们的值变得难以预测。</p>
<p>比如，曾经有一家英国银行，直接使用顺序排列的数值表示session id:</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/09045510.png" alt="" /></p>
<p>黑客可以先注册一个账户，找到这个cookie，看到这个值的表示方法。然后，改动cookie，从而劫持其他人的session id。至于查询字符串，也可以通过类似方式泄漏。</p>
<p><strong>误解一：只有注册登录页，才需要HTTPS</strong></p>
<p>这种想法很普遍。人们觉得，HTTPS可以保护用户的密码，此外就不需要了。Firefox浏览器新插件Firesheep，证明了这种想法是错的。我们可以看到，在Twitter和Facebook上，劫持其他人的session是非常容易的。</p>
<p>咖啡馆的免费WiFi，就是一个很理想的劫持环境，因为两个原因：</p>
<p>1. 这种WiFi通常不会加密，所以很容易监控所有流量。</p>
<p>2. WiFi通常使用NAT进行外网和内网的地址转换，所有内网客户端都共享一个外网地址。这意味着，被劫持的session，看上去很像来自原来的登录者。</p>
<p>以Twitter为例，它的登录页使用了HTTPS，但是登录以后，其他页面就变成了HTTP。这时，它的cookie里的session值就暴露了。</p>
<p><img src="http://slj.me/wp-content/uploads/2011/02/09045511.png" alt="" /></p>
<p>也就是说，这些cookie是在HTTPS环境下建立的，但是却在HTTP环境下传输。如果有人劫持到这些cookie，那他就能以你的身份在Twitter上发言了。</p>
<p>原文网址：<a href="http://blog.httpwatch.com/2011/01/28/top-7-myths-about-https/" target="_blank">http://blog.httpwatch.com/2011/01/28/top-7-myths-about-https/</a></p>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/02/install-godaddy-ssl-https-on-nginx/" title="转购买安装Godaddy SSL证书以及Nginx配置HTTPS方法">转购买安装Godaddy SSL证书以及Nginx配置HTTPS方法</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2011/02/top-7-myths-about-https/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript 操作select控件大全（新增、修改、删除、选中、清空、判断存在等）</title>
		<link>http://slj.me/2010/12/javascript-select-operations/</link>
		<comments>http://slj.me/2010/12/javascript-select-operations/#comments</comments>
		<pubDate>Thu, 23 Dec 2010 02:38:21 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[HTML/CSS]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[select]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2124</guid>
		<description><![CDATA[转载一篇，这个有的时候还是很有用的，所以收藏一下 1、判断select选项中 是否存在Value=&#8221;paraValue&#8221;的Item 2、向select选项中 加入一个Item 3、从select选项中 删除一个Item 4、删除select中选中的项 5、修改select选项中 value=&#8221;paraValue&#8221;的text为&#8221;paraText&#8221; 6、设置select中text=&#8221;paraText&#8221;的第一个Item为选中 7、设置select中value=&#8221;paraValue&#8221;的Item为选中 8、得到select的当前选中项的value 9、得到select的当前选中项的text 10、得到select的当前选中项的Index 11、清空select的项 //js 代码 // 1.判断select选项中 是否存在Value="paraValue"的Item function jsSelectIsExitItem(objSelect, objItemValue) { var isExit = false; for (var i = 0; i < objSelect.options.length; i++) { if (objSelect.options[i].value == objItemValue) { isExit = true; break; } } return isExit; } // 2.向select选项中 加入一个Item function jsAddItemToSelect(objSelect, objItemText, [...]]]></description>
			<content:encoded><![CDATA[<p>转载一篇，这个有的时候还是很有用的，所以收藏一下</p>
<p>1、判断select选项中 是否存在Value=&#8221;paraValue&#8221;的Item<br />
2、向select选项中 加入一个Item<br />
3、从select选项中 删除一个Item<br />
4、删除select中选中的项<br />
5、修改select选项中 value=&#8221;paraValue&#8221;的text为&#8221;paraText&#8221;<br />
6、设置select中text=&#8221;paraText&#8221;的第一个Item为选中<br />
7、设置select中value=&#8221;paraValue&#8221;的Item为选中<br />
8、得到select的当前选中项的value<br />
9、得到select的当前选中项的text<br />
10、得到select的当前选中项的Index<br />
11、清空select的项</p>
<p><span id="more-2124"></span></p>
<pre class="js" name="code">
//js 代码
// 1.判断select选项中 是否存在Value="paraValue"的Item
function jsSelectIsExitItem(objSelect, objItemValue) {
    var isExit = false;
    for (var i = 0; i < objSelect.options.length; i++) {
        if (objSelect.options[i].value == objItemValue) {
            isExit = true;
            break;
        }
    }
    return isExit;
}         

// 2.向select选项中 加入一个Item
function jsAddItemToSelect(objSelect, objItemText, objItemValue) {
    //判断是否存在
    if (jsSelectIsExitItem(objSelect, objItemValue)) {
        alert("该Item的Value值已经存在");
    } else {
        var varItem = new Option(objItemText, objItemValue);
        objSelect.options.add(varItem);
        alert("成功加入");
    }
}        

// 3.从select选项中 删除一个Item
function jsRemoveItemFromSelect(objSelect, objItemValue) {
    //判断是否存在
    if (jsSelectIsExitItem(objSelect, objItemValue)) {
        for (var i = 0; i < objSelect.options.length; i++) {
            if (objSelect.options[i].value == objItemValue) {
                objSelect.options.remove(i);
                break;
            }
        }
        alert("成功删除");
    } else {
        alert("该select中 不存在该项");
    }
}    

// 4.删除select中选中的项
function jsRemoveSelectedItemFromSelect(objSelect) {
    var length = objSelect.options.length - 1;
    for(var i = length; i >= 0; i--){
        if(objSelect[i].selected == true){
            objSelect.options[i] = null;
        }
    }
}      

// 5.修改select选项中 value="paraValue"的text为"paraText"
function jsUpdateItemToSelect(objSelect, objItemText, objItemValue) {
    //判断是否存在
    if (jsSelectIsExitItem(objSelect, objItemValue)) {
        for (var i = 0; i < objSelect.options.length; i++) {
            if (objSelect.options[i].value == objItemValue) {
                objSelect.options[i].text = objItemText;
                break;
            }
        }
        alert("成功修改");
    } else {
        alert("该select中 不存在该项");
    }
}        

// 6.设置select中text="paraText"的第一个Item为选中
function jsSelectItemByValue(objSelect, objItemText) {
    //判断是否存在
    var isExit = false;
    for (var i = 0; i < objSelect.options.length; i++) {
        if (objSelect.options[i].text == objItemText) {
            objSelect.options[i].selected = true;
            isExit = true;
            break;
        }
    }
    //Show出结果
    if (isExit) {
        alert("成功选中");
    } else {
        alert("该select中 不存在该项");
    }
}        

// 7.设置select中value="paraValue"的Item为选中
document.all.objSelect.value = objItemValue;    

// 8.得到select的当前选中项的value
var currSelectValue = document.all.objSelect.value;    

// 9.得到select的当前选中项的text
var currSelectText = document.all.objSelect.options[document.all.objSelect.selectedIndex].text;    

// 10.得到select的当前选中项的Index
var currSelectIndex = document.all.objSelect.selectedIndex;    

// 11.清空select的项
document.all.objSelect.options.length = 0;
</pre>
</pre>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2010/04/mysql-group-by-having/" title="MySQL: group by &#8230; having &#8230;">MySQL: group by &#8230; having &#8230;</a></li><li><a href="http://slj.me/2010/03/45-fresh-useful-javascript-and-jquery-techniques-and-tools/" title="[英,转]45个新鲜有用的JS与jQuery技术和工具">[英,转]45个新鲜有用的JS与jQuery技术和工具</a></li><li><a href="http://slj.me/2010/03/building-iphone-apps-with-html-css-and-javascript/" title="【好书PDF】：Building iPhone Apps with HTML, CSS, and JavaScript">【好书PDF】：Building iPhone Apps with HTML, CSS, and JavaScript</a></li><li><a href="http://slj.me/2010/01/js%e8%8e%b7%e5%8f%96%e6%b5%8f%e8%a7%88%e5%99%a8%e7%aa%97%e5%8f%a3%e5%a4%a7%e5%b0%8f-%e8%8e%b7%e5%8f%96%e5%b1%8f%e5%b9%95%ef%bc%8c%e6%b5%8f%e8%a7%88%e5%99%a8%ef%bc%8c%e7%bd%91%e9%a1%b5%e9%ab%98/" title="JS获取浏览器窗口大小 获取屏幕，浏览器，网页高度宽度 ">JS获取浏览器窗口大小 获取屏幕，浏览器，网页高度宽度 </a></li><li><a href="http://slj.me/2009/07/javascript-pic-reflection-glossy-effect/" title="Javascript 实现图像倒影、发光效果">Javascript 实现图像倒影、发光效果</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2010/12/javascript-select-operations/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[转] Redis几个认识误区</title>
		<link>http://slj.me/2010/12/redis-misunderstood/</link>
		<comments>http://slj.me/2010/12/redis-misunderstood/#comments</comments>
		<pubDate>Sat, 18 Dec 2010 13:37:00 +0000</pubDate>
		<dc:creator>SLJ</dc:creator>
				<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[radis]]></category>

		<guid isPermaLink="false">http://slj.me/?p=2120</guid>
		<description><![CDATA[转自：Tim 后端技术 前几天微博发生了一起大的系统故障，很多技术的朋友都比较关心，其中的原因不会超出James Hamilton在On Designing and Deploying Internet-Scale Service(1)概括的那几个范围，James第一条经验“Design for failure”是所有互联网架构成功的一个关键。互联网系统的工程理论其实非常简单，James paper中内容几乎称不上理论，而是多条实践经验分享，每个公司对这些经验的理解及执行力决定了架构成败。 题外话说完，最近又研究了Redis。去年曾做过一个MemcacheDB, Tokyo Tyrant, Redis performance test，到目前为止，这个benchmark结果依然有效。这1年我们经历了很多眼花缭乱的key value存储产品的诱惑，从Cassandra的淡出(Twitter暂停在主业务使用)到HBase的兴起(Facebook新的邮箱业务选用HBase(2))，当再回头再去看Redis，发现这个只有1万多行源代码的程序充满了神奇及大量未经挖掘的特性。Redis性能惊人，国内前十大网站的子产品估计用1台Redis就可以满足存储及Cache的需求。除了性能印象之外，业界其实普遍对Redis的认识存在一定误区。本文提出一些观点供大家探讨。 1. Redis是什么 这个问题的结果影响了我们怎么用Redis。如果你认为Redis是一个key value store, 那可能会用它来代替MySQL；如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写，在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems，这个定义偏向key value store。还有一些看法则认为Redis是一个memory database，因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server，因为Redis支持复杂的数据特性，比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。 互联网数据目前基本使用两种方式来存储，关系数据库或者key value。但是这些互联网业务本身并不属于这两种数据类型，比如用户在社会化平台中的关系，它是一个list，如果要用关系数据库存储就需要转换成一种多行记录的形式，这种形式存在很多冗余数据，每一行需要存储一些重复信息。如果用key value存储则修改和删除比较麻烦，需要将全部数据读出再写入。Redis在内存中设计了各种数据类型，让业务能够高速原子的访问这些数据结构，并且不需要关心持久存储的问题，从架构上解决了前面两种存储需要走一些弯路的问题。 2. Redis不可能比Memcache快 很多开发者都认为Redis不可能比Memcached快，Memcached完全基于内存，而Redis具有持久化保存特性，即使是异步的，Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因，目前想到的原因有这几方面。 Libevent。和Memcached不同，Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event [...]]]></description>
			<content:encoded><![CDATA[<p>转自：Tim 后端技术</p>
<p>前几天微博发生了一起大的<a href="http://tech.sina.com.cn/i/2010-12-01/15324930344.shtml" target="_blank">系统故障</a>，很多技术的朋友都比较关心，其中的原因不会超出James Hamilton在On Designing and Deploying Internet-Scale Service(1)概括的那几个范围，James第一条经验“Design for failure”是所有互联网架构成功的一个关键。互联网系统的工程理论其实非常简单，James paper中内容几乎称不上理论，而是多条实践经验分享，每个公司对这些经验的理解及执行力决定了架构成败。</p>
<p>题外话说完，最近又研究了<a href="http://code.google.com/p/redis/" target="_blank">Redis</a>。去年曾做过一个<a href="http://timyang.net/data/mcdb-tt-redis/" target="_blank">MemcacheDB, Tokyo Tyrant, Redis performance test</a>，到目前为止，这个benchmark结果依然有效。这1年我们经历了很多眼花缭乱的key value存储产品的诱惑，从Cassandra的淡出(Twitter暂停在主业务使用)到HBase的兴起(Facebook新的邮箱业务选用HBase(2))，当再回头再去看Redis，发现这个只有1万多行源代码的程序充满了神奇及大量未经挖掘的特性。Redis性能惊人，国内前十大网站的子产品估计用1台Redis就可以满足存储及Cache的需求。除了性能印象之外，业界其实普遍对Redis的认识存在一定误区。本文提出一些观点供大家探讨。</p>
<h3><span id="more-2120"></span>1. Redis是什么</h3>
<p>这个问题的结果影响了我们怎么用Redis。如果你认为Redis是一个key value store, 那可能会用它来代替MySQL；如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写，在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems，这个定义偏向key value store。还有一些看法则认为Redis是一个memory database，因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server，因为Redis支持复杂的数据特性，比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。</p>
<p>互联网数据目前基本使用两种方式来存储，关系数据库或者key value。但是这些互联网业务本身并不属于这两种数据类型，比如用户在社会化平台中的关系，它是一个list，如果要用关系数据库存储就需要转换成一种多行记录的形式，这种形式存在很多冗余数据，每一行需要存储一些重复信息。如果用key value存储则修改和删除比较麻烦，需要将全部数据读出再写入。Redis在内存中设计了各种数据类型，让业务能够高速原子的访问这些数据结构，并且不需要关心持久存储的问题，从架构上解决了前面两种存储需要走一些弯路的问题。</p>
<h3>2. Redis不可能比Memcache快</h3>
<p>很多开发者都认为Redis不可能比Memcached快，Memcached完全基于内存，而Redis具有持久化保存特性，即使是异步的，Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因，目前想到的原因有这几方面。</p>
<ul>
<li><a href="http://monkey.org/~provos/libevent/" target="_blank">Libevent</a>。和Memcached不同，Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event loop(4)。业界不少开发者也建议Redis使用另外一个libevent高性能替代libev，但是作者还是坚持Redis应该小巧并去依赖的思路。一个印象深刻的细节是编译Redis之前并不需要执行./configure。</li>
<li>CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源的方法。CAS实现需要为每个cache key设置一个隐藏的cas token，cas相当value版本号，每次set会token需要递增，因此带来CPU和内存的双重开销，虽然这些开销很小，但是到单机10G+ cache以及QPS上万之后这些开销就会给双方相对带来一些细微性能差别(5)。</li>
</ul>
<h3>3. 单台Redis的存放数据必须比物理内存小</h3>
<p>Redis的数据全部放在内存带来了高速的性能，但是也带来一些不合理之处。比如一个中型网站有100万注册用户，如果这些资料要用Redis来存储，内存的容量必须能够容纳这100万用户。但是业务实际情况是100万用户只有5万活跃用户，1周来访问过1次的也只有15万用户，因此全部100万用户的数据都放在内存有不合理之处，RAM需要为冷数据买单。</p>
<p>这跟操作系统非常相似，操作系统所有应用访问的数据都在内存，但是如果物理内存容纳不下新的数据，操作系统会智能将部分长期没有访问的数据交换到磁盘，为新的应用留出空间。现代操作系统给应用提供的并不是物理内存，而是虚拟内存(Virtual Memory)的概念。</p>
<p>基于相同的考虑，Redis 2.0也增加了VM特性。让Redis数据容量突破了物理内存的限制。并实现了数据冷热分离。</p>
<h3>4. Redis的VM实现是重复造轮子</h3>
<p>Redis的VM依照之前的epoll实现思路依旧是自己实现。但是在前面操作系统的介绍提到OS也可以自动帮程序实现冷热数据分离，Redis只需要OS申请一块大内存，OS会自动将热数据放入物理内存，冷数据交换到硬盘，另外一个知名的“理解了现代操作系统(3)”的Varnish就是这样实现，也取得了非常成功的效果。</p>
<p>作者antirez在解释为什么要自己实现VM中提到几个原因(6)。主要OS的VM换入换出是基于Page概念，比如OS VM1个Page是4K, 4K中只要还有一个元素即使只有1个字节被访问，这个页也不会被SWAP, 换入也同样道理，读到一个字节可能会换入4K无用的内存。而Redis自己实现则可以达到控制换入的粒度。另外访问操作系统SWAP内存区域时block进程，也是导致Redis要自己实现VM原因之一。</p>
<h3>5. 用get/set方式使用Redis</h3>
<p>作为一个key value存在，很多开发者自然的使用set/get方式来使用Redis，实际上这并不是最优化的使用方法。尤其在未启用VM情况下，Redis全部数据需要放入内存，节约内存尤其重要。</p>
<p>假如一个key-value单元需要最小占用512字节，即使只存一个字节也占了512字节。这时候就有一个设计模式，可以把key复用，几个key-value放入一个key中，value再作为一个set存入，这样同样512字节就会存放10-100倍的容量。</p>
<p>这就是为了节约内存，建议使用hashset而不是set/get的方式来使用Redis，详细方法见参考文献(7)。</p>
<h3>6. 使用aof代替snapshot</h3>
<p>Redis有两种存储方式，默认是snapshot方式，实现方法是定时将内存的快照(snapshot)持久化到硬盘，这种方法缺点是持久化之后如果出现crash则会丢失一段数据。因此在完美主义者的推动下作者增加了aof方式。aof即append only mode，在写入内存数据的同时将操作命令保存到日志文件，在一个并发更改上万的系统中，命令日志是一个非常庞大的数据，管理维护成本非常高，恢复重建时间会非常长，这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型，所有的优势都是建立在对内存复杂数据结构高效的原子操作上，这样就看出aof是一个非常不协调的部分。</p>
<p>其实aof目的主要是数据可靠性及高可用性，在Redis中有另外一种方法来达到目的：Replication。由于Redis的高性能，复制基本没有延迟。这样达到了防止单点故障及实现了高可用。</p>
<h3>小结</h3>
<p>要想成功使用一种产品，我们需要深入了解它的特性。Redis性能突出，如果能够熟练的驾驭，对国内很多大型应用具有很大帮助。希望更多同行加入到Redis使用及代码研究行列。</p>
<h4>参考文献</h4>
<ol>
<li><a href="http://www.mvdirona.com/jrh/talksAndPapers/JamesRH_Lisa.pdf" target="_blank">On Designing and Deploying Internet-Scale Service(PDF)</a></li>
<li><a href="http://highscalability.com/blog/2010/11/16/facebooks-new-real-time-messaging-system-hbase-to-store-135.html" target="_blank">Facebook’s New Real-Time Messaging System: HBase To Store 135+ Billion Messages A Month</a></li>
<li><a href="http://www.varnish-cache.org/trac/wiki/ArchitectNotes" target="_blank">What’s wrong with 1975 programming</a></li>
<li><a href="http://groups.google.com/group/redis-db/browse_thread/thread/b52814e9ef15b8d0/b9de497c6a73614f" target="_blank">Linux epoll is now supported</a>(Google Groups)</li>
<li><a href="http://groups.google.com/group/redis-db/browse_thread/thread/6b8ccada4d4b79fa" target="_blank">CAS and why I don’t want to add it to Redis</a>(Google Groups)</li>
<li><a href="http://groups.google.com/group/redis-db/browse_thread/thread/f1c641c07cc0346c" target="_blank">Plans for Virtual Memory</a>(Google Groups)</li>
<li><a href="http://antirez.com/post/redis-weekly-update-7.html" target="_blank">Full of keys</a>(Salvatore antirez Sanfilippo)</li>
</ol>
<h2  class="related_post_title">Related Posts / 相关文章</h2><ul class="related_post"><li><a href="http://slj.me/2011/04/redis-cli-commands/" title="[Redis] redis-cli 命令总结">[Redis] redis-cli 命令总结</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://slj.me/2010/12/redis-misunderstood/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

