<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>一个藏袍</title>
<link>http://www.example.net.cn/</link>
<description>一个藏袍，关注互联网，关注旅游</description>
<copyright>Copyright 2009</copyright>
<lastBuildDate>Mon, 30 Mar 2009 16:45:41 +0800</lastBuildDate>
<generator>http://www.movabletype.org/?v=4.25</generator>
<docs>http://blogs.law.harvard.edu/tech/rss</docs> 


<item>
<title>初创网站与开源软件</title>
<description><![CDATA[<p>前面有一篇文章中提到过开源软件，不过主要是在系统运维的角度去讲的，主要分析一些系统级的开源软件(例如bind,memcached)，这里我们讨论的是用于搭建初创网站应用的开源软件(例如phpbb,phparticle)，运行在Linux，MySQL，Apache,PHP,Java等下面。</p>

<p>创业期的网站往往采用比较简单的系统架构，或者是直接使用比较成熟的开源软件。使用开源软件的好处是搭建速度快，基本不需要开发，买个空间域名，下个软件一搭建，用个半天就搞定了，一个崭新的网站就开张了，在前期可以极大程度的节约时间成本和开发成本。</p>

<p>当然使用开源软件搭建应用也存在一些局限性，这是我们要重点研究的，而研究的目的就是如何在开源软件选型时以及接下来的维护过程中尽量避免。</p>

<p>一方面是开源软件一般只有在比较成熟的领域才有，如果是一些创新型的项目很难找到合适的开源软件，这个时候没什么好的解决办法，如果非要用开源的话一般会找一个最相似的改一下。实际上目前开源的项目也比较多了，在sf.net上可以找到各种各样的开源项目。选型的时候尽量应该选取一个程序架构比较简单的，不一定越简单越好，但一定要简单，一目了然，别用什么太高级的特性，互联网应用项目不需要太复杂的框架。原因有两个，一个是框架复杂无非是为了实现更好的可扩展性和更清晰的层次，而我们正在做的互联网应用范围一般会比开源软件设计时所考虑的范围小的多，所以有的应用会显得设计过度，另外追求完美的层次划分导致的太复杂的继承派生关系也会影响到整个系统维护的工作量。建议应用只需要包含三个层就可以了，数据(实体)层，业务逻辑层，表现层。太复杂的设计容易降低开发效率，提高维护成本，在出现性能问题或者突发事件的时候也不容易找到原因。</p>

<p>另外一个问题是开源软件的后期维护和继续开发可能会存在问题，这一点不是绝对的，取决于开源软件的架构是否清晰合理，扩展性好，如果是较小的改动可能一般不会存在什么问题，例如添加一项用户属性或者文章属性，但有些需求可能就不是很容易实现了。例如网站发展到一定阶段后可能会考虑扩展产品线，原来只提供一个论坛加上cms，现在要再加上商城，那用户系统就会有问题，如何解决这个问题已经不仅仅是改一下论坛或者cms就可以解决了，这个时候我们需要上升到更高的层次来考虑问题，是否需要建立针对整个网站的用户认证系统，实现单点登录，用户可以在产品间无缝切换而且保持登录状态。由于网站初始的用户数据可能大部分都存放在论坛里，这个时候我们需要把用户数据独立出来就会碰到麻烦，如何既能把用户数据独立出来又不影响论坛原有系统的继续运行会是件很头痛的事情。经过一段时间的运行，除非是特别好的设计以及比较好的维护，一般都会在论坛里存在各种各样乱七八糟的对用户信息的调用，而且是直接针对数据库的，这样如果要将用户数据移走的话要修改代码的工作量将不容忽视，而另外一个解决办法是复制一份用户数据出来，以新的用户数据库为主，论坛里的用户数据通过同步或异步的机制实现同步。最好的解决办法就是在选型时选一个数据层封装的比较好的，sql代码不要到处飞的软件，然后在维护的时候保持系统原有的优良风格，把所有涉及到数据库的操作都放到数据层或者实体层里，这样无论对数据进行什么扩展，代码修改起来都比较方便，基本不会对上层的代码产生影响。</p>

<p>网站访问速度问题对初创网站来说一般考虑的比较少，买个空间或者托管服务器，搭建好应用后基本上就开始运转了，只有到真正面临极大的速度访问瓶颈后才会真正对这个问题产生重视。实际上在从网站的开始阶段开始，速度问题就会一直存在，并且会随着网站的发展也不断演进。一个网站最基本的要求，就是有比较快的访问速度，没有速度，再好的内容或服务也出不来。所以，访问速度在网站初创的时候就需要考虑，无论是采用开源软件还是自己开发都需要注意，数据层尽量能够正确，高效的使用SQL。SQL包含的语法比较复杂，实现同样一个效果如果考虑到应用层的的不同实现方法，可能有好几种方法，但里面只有一种是最高效的，而通常情况下，高效的SQL一般是那个最简单的SQL。在初期这个问题可能不是特别明显，当访问量大起来以后，这个可能成为最主要的性能瓶颈，各种杂乱无章的SQL会让人看的疯掉。当然前期没注意的话后期也有解决办法，只不过可能不会解决的特别彻底，但还是要吧非常有效的提升性能。看MySQL的SlowQuery Log是一个最为简便的方法，把执行时间超过1秒的查询记录下来，然后分析，把该加的索引加上，该简单的SQL简化。另外也可以通过Showprocesslist查看当前数据库服务器的死锁进程，从而锁定导致问题的SQL语句。另外在数据库配置文件上可以做一些优化，也可以很好的提升性能，这些文章在网站也比较多，这里就不展开。</p>

<p>这些工作都做了以后，下面数据库如果再出现性能问题就需要考虑多台服务器了，一台服务器已经解决不了问题了，我以前的文章中也提到过，这里也不再展开。</p>

<p>其它解决速度问题的办法就不仅仅是在应用里面就可以实现的了，需要从更高的高度去设计系统，考虑到服务器，网络的架构，以及各种系统级应用软件的配合，这里也不再展开。</p>

<p>良好设计并实现的应用+中间件+良好的分布式设计的数据库+良好的系统配置+良好的服务器/网络结构，就可以支撑起一个较大规模的网站了，加上前面的几篇文章，一个小网站发展到大网站的过程基本上就齐了。这个过程会是一个充满艰辛和乐趣的过程，也是一个可以逐渐过渡的过程，主动出击，提前考虑，减少救火可以让这个过程轻松一些。<br />
</p>]]></description>
<link>http://www.example.net.cn/2006/09/startup_and_opensource.html</link>
<guid>http://www.example.net.cn/2006/09/startup_and_opensource.html</guid>
<category>Example</category>
<pubDate>Mon, 04 Sep 2006 17:22:34 +0800</pubDate>
</item>

<item>
<title>ICE-高效的中间件平台，牛刀小试</title>
<description><![CDATA[<p>ICE(Internet Communications Engine)是<a href="http://www.zeroc.com">ZeroC</a>提供的一款高性能的中间件，基于ICE可以实现电信级的解决方案。前面我们提到过在设计网站架构的时候可以使用ICE实现对网站应用的基础对象操作，将基础对象操作和数据库操作封装在这一层，在业务逻辑层以及表现层(java,php,.net,python)进行更丰富的表现与操作，从而实现比较好的架构。基于ICE的数据层可以在未来方便的进行扩展。ICE支持分布式的部署管理，消息中间件，以及网格计算等等。</p>

<p>大道理讲完，言归正传，最近育儿网新增了不少新服务，服务间经常会需要相互调用数据，例如用户中心要取博客系统里的文章啊，论坛里发文后要在积分系统里增加用户积分啊。由于设计时这些服务仅仅基于统一的用户中心，服务间基本是独立的，所以要实现这些调用只能在每个服务上新增为其它服务提供服务的服务-_-!。这个时候有几个可选方案，我们开始选择了xml-rpc，基于http和xml的选程调用，用了一段时间，发现维护成本和访问性能都存在问题。</p>

<p>由于这些中间服务部署的时候是和各自所属的服务部署在一起的，对这些服务做整体的改动就非常困难，要维护起来就比较麻烦。另外由于是什么http和xml作为通信协议，由php实现业务逻辑，性能问题也很明显，而且这些http请求都会在http日志留下足迹，导致我们的日志分析很不精确。这个问题不是太大，但很郁闷，所以我们考虑使用ICE来解决这个问题，至于SOAP什么的就不考虑了，同样效率低下。</p>

<p>实现的过程还是比较顺利，花了三天的时间用c++实现了大部分常用的接口，服务端采用deamon的方式运行，错误日志记在syslog里(/var/log/messages)，客户端PHP，编译进去了IcePHP，调用的方法很简单。现在还存在一些问题，运行的时候会异常退出，还需要一段时间来解决，暂时加了只狗看着，一旦进程里没了就重新启动。</p>

<p>既然要跨平台通讯，就涉及对象描述，ICE使用Slice来对结构，类，方法等进行定义。完了以后服务器端，客户端都按这个来调用和实现。ICE内置的Linux 下后台Deamon实现方案非常简单，只需要从Ice::Service里派生出一个类来，实现run方法，在这个方法里创建adapter对象，并在adapter对象里添加Servants，然后激活这个adapter就可以了，网络层的通信都由ICE接管了。由于是基于tcp/ip的直接通信，比更高层的http通信效率要高很多。</p>

<p>在客户端实现时，我们也碰到了一些小麻烦。一个是内置的$ICE对象用的时候有时需要用global声明，否则可能会出错，另外由于默认情况下Slice中struct对应到php的类型是一个类的实例，而不是一个数组，所以在赋值给页面的时候，smarttemplate以及其它模板系统中可能都会存在问题，可以通过修改模板系统的数据赋值显示代码解决。</p>

<p>我们做了一些性能的测试，同样运行1千次请求，使用xml-rpc实现需要28秒左右，使用ICE实现，只需要3秒多，性能的差距还是很大的，同时在这个过程中没发现有内存泄露的情况，效果还比较理想。</p>

<p>最后感慨一下，ICE是适合人类使用的中间件！</p>]]></description>
<link>http://www.example.net.cn/2006/07/ice.html</link>
<guid>http://www.example.net.cn/2006/07/ice.html</guid>
<category>Example</category>
<pubDate>Thu, 06 Jul 2006 15:39:34 +0800</pubDate>
</item>

<item>
<title>mixi.jp：使用开源软件搭建的可扩展SNS网站</title>
<description><![CDATA[<p>于敦德 2006-6-27</p>

<p><a href="http://www.Mixi.jp">Mixi</a>目前是日本排名第三的网站，全球排名42，主要提供SNS服务：日记，群组，站内消息，评论，相册等等，是日本最大的SNS网站。Mixi从2003年12月份开始开发，由现在它的CTO - Batara Kesuma一个人焊，焊了四个月，在2004年2月份开始上线运行。两个月后就注册了1w用户，日访问量60wPV。在随后的一年里，用户增长到了21w，第二年，增长到了200w。到今年四月份已经增长到370w注册用户，并且还在以每天1.5w人的注册量增长。这些用户中70%是活跃用户（活跃用户：三天内至少登录一次的用户），平均每个用户每周在线时间为将近3个半小时。</p>

<p>下面我们来看它的技术架构。Mixi采用开源软件作为架构的基础：Linux 2.6，Apache 2.0，MySQL，Perl 5.8，memcached，Squid等等。到目前为止已经有100多台MySQL数据库服务器，并且在以每月10多台的速度增长。Mixi的数据库连接方式采用的是每次查询都进行连接，而不是持久连接。数据库大多数是以InnoDB方式运行。Mixi解决扩展问题主要依赖于对数据库的切分。</p>

<p>首先进行垂直切分，按照表的内容将不同的表划分到不同的数据库中。然后是水平切分，根据用户的ID将不同用户的内容再划分的不同的数据库中，这是比较通常的做法，也很管用。划分的关键还是在于应用中的实现，需要将操作封装在在数据层，而尽量不影响业务层。当然完全不改变逻辑层也不可能，这时候最能检验以前的设计是否到位，如果以前设计的不错，那创建连接的时候传个表名，用户ID进去差不多就解决问题了，而以前如果sql代码到处飞，或者数据层封装的不太好的话那就累了。</p>

<p>这样做了以后并不能从根本上解决问题，尤其是对于像mixi这种SNS网站，页面上往往需要引用大量的用户信息，好友信息，图片，文章信息，跨表，跨库操作相当多。这个时候就需要发挥memcached的作用了，用大内存把这些不变的数据全都缓存起来，而当修改时就通知cache过期，这样应用层基本上就可以解决大部分问题了，只会有很小一部分请求穿透应用层，用到数据库。Mixi的经验是平均每个页面的加载时间在0.02秒左右（当然根据页面大小情况不尽相似），可以说明这种做法是行之有效的。Mixi一共在32台机器上有缓存服务器，每个Cache Server 2G内存，这些Cache Server与App Server装在一起。因为Cache Server对CPU消耗不大，而有了Cache Server的支援，App Server对内存要求也不是太高，所以可以和平共处，更有效的利用资源。</p>

<p>图片的处理就显得相对简单的多了。对于mixi而言，图像主要有两部分：一部分是经常要使用到的，像用户头像，群组的头像等等，大概有100多GB，它们被Squid和CDN所缓存，命中率相对比较高；另一部分是用户上传的大量照片，它们的个体访问量相对而言比较小，命中率也比较低，使用Cache不划算，所以对于这些照片的策略是直接在用户上传的时候分发到到图片存储服务器上，在用户访问的时候直接进行访问，当然图片的位置需要在数据库中进行记录，不然找不到放在哪台服务器上就郁闷了。</p>

<p>文章参考：<a href="http://www.mysqluc.com/presentations/mysql06/mixi_update.pdf">Batara Kesuma在MySQL Users Con 2006上的发言</a></p>]]></description>
<link>http://www.example.net.cn/2006/06/mixijpsns.html</link>
<guid>http://www.example.net.cn/2006/06/mixijpsns.html</guid>
<category>Example</category>
<pubDate>Tue, 27 Jun 2006 20:23:06 +0800</pubDate>
</item>

<item>
<title>FeedBurner:基于MySQL和JAVA的可扩展Web应用</title>
<description><![CDATA[<p>于敦德 2006-6-27</p>

<p><a href="http://www.FeedBurner.com">FeedBurner</a>（以下简称FB，呵呵）我想应该是大家耳熟能详的一个名字，在国内我们有一个同样的服务商，叫做<a href="http://www.FeedSky.com">FeedSky</a>。在2004年7月份，FB的流量是300kbps，托管是5600个源，到2005年4月份，流量已经增长到5Mbps，托管了47700个源；到2005年9月份流量增长到20M，托管了109200个源，而到2006年4月份，流量已经到了115Mbps，270000个源，每天点击量一亿次。</p>

<p>FB的服务使用Java实现，使用了Mysql数据库。我们下面来看一下FB在发展的过程中碰到的问题，以及解决的方案。</p>

<p>在2004年8月份，FB的硬件设备包括3台Web服务器，3台应用服务器和两台数据库服务器，使用DNS轮循分布服务负载，将前端请求分布到三台Web服务器上。说实话，如果不考虑稳定性，给5600个源提供服务应该用不了这么多服务器。现在的问题是即使用了这么多服务器他们还是无法避免单点问题，单点问题将至少影响到1/3的用户。FB采用了监控的办法来解决，当监控到有问题出现时及时重启来避免更多用户受到影响。FB采用了Cacti(<a href="http://www.cacti.net">http://www.cacti.net</a>)和Nagios(<a href="http://www.nagios.org">http://www.nagios.org</a>)来做监控。</p>

<p>FB碰到的第二个问题是访问统计和管理。可以想象，每当我们在RSS阅读器里点击FB发布的内容，都需要做实时的统计，这个工作量是多么的巨大。大量写操作将导致系统的效率急剧下降，如果是Myisam表的话还会导致表的死锁。FB一方面采用异步写入机制，通过创建执行池来缓冲写操作；只对本日的数据进行实时统计，而以前的数据以统计结果形式存储，进而避免每次查看访问统计时的重复计算。所以每一天第一次访问统计信息时速度可能会慢，这个时候应该是FB在分析整理前一天的数据，而接下来的访问由于只针对当日数据进行分析，数据量小很多，当然也会快很多。FB的Presentation是这样写，但我发现好像我的FB里并没有今天实时的统计，也许是我观察的不够仔细-_-!</p>

<p>现在第三个问题出现了，由于大多数的操作都集中在主数据库上，数据库服务器的读写出现了冲突，前面提到过Myiasm类型的数据库在写入的时候会锁表，这样就导致了读写的冲突。在开始的时候由于读写操作比较少这个问题可能并不明显，但现在已经到了不能忽视的程度。解决方案是平衡读写的负载，以及扩展HibernateDaoSupport，区分只读与读写操作，以实现针对读写操作的不同处理。</p>

<p>现在是第四个问题：数据库全面负载过高。由于使用数据库做为缓存，同时数据库被所有的应用服务器共享，速度越来越慢，而这时数据库大小也到了Myisam的上限-4GB，FB的同学们自己都觉得自己有点懒&#61514;。解决方案是使用内存做缓存，而非数据库，他们同样使用了我们前面推荐的memcached，同时他们还使用了Ehcache(<a href="http://ehcache.sourceforge.net/">http://ehcache.sourceforge.net/</a>)，一款基于Java的分布式缓存工具。</p>

<p>第五个问题：流行rss源带来大量重复请求，导致系统待处理请求的堆积。同时我们注意到在RSS源小图标有时候会显示有多少用户订阅了这一RSS源，这同样需要服务器去处理，而目前所有的订阅数都在同一时间进行计算，导致对系统资源的大量占用。解决方案，把计算时间错开，同时在晚间处理堆积下来的请求，但这仍然不够。</p>

<p>问题六：状态统计写入数据库又一次出问题了。越来越多的辅助数据（包括广告统计，文章点击统计，订阅统计）需要写入数据库，导致太多的写操作。解决方案：每天晚上处理完堆积下来的请求后对子表进行截断操作：</p>

<p>–	FLUSH TABLES; TRUNCATE TABLE ad_stats0;</p>

<p>这样的操作对Master数据库是成功的，但对Slave会失败，正确的截断子表方法是：</p>

<p>– ALTER TABLE ad_stats TYPE=MERGE UNION=(ad_stats1,ad_stats2);</p>

<p>– TRUNCATE TABLE ad_stats0;</p>

<p>– ALTER TABLE ad_stats TYPE=MERGE UNION=(ad_stats0,ad_stats1,ad_stats2);</p>

<p>解决方案的另外一部分就是我们最常用的水平分割数据库。把最常用的表分出去，单独做集群，例如广告啊，订阅计算啊，</p>

<p>第七个问题，问题还真多，主数据库服务器的单点问题。虽然采用了Master-Slave模式，但主数据库Master和Slave都只有一台，当Master出问题的时候需要太长的时间进行Myisam的修复，而Slave又无法很快的切换成为Master。FB试了好多办法，最终的解决方案好像也不是非常完美。从他们的实验过程来看，并没有试验Master-Master的结构，我想Live Journal的Master-Master方案对他们来说应该有用，当然要实现Master-Master需要改应用，还有有些麻烦的。</p>

<p>第八个问题，停电!芝加哥地区的供电状况看来不是很好，不过不管好不好，做好备份是最重要的，大家各显神通吧。</p>

<p>这个Presentation好像比较偏重数据库，当然了，谁让这是在Mysql Con上的发言，不过总给人一种不过瘾的感觉。另外一个感觉，FB的NO们一直在救火，没有做系统的分析和设计。</p>

<p>最后FB的运维总监Joe Kottke给了四点建议：</p>

<p>1、	监控网站数据库负载。</p>

<p>2、	“explain”所有的SQL语句。</p>

<p>3、	缓存所有能缓存的东西。</p>

<p>4、	归档好代码。</p>

<p>最后，FB用到的软件都不是最新的，够用就好，包括：Tomcat5.0，Mysql 4.1，Hibernate 2.1，Spring，DBCP。</p>

<p>文章参考了<a href="http://www.mysqluc.com/presentations/mysql06/kottke_joe.pdf">Joe Kottke在MySQL Users Conference 2006上的发言</a>。</p>]]></description>
<link>http://www.example.net.cn/2006/06/feedburnermysqljavaweb.html</link>
<guid>http://www.example.net.cn/2006/06/feedburnermysqljavaweb.html</guid>
<category>Example</category>
<pubDate>Tue, 27 Jun 2006 13:58:23 +0800</pubDate>
</item>

<item>
<title>使用Red5和FFMpeg搭建在线Flash流媒体分享平台</title>
<description><![CDATA[<p>最近视频的东西比较火，前些天我也稍微了解了一下使用开源软件建在线Flash流媒体播放平台的解决方案，还是有一些收获。</p>

<p><a href="http://osflash.org/red5">Red5</a>是一款基于java的开源的Flash流媒体Server软件，可以作为取代Macromedia提供的商业版本FMS。Red5使用RSTP作为流媒体传输协议，内置了一些示例，这些示例实现了在线录制，flash流媒体播放，在线聊天，视频会议等一些基本的功能。由于系统本身是开源的，在碰到问题的时候也比较容易解决，大不了直接改代码，在成本方面也可以省下一笔不小的开销，为未来的功能扩展也提供了充分的空间。</p>

<p>如果仅仅是实现在线录制，在线播放，那么Red5也就差不多够了，但可能我们有时候还需要用户上传自己拍摄的视频文件，而要把这些视频文件转成可播放的flv文件就需要视频编码软件了。<a href="http://ffmpeg.mplayerhq.hu/">FFMpeg</a>提供了录制，播放，视频流处理的完整解决方案。它自身也带了一个基于HTTP的流媒体广播程序以及其它几个实用的程序，但我们的重点还是它的视频转换程序，似乎Google Video也是用的它的程序作为视频转换工具。</p>

<p>我用FFMpeg转了几个视频，效果还可以，在声音上碰到了一些问题，在不添加参数的情况下，有一部分视频的声音会有问题，有的视频无论怎么添加参数，都出不来声音，报错提示的是不支持所带的声音采样格式，只支持几种固定的格式，我看了一下代码，确实是这样子，但理论上应该是能够解决的。FFMpeg自带的libavcodec是一套很牛的编码库，为了保证质量和性能，里面的很多codec都是从头开发的。</p>

<p>这两个加起来，实现一些简单的在线视频功能就差不多了。</p>

<p>PS:今天刚看到古永锵也开始做小视频分享网站：<a href="http://www.yoqoo.com/index/">优酷</a>。</p>]]></description>
<link>http://www.example.net.cn/2006/06/red5ffmpegflash.html</link>
<guid>http://www.example.net.cn/2006/06/red5ffmpegflash.html</guid>
<category>Example</category>
<pubDate>Thu, 22 Jun 2006 10:34:27 +0800</pubDate>
</item>

<item>
<title>使用开源软件，设计高性能可扩展网站</title>
<description><![CDATA[<p>2006-6-17 于敦德</p>

<p>上次我们<a href="http://www.example.net.cn/archives/2006/03/olivejournaloio.html">以LiveJournal为例</a>详细分析了一个小网站在一步一步的发展成为大规模的网站中性能优化的方案，以解决在发展中由于负载增长而引起的性能问题，同时在设计网站架构的时候就从根本上避免或者解决这些问题。</p>

<p>今天我们来看一下在网站的设计上一些通常使用的解决大规模访问，高负载的方法。我们将主要涉及到以下几方面：</p>

<p>1、	前端负载<br />
2、	业务逻辑层<br />
3、	数据层</p>

<p>在<a href="http://www.example.net.cn/archives/2006/03/olivejournaloio.html">LJ性能优化文章</a>中我们提到对服务器分组是解决负载问题，实现无限扩展的解决方案。通常中我们会采用类似LDAP的方案来解决，这在邮件的服务器以及个人网站，博客的应用中都有使用，在Windows下面有类似的Active Directory解决方案。有的应用（例如博客或者个人网页）会要求在二级域名解析的时候就将用户定位到所属的服务器群组，这个时候请求还没到应用上面，我们需要在DNS里解决这个问题。这个时候可以用到一款软件<a href="http://www.example.net.cn/archives/2006/01/bind_dlz_oeeiei.html">bind dlz</a>，这是bind的一个插件，用于取代bind的文本解析配置文件。它支持包括LDAP，BDB在内的多种数据存储方式，可以比较好的解决这个问题。</p>

<p>另外一种涉及到DNS的问题就是目前普遍存在的南北互联互通的问题，通过bind9内置的视图功能可以根据不同的IP来源解析出不同的结果，从而将南方的用户解析到南方的服务器，北方的用户解析到北方的服务器。这个过程中会碰到两个问题，一是取得南北IP的分布列表，二是保证南北服务器之间的通讯顺畅。第一个问题有个笨办法解决，从日志里取出所有的访问者IP，写一个脚本，从南北的服务器分别ping回去，然后分析结果，可以得到一个大致准确的列表，当然最好的办法还是直到从运营商那里拿到这份列表(update:参见<a href="http://lyp.cn/study/digest/2006-07-04/296/apnic-whois.html">这篇文章</a>)。后一个问题解决办法比较多，最好的办法就是租用双线机房，同一台机器，双IP，南北同时接入，差一些的办法就是南北各自找机房，通过大量的测试找出中间通讯顺畅的两个机房，后一种通常来说成本较低，但效果较差，维护不便。</p>

<p>另外DNS负载均衡也是广泛使用的一种负载均衡方法，通过并列的多条A记录将访问随即的分布到多台前端服务器上，这种通常使用在静态页面居多的应用上，几大门户内容部分的前端很多都是用的这种方法。</p>

<p>用户被定位到正确的服务器群组后，应用程序就接手用户的请求，并开始沿着定义好的业务逻辑进行处理。这些请求主要包括两类静态文件(图片，js脚本,css等)，动态请求。</p>

<p>静态请求一般使用squid进行缓存处理，可以根据应用的规模采用不同的缓存配置方案，可以是一级缓存，也可以是多级缓存，一般情况下cache的命中率可以达到70%左右，能够比较有效的提升服务器处理能力。Apache的deflate模块可以压缩传输数据，提高速度，2.0版本以后的cache模块也内置实现磁盘和内存的缓存，而不必要一定做反向代理。</p>

<p>动态请求目前一般有两种处理方式，一种是静态化，在页面发生变化时重新静态页面，现在大量的CMS，BBS都采用这种方案，加上cache，可以提供较快的访问速度。这种通常是写操作较少的应用比较适合的解决方案。</p>

<p>另一种解决办法是动态缓存，所有的访问都仍然通过应用处理，只是应用处理的时候会更多的使用内存，而不是数据库。通常访问数据库的操作是极慢的，而访问内存的操作很快，至少是一个数量级的差距，使用<a href="http://www.example.net.cn/archives/2006/01/eoamemcachedoea.html">memcached</a>可以实现这一解决方案，做的好的memcache甚至可以达到90%以上的缓存命中率。10年前我用的还是2M的内存，那时的一本杂事上曾经风趣的描述一对父子的对话：</p>

<p>儿子：爸爸，我想要1G的内存。</p>

<p>爸爸：儿子，不行，即使是你过生日也不行。</p>

<p>时至今日，大内存的成本已经完全可以承受。Google使用了大量的PC机建立集群用于数据处理，而我一直觉得，使用大内存PC可以很低成本的解决前端甚至中间的负载问题。由于PC硬盘寿命比较短，速度比较慢，CPU也稍慢，用于做web前端既便宜，又能充分发挥大内存的优势，而且坏了的话只需要替换即可，不存在数据的迁移问题。</p>

<p>下面就是应用的设计。应用在设计的时候应当尽量的设计成支持可扩展的数据库设计，数据库可以动态的添加，同时支持内存缓存，这样的成本是最低的。另外一种应用设计的方法是采用中间件，例如<a href="http://www.zeroc.com/ice.html">ICE</a>。这种方案的优点是前端应用可以设计的相对简单，数据层对于前端应用透明，由ICE提供，数据库分布式的设计在后端实现，使用ICE封装后给前端应用使用，这路设计对每一部分设计的要求较低，将业务更好的分层，但由于引入了中间件，分了更多层，实现起来成本也相对较高。</p>

<p>在数据库的设计上一方面可以使用集群，一方面进行分组。同时在细节上将数据库优化的原则尽量应用，数据库结构和数据层应用在设计上尽量避免临时表的创建、死锁的产生。数据库优化的原则在网上比较常见，多google一下就能解决问题。在数据库的选择上可以根据自己的习惯选择，Oracle，MySQL等，并非Oracle就够解决所有的问题，也并非MySQL就代表小应用，合适的就是最好的。</p>

<p>前面讲的都是基于软件的性能设计方案，实际上硬件的良好搭配使用也可以有效的降低时间成本，以及开发维护成本，只是在这里我们不再展开。</p>

<p>网站架构的设计是一个整体的工程，在设计的时候需要考虑到性能，可括展性，硬件成本，时间成本等等，如何根据业务的定位，资金，时间，人员的条件设计合适的方案是件比较困难的事情，但多想多实践，终究会建立一套适合自己的网站设计理念，用于指导网站的设计工作，为网站的发展奠定良好的基础。</p>]]></description>
<link>http://www.example.net.cn/2006/06/open_source_high_performance.html</link>
<guid>http://www.example.net.cn/2006/06/open_source_high_performance.html</guid>
<category>Example</category>
<pubDate>Sun, 18 Jun 2006 00:22:47 +0800</pubDate>
</item>

<item>
<title>从LiveJournal后台发展看大规模网站性能优化方法</title>
<description><![CDATA[<p>于敦德 2006-3-16</p>

<h2>一、LiveJournal发展历程</h2>
<a href="http://www.livejournal.com">
LiveJournal</a>是99年始于校园中的项目，几个人出于爱好做了这样一个应用，以实现以下功能：
<ul><li>博客，论坛</li><li>社会性网络，找到朋友</li><li>聚合，把朋友的文章聚合在一起</li></ul>
LiveJournal采用了大量的开源软件，甚至它本身也是一个开源软件。

<p>在上线后，LiveJournal实现了非常快速的增长：</p>

<ul><li>2004年4月份：280万注册用户。</li><li>2005年4月份：680万注册用户。</li><li>2005年8月份：790万注册用户。</li><li>达到了每秒钟上千次的页面请求及处理。</li><li>使用了大量MySQL服务器。</li><li>使用了大量通用组件。</li></ul>

<h2>二、LiveJournal架构现状概况</h2>

<p><img alt="livejournal_backend.png" src="http://www.example.net.cn/archives/livejournal_backend.png" width="600" height="445" /><br />
 <br />
<h2>三、从LiveJournal发展中学习</h2></p>

<p>LiveJournal从1台服务器发展到100台服务器，这其中经历了无数的伤痛，但同时也摸索出了解决这些问题的方法，通过对LiveJournal的学习，可以让我们避免LJ曾经犯过的错误，并且从一开始就对系统进行良好的设计，以避免后期的痛苦。</p>

<p>下面我们一步一步看LJ发展的脚步。</p>]]></description>
<link>http://www.example.net.cn/2006/03/livejournal_optimize_step_by_step.html</link>
<guid>http://www.example.net.cn/2006/03/livejournal_optimize_step_by_step.html</guid>
<category>Example</category>
<pubDate>Thu, 16 Mar 2006 14:39:18 +0800</pubDate>
</item>

<item>
<title>imageMagick图片处理工具</title>
<description><![CDATA[<p><a href="http://www.imagemagick.org">ImageMagick</a>是一套Linux下的开源图形处理工具，针对几乎所有的图片格式提供比较全面的图片处理功能。不像windows下的photoshop，先要双击运行，然后打开图片，然后才能对图片进行处理，ImageMagick可以直接在命令行下运行，加上几个参数，就可以得到想要的图片了，而大批量的处理图片也比photoshop简单的多，写个shell多循环几次就可以了。</p>

<p>假如我想给图片加个框，转一下，再加个阴影，输入以下的命令就可以了：<br />
<pre class="code">convert -size 400x180 hatching.jpg  -thumbnail '200x90>' \<br />
    -bordercolor white  -border 6 \<br />
    -bordercolor grey60 -border 1 \<br />
    -background  none   -rotate 6 \<br />
    -background  black  \( +clone -shadow 60x4+4+4 \) +swap \<br />
    -background  none   -flatten \<br />
    -depth 8 -colors 256 -quality 95   poloroid.png<br />
</pre><br />
结果是这样：<br />
<center><img src=http://www.cit.gu.edu.au/~anthony/graphics/imagick6/thumbnails/poloroid.png></center></p>

<p>除了提供命令行工作，ImageMagick同样为各种语言(包括Java，perl,php,c/c++,pascal,python,ruby,tcl/tk等)提供了丰富的开发接口。开发人员可以直接使用这些接口对图片进行高质量，效果丰富的处理。这些都是ImageMagick处理的效果：<br><br />
<center><img src=http://static.flickr.com/29/102143439_8e9c71e8e1.jpg></center><br />
更多的效果：<a href="http://www.cit.gu.edu.au/~anthony/anthony.html">Anthony Thyssen</a>写的<a href="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/">使用帮助</a>，<a href="http://www.spymac.com/galleries/index.php">一些缩略图的效果</a>，<a href="http://www.drublair.com/subcat.asp?0=203">一些汽泡状缩略图效果</a>。ImageMagick还有个比较酷的功能是可以做图片的比较：<br />
   <img src="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/compare/bgnd_overlaid.png" alt="[IM Output]" border="1" height="125" hspace="5" vspace="5" width="100"><img src="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/w_images/bar.gif" alt="==&gt;" height="20" width="20"><img src="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/compare/bgnd.png" alt="[IM Output]" border="1" height="125" hspace="5" vspace="5" width="100"><img src="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/w_images/right.gif" alt="==&gt;" height="20" width="20"><img src="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/compare/overlay_extracted.png" alt="[IM Output]" border="0" height="125" hspace="5" vspace="5" width="100"></p>

<p>ImageMagick安装起来也相当方便，以php为例，需要下载两个包，一个是ImageMagick的包，一个是MagickWand的包，打包下载后运行：<br />
<pre class="code">tar zxvf imagemagick.tar.gz<br />
cd ImageMagick-xx-xx<br />
./configure --prefix=/usr/local/ImageMagick<br />
make && make install<br />
export PATH=$PATH:/usr/local/ImageMagick/bin<br />
</pre><br />
这样ImageMagick就装完了，可以直接在任何一个目录下面运行命令行的程序了。下面我们假设机器上已经装好了某个版本的php，运行：<br />
<pre class="code">tar zxvf MagickWand.tar.gz<br />
mv MagickWand-xx-xx /path/to/php-install/ext/<br />
cd /path/to/php-install/ext/MagickWand-xx-xx/<br />
phpize<br />
cd /path/to/php-install<br />
rm configure<br />
./buildconf --force<br />
./configure [options] --with-magickwand=/path/to/ImageMagick<br />
make && make install<br />
</pre><br />
这样php就可以使用ImageMagick提供的函数了。</p>]]></description>
<link>http://www.example.net.cn/2006/02/imagemagick.html</link>
<guid>http://www.example.net.cn/2006/02/imagemagick.html</guid>
<category>Example</category>
<pubDate>Mon, 20 Feb 2006 23:02:16 +0800</pubDate>
</item>

<item>
<title>bind dlz - 分布式系统的请求分发工具</title>
<description><![CDATA[<p><a href="http://bind-dlz.sourceforge.net/">bind dlz</a>全称是bind dynamic loadable zones，是基于bind的提供的一个组件，作用看名字就知道了，支持动态域加载支持。</p>

<p>bind已经有很久的历史，目前是搭建DNS服务器的首选。对于一般网站来说，一个标准的bind已经完全可以完成所有dns解决的工作，但在海量域名数量的情况下，bind也确实存在着一些问题：</p>

<p>1、域名解析信息全部存储在文本文件中，这非常容易导致由于编辑出错导致的域名解析出错。<br />
2、bind运行时将全部的解析信息放在内存里，如果数量巨大将可能出现内存不足的情况，同时解析信息重新加载时所耗费的时间也非常值得考虑，由于加载时间较长，所以基本可以不考虑动态的进行域名的调整。</p>

<p>dlz就是为了解决这个问题而针对bind开发的组件，可以将域名解析信息放在数据库中，从而避免域名信息变动时重新加载的时间，在变动后马上生效。</p>

<p>dlz支持多种数据存储形式，包括文件系统，Berkeley-DB，Postgre-SQL，MySQL，ODBC，LDAP等等。性能的比较在<a href="http://bind-dlz.sourceforge.net/perf_tests.html">这里</a>。</p>

<p>bind dlz这种提供动态的域名调整，并且仍然可以提供高性能的dns解析服务的特点可以应用于提供二级或三级域名服务的分布式系统的前端，对不同的域名解析到所在服务器组上，从而实现可扩展的系统架构。</p>]]></description>
<link>http://www.example.net.cn/2006/01/bind_dlz.html</link>
<guid>http://www.example.net.cn/2006/01/bind_dlz.html</guid>
<category>Example</category>
<pubDate>Thu, 19 Jan 2006 21:12:49 +0800</pubDate>
</item>

<item>
<title>使用memcached进行内存缓存</title>
<description><![CDATA[<p>旧文重发<br />
2005.8.9</p>

<p>通常的网页缓存方式有动态缓存和静态缓存等几种，在ASP.NET中已经可以实现对页面局部进行缓存，而使用memcached的缓存比ASP.NET的局部缓存更加灵活，可以缓存任意的对象，不管是否在页面上输出。而memcached最大的优点是可以分布式的部署，这对于大规模应用来说也是必不可少的要求。<br />
LiveJournal.com使用了memcached在前端进行缓存，取得了良好的效果，而像wikipedia,sourceforge等也采用了或即将采用memcached作为缓存工具。memcached可以大规模网站应用发挥巨大的作用。</p>]]></description>
<link>http://www.example.net.cn/2006/01/memcached.html</link>
<guid>http://www.example.net.cn/2006/01/memcached.html</guid>
<category>Example</category>
<pubDate>Fri, 13 Jan 2006 02:58:23 +0800</pubDate>
</item>

<item>
<title>CMS系统的演进</title>
<description><![CDATA[<p>CMS即Content Management System，一般用于网站的内容组织发布。不严格的意义上来看，博客系统也可以算是一个小型的CMS系统。最近做了一个小的CMS系统，感悟不少。</p>

<p>CMS最基本的功能当然是文章发布系统，后台提供一个文章管理的功能，前面将文章显示出来，按照栏目进行组织。当然，栏目，用户，权限管理等基本功能也是必不可少。</p>

<p>开始文章的显示是动态的，每次有人看都执行一下，然后把页面显示出来。后来发布动态的发布虽然实现简单，但即有着一些天然的缺陷。例如抵御大规模的访问，虽然可以通过缓存来进行解决，但毕竟无法从根本上解决这个问题。还有就是文章浏览与管理集中，依赖于同一数据源，一台数据源出现问题两个服务都无法正常提供。在这个条件下很多CMS就提供了静态化的发布方式，文章以静态文件发布出去后与CMS系统没有直接的关系，无论是访问速度，还是可靠性都得到大幅的提高。</p>

<p>Content的指的是内容，并不单纯是文章，而互联网的逐步发展使用户已经不满足于简单的文本阅读，于是CMS又添加了图文混排的功能，开始是单图，然后进一步是组图。<br />
图片加上了以后，很多网站发布每天发布这么多文章实际上有很多文章是转载来的，如果能够自动的将别人网站的文章抓过来，编辑打勾就可以直接发布效率就高的多了，于是各种抓站系统又成了CMS的标准配置。这里面值得称道的是donews的CMS系统，看到一个喜欢的网页，直接右键保存，系统可以自动分析html页面，并将关键数据取出，点一下确定就可以发布，实在是非常方便。而且可以自动取出关键字，并在文章之间根据关键词形成关联。</p>

<p>在这个过程中模板系统也逐渐产生了。以前的模板多是由技术人员手工开发。例如做一个首页，页面上各个区块的逻辑确定后都手动写代码，写死后很难改变。这样子倒没有错误，只是模板制作效率非常低下，新做或修改模板非常麻烦。在这个条件下就促使开发人员将模板做进一步处理。模板一般会被切分成碎片，碎片有几种类型，文本，图片，广告，列表。前面三种都是简单的对html进行分块处理，列表是动态的功能，负责在发布的时候动态的组织内容。这样子就很方便了，可以很快的做出一个模板，加上模板复制的功能就更加如虎添翼。</p>

<p>目前新浪的CMS是C++做的，重点强调数据结构的丰富，功能非常强大，评论系统做的也不错。评论系统做的最好的是网易，它的延伸阅读做的也不错。Sohu的图库做的不错。</p>

<p>以后CMS发展的方向我认为很大的一方面是内容的相关组织。目前各大网站最常用的提高访问量的招数就是在文章页底添加相关链接，一般是比较火暴的文章和图片，提升访问量非常显著。但这种方式比较死板，每篇文章下面的内容都一样，用户点了一次就不会点第二次。理想的效果是在文章下面添加相关的文章，而且不仅仅局限于CMS内部，应该将站外的相关内容都添加进去，只要用户觉得方便，别怕他不回来。</p>

<p>另外一个方向就是内容来源多样化。例如新浪的CMS，目前似乎只能对手发文章进行比较好的管理，对于iask的内容，对于论坛的内容都是手动的编辑，目前似乎还能满足需要，但从长期来看，是肯定要变的。如果没有RSS的出现，内容来源的多样化还是一句空话，RSS出现后，站内的内容，站外的内容都可以通过RSS来传递。</p>

<p>互联网的入口开始是门户，后来成了搜索引擎，就是因为搜索引擎可以提供来源多样化的内容，一个网站再大也只是一个网站，做再多的频道也就是一个网站，无法满足用户对于多样化，个性化的需要。未来的入口是什么，现在还说不定，但肯定是要对用户的胃口，不能我给你什么，你就看什么，而是看谁能提供给我最想看的东西，让我最少的动脑动手。</p>

<p>我认为未来内容分化为两部分的趋势会逐渐显现出来。一部分提供底层的内容，博客服务提供商以及社区服务提供商会是主力，门户也是重要组成部分；另外一部分仅仅对内容进行组织，充当入口，只提供内容的链接，并不实质的存放内容。</p>

<p>Google的ig是一个例子，微软的Live站略中RSS Live也是重中之重，Yahoo最近也提供了个性化的门户，这些都是引子，慢慢的戏会越来越好看。</p>

<p>发文庆祝CMS完成，小小的展望一下未来，继续做事。</p>]]></description>
<link>http://www.example.net.cn/2005/11/cms.html</link>
<guid>http://www.example.net.cn/2005/11/cms.html</guid>
<category>Example</category>
<pubDate>Wed, 09 Nov 2005 21:53:39 +0800</pubDate>
</item>

<item>
<title>Skype的主要功能-Skype通讯协议分析(3)</title>
<description><![CDATA[<p>Skype的功能主要可以分为：初始化，登录，用户搜索，呼叫建立与终止，媒体传输和状态消息。</p>

<p>1、初始化<br />
第一次安装后，Skype会发送一段HTTP 1.1的请求给中央服务器，包括关键字"installed"以及所装Skype的版本号。以后的每次登录Skype都会向中央服务器发送一小段包含关键字"getlatestversion"的HTTP 1.1请求，检查是否有新版本的Skype。</p>]]></description>
<link>http://www.example.net.cn/2005/01/skypeskype3.html</link>
<guid>http://www.example.net.cn/2005/01/skypeskype3.html</guid>
<category>Example</category>
<pubDate>Sun, 30 Jan 2005 20:41:02 +0800</pubDate>
</item>

<item>
<title>Skype的主要组成部分-Skype通讯协议分析(2)</title>
<description><![CDATA[<p>1、端口<br />
在Skype的连接属性对话框中可以设置监听的端口号，在安装的时候Skype会随机的选择一个端口作为监听的端口，这一点与HTTP协议等不同，Skype没有默认的服务端口。同时，它还会打开对80和443端口的监听。80是常见的HTTP服务默认端口，而443则是HTTPS服务的默认端口。<br />
2、主机列表(HC，Host Cache)<br />
这里的主机指的是可以提供踏板及广播服务的Super Node(SN)。通常它被存储在注册表里的：HKEY_CURRENT_USER / SOFTWARE / SKYPE / PHONE / LIB / CONNECTION / HOSTCACHE 中.一般情况下，运行两天后，HC中会有约200个机器地址及对应的端口号。</p>]]></description>
<link>http://www.example.net.cn/2005/01/skypeskype2.html</link>
<guid>http://www.example.net.cn/2005/01/skypeskype2.html</guid>
<category>Example</category>
<pubDate>Sun, 30 Jan 2005 13:51:03 +0800</pubDate>
</item>

<item>
<title>Skype通讯协议分析(1)</title>
<description><![CDATA[<center><img src=http://www.skype.com/i/logos/skype.png border=0 title="skype"></center>
晚上在看Salman A. Baset和Henning Schulzrinne写的《An Analysis of the Skype Peer-to-Peer Internet Telephony Protocol》。因为Skype的通讯协议是不公开的，而且通讯内容是加过密的，这两位完全在实验的基础上对Skype的通讯机制进行分析，分析结果很有参考价值。

<p>通过分析得出的结论主要有三个：<br />
1、Skype的通话质量较MSN和Yahoo的即时通信工具要好；<br />
2、可以无缝的在NATs和防火墙后使用；<br />
3、安装使用起来确实非常简单。<br />
<center><img alt="skype_network.gif" src="http://www.example.net.cn/upload/skype_network.gif" width="301" height="542" /></center></p>]]></description>
<link>http://www.example.net.cn/2005/01/skype1.html</link>
<guid>http://www.example.net.cn/2005/01/skype1.html</guid>
<category>Example</category>
<pubDate>Sun, 30 Jan 2005 01:50:36 +0800</pubDate>
</item>

<item>
<title>awk学习笔记</title>
<description><![CDATA[<p>awk是一种用于处理数据和生成报告的编程语言。<br />
一般的使用格式是：<br />
<blockquote>awk '{pattern + action}' {filenames} </blockquote><br />
pattern指在每一行中进行匹配的条件，action指针对符合条件的行进行的操作，filenames是输入的文件名。<br />
假设data文件中有以下数据：<br />
<blockquote>1 donald 305 20050129<br />
2 chin 102 20040129<br />
3 mark 304 20040229</blockquote><br />
<strong>下面对这个文件进行操作:</strong><br />
<blockquote>awk '{print $1, $2, $3, $4}' data</blockquote><br />
输出:<br />
<blockquote>1 donald 305 20050129<br />
2 chin 102 20040129<br />
3 mark 304 20040229</blockquote><br />
<hr><br />
<blockquote>awk '{print $1"\t", $2"\t", $3"\t", $4}' data</blockquote><br />
输出:<br />
<blockquote>1        donald  305     20050129<br />
2        chin    102     20040129<br />
3        mark    304     20040229</blockquote><br />
这里显示的格式并不是输出的真实格式，真实格式是中间会有一个tab符号，格式对的很整齐，只不过在html里看不出来。</p>]]></description>
<link>http://www.example.net.cn/2005/01/awk.html</link>
<guid>http://www.example.net.cn/2005/01/awk.html</guid>
<category>Example</category>
<pubDate>Sat, 29 Jan 2005 20:40:29 +0800</pubDate>
</item>


</channel>
</rss>