2009年12月22日星期二

replay

发现最近的生活,越来越重复了。怎么说呢?每天早上起来,照例刷牙洗脸,吃饭出门。走在南泉路上,会看到一辆119。拐到兰村路上,会看到一个黑衣MM,对面走过来。人很漂亮,一般是在打手机,否则就是拿手机听歌。前走一点,有个保安在和卖煎饼的聊天,一个抽烟一个翻煎饼,每天的差异差不多就是有客户和没客户而已。再往前,在东方路前会碰到一个辫子MM走出来,辫子很长,从后面看很漂亮。不过记住,如果你不想对世界失去信心,一定要走在她后面。走在前面千万不要回头,无论是有人喊你还是后面有车要70码你。我头次很好奇的回了个头,结果一天都无法正常工作。走到东方路,有八成概率是一堆人在等红灯。恭喜,这代表你会在20秒内碰到绿灯――平均值通常是5秒。
上地铁后就更规律了,如果一堆人在等车,那车上肯定也是一堆人,你如果被挤上去就算是走运了。相反,如果只有小猫两三只,那么车上多半也没有人,慢慢走上去就好。到了世纪大道换车,就可以开电脑放音乐,头一首歌照例是《钢之炼金术士2009》的片头。到了张江,有车停左边和车停右边两个选项。不过没有关系,凡是在进站前停车的,就是左边,否则是右边。因为车要靠右开,停靠右边站台的车在开出时,换到左边(相对他是右边),而我们的车在进站时要靠左,也需要换边。不停车怕又碰到昨天一号线的事故,因此惯例是要停车的。
地铁下来后,有两个红绿灯,第一个灯是20秒横走40秒直行,因此多数会直行过去。第二个灯是50秒横走20秒直行,因此多数会横向过街。联合以上数据计算概率,两次直行的概率是19%,先直行后过街的概率是47.6%,先横后直行的概率是33.3%。没有觉得什么不对?看来又多一个走傻掉的。计算以上概率的方法是分支法,联合概率乘法?我没事先过个街,第二个路口走回来?那不真傻了?
最后,到办公室。一般这时候是王菲在唱《只有我自己》。如果刚唱到"走过千山万水",那说明地铁走的还是挺快的。如果已经到了"失去你,就失去,面对孤独的勇气",那――要么是地铁走的慢了,要么是你走的慢了。

2009年12月7日星期一

论BTchina的倒掉

    BTchina倒了,死的很惨。被广电总局直接勒令关闭,连整改的机会都没有。无疑,大家都知道,VeryCD会紧随其后。无论是非如何,请允许我先向这两家陪伴我多年的网站道声感谢,一路走好。
    就打击这个问题来说,我无疑是赞成的。广电总局打击集中向两个关键词,盗版和非法。无论哪个,都是应该打击的对象。但是这次打击本身却值得怀疑,主要集中在三点,是否允许整改,选择性执法,还有实际效果。
    首先,拿整改问题来说。BTchina和VeryCD做的是下载业务,其中有盗版下载再正常不过。一般打击都是先责令整改,然后再关服务器——虽然我们知道责令也不见什么效果,BTchina肯定改不过来的。不过样子还得做啊。不过从某种意义上说,样子做不做也就是政府内部的事情。无论做不做都是合理合法的,所以这点问题还不大。
    其次,我质疑比较大的一点,就是选择性执法。有个朋友说的比较精辟,每只猫都有他的目的。我总是不惮以最大的恶意来揣测咱们的政府——他们这回想干啥?如果要打击盗版,那问题严重了去了。中国桌面上,十有八九都是盗版Windows。哪怕你买了个笔记本,上面带了个正版Vista,一般也非要装个番茄花园不可。中国人看的电影,听的歌,乃至于用的手机,都是盗版产品。所以从这个角度说,我到真的很愿意国家打击盗版。盗版没了我们的软件才更好卖,盗版没了才有人被逼用Linux,盗版没了我们这行才能赚钱。不过咱得看事实,不能听风就是雨,更不能YY。广电总局要真有决心打击盗版,首先应该奔着卖盗版盘和卖盗版书的去——虽然他们也被互联网下载整的生不如死。问题是,他们没有。
    那,会不会是打击非法音像呢?这话说的更搞笑了。BTchina和VeryCD上有没有色情我不敢说,不过要有也绝对少于新华网。这不是指责新华网有多色情,而是阐述两者身为不同主体的无奈事实。BTchina和VeryCD要是碰到色情门那是沾上就死抡上就亡。作为半国企的新华网,就算偶尔行为出格,只要不出大差错无非就是检讨一下而已。这种情况下,前两家的审查力度,和后一家怎么可能同日而语?实话说,我当初还非常努力的试图在VeryCD上找什么色情资料。只能说他们的版主比较尽责,连疑似的都没有。要打击非法音像,还得找小网站——就是那种准备烧一把就走的。除非碰上严打,否则等查处来的时候,人都没了。
    那我就得怀疑了,广电总局想干啥呢?说打击盗版,不像,说打击非法音像,也不像。这事情我怎么看怎么觉得像上海政府查处黑车,黑车不黑车不重要,重要的是规范正当市场——说白了就是交钱。百度百科也涉嫌抄袭Wikipedia啊,怎么没看广电局找他们麻烦呢?人家3000万春晚赞助可不是白交的。
    那这事靠不靠谱呢?我只能说,越来越不靠谱了。从本心来说,我希望打击盗版,但是从现实而言,无论是美国政府,欧洲诸国政府,还是中国政府,对打击盗版都没啥办法。前两者有海盗党——当然,他们也被人盗版了他们的logo,真是讽刺。后者则有1亿多网民,每天发明各种奇怪的办法。现在的网民水准是越来越高了,或者说软件是越来越傻瓜了。原来下载必须在中心节点上投入大量资金,而且政府一来就玩完了。后来则是中心节点上只要搭个论坛,剩下的自然有P2P软件搞定。现在,根本就没中心节点。DHT的普及,使得去中心化的优势体现的淋漓尽致。Emule里面可以用kad搜索,直接搜索你需要的资源——正常情况下不比VeryCD差。而torrent里面则有个种子市场,可以直接搜索你要的种子。
    好家伙,连服务器都不要了,这次广电局再要下手,只有从网络传输上下手了——中国为了解决轮子问题,为GFW投资了不少钱。不知道广电局是否能收到足够的钱,把这个系统扩大个几倍,把P2P的混淆协议也全概括进去。作为一个老程序员,我劝诫所有的下载者一点。下次再弄的时候,用emule的kad搜索来找你需要的资源,你会发现其实verycd也不是必须的——虽然对他们来说,这是个比广电局查处更不利的消息。

2009年12月6日星期日

用python实现webserver(二)――Thread

    我们上面说过,Prefork模式有着先天的缺陷。针对http这种大量短请求的应用(当然,http1.1以来,有不少客户端使用了长连接),Prefork的最高并发很让人不满。并且,无论是否高并发,Prefork的性能都非常不好。现在我们介绍一下Thread模式。
    和Prefork非常类似,每Thread模式通过新建的线程来控制对象的传输。和Prefork模式不同的是,一个用户能够建立多少个线程并没有限制。在系统上似乎有限制,65535个,但是同样,文件句柄最高也就能打开65535个,因此通常而言一个服务器最高也就能顶50000并发,无法再高了(nginx就能够支撑5W并发,再高要使用一些特殊手法来均衡负载)。而且线程的建立和销毁的开销非常小——没有独立的空间,不用复制句柄,只要复制一份栈和上下文对象就可以。但是,由于所有线程运行在同一个进程空间中,因此每线程模式有几个非常麻烦的瓶颈。
    首先是对象锁定和同步,在每进程模式中,由于进程空间独立,因此一个对象被两个进程使用的时候,他们使用了两个完全不同的对象。而线程模式下,他们访问的是同一个对象。如果两个线程需要进行排他性访问,就必须使用锁,或者其他线程同步工具来进行线程同步。其次,由于使用同一个进程空间,因此一旦有一个连接处理的时候发生错误,整个程序就会崩溃。对于这一问题,可以通过watchdog方式来进行部分规避。原理是通过一个父进程启动子进程,子进程使用每线程处理请求。如果子进程崩溃,父进程的wait就会返回结果。此时父进程重启子进程。使用了watchdog后,服务不会中断,但是程序崩溃时正在处理的连接会全部丢失。最后,是python特有的问题——GIL。由于GIL的存在,因此无论多少线程,实际上只有一个线程可以处理请求,这无形中降低了效率。下面我们看一下Thread模式的测试结果:
测试指令: ab -n 1000 -c 100 http://localhost:8000/py-web-server
返回结果:
Document Path:          /py-web-server
Document Length:        1682 bytes

Concurrency Level:      100
Time taken for tests:   3.834 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1723000 bytes
HTML transferred:       1682000 bytes
Requests per second:    260.85 [#/sec] (mean)
Time per request:       383.362 [ms] (mean)
Time per request:       3.834 [ms] (mean, across all concurrent requests)
Transfer rate:          438.91 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   75 468.4      0    3001
Processing:     2   32  84.0     20    1593
Waiting:        1   30  84.0     18    1592
Total:          2  107 511.0     20    3828

测试指令: ab -n 10000 -c 1000 http://localhost:8000/py-web-server
返回结果:
Document Path:          /py-web-server
Document Length:        1682 bytes

Concurrency Level:      1000
Time taken for tests:   37.510 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      17231723 bytes
HTML transferred:       16821682 bytes
Requests per second:    266.60 [#/sec] (mean)
Time per request:       3751.004 [ms] (mean)
Time per request:       3.751 [ms] (mean, across all concurrent requests)
Transfer rate:          448.62 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  695 2422.8      0   21004
Processing:     0   67 341.1     28    9855
Waiting:        0   64 340.5     26    9855
Total:          0  762 2516.6     29   30856

    根据结果可以看到,Thread模式在1000并发的时候还工作良好,每秒处理请求数在250-300req/sec,但是每个请求的总处理时间已经高达760ms。并且从中我们可以看出,大量的时间都是消耗在等待上,说明线程的建立逐渐成为问题(为什么?下面说明)。实际性能测试的结果,也表明大约一半的时间花费在了等待上,而另一半花费在了线程建立上。加上销毁的开销,整个系统主要的瓶颈在于由于大量线程建立和销毁造成的CPU开销上。
    结合上述情况,我们同时也想到一些问题,Thread模式在一个进程中,到底能创建多少个线程?上文上说大约是5W个,其实太理论了。实际上如果按照Windows来计算,最高不超过1000个,Linux下也在这个数量级上。为什么?由于进程内存空间的问题。一个线程在创建时,默认需要1M的内存空间来作为栈。对于专用的高速系统,我们建议将这个值调整到500K,一般一个session的内存消耗就在500K上下,考虑还有堆消耗,500K是一个比较安全的值。单一进程,32位访问的寻址空间是4G,然而系统需要使用其中的2G作为系统空间——这一状态可以经由启动时的3G参数调整(针对Windows)。然而由于使用了系统空间,因此系统中很多表项空间不足,对稳定性也有不利影响,通常我们建议不要进行这种“优化”。而系统的基础使用和库使用需要数百M的空间,安全起见,能够自由的用于栈的可分配自由空间只有1G的大小。这1G的空间,以创建1M的栈计算,只能同时开1000线程。这就是单一进程中线程的极限。
    实际上,是根本做不出这么多的线程的。贝壳的小型测试机上只观测到过10-20个线程/每进程。这是由于线程的建立也需要时间,在创建下一个线程之前,工作进程已经跑了一些了。创建几个工作线程后,第一个工作线程已经完成工作。因此我们在实际中看到的是,压力越高,连接建立的速度越慢。因为负责创立新线程的线程获得越少的CPU时间用于工作。为了增加处理速度,通常我们可以采取一个CPU建立一个进程的策略,这被称为多线程/多进程模式。下面我们来测量其工作效率:
测试指令: ab -n 10000 -c 1000 http://localhost:8000/
返回结果:
Document Path:          /
Document Length:        3318 bytes

Concurrency Level:      1000
Time taken for tests:   20.319 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      33590000 bytes
HTML transferred:       33180000 bytes
Requests per second:    492.14 [#/sec] (mean)
Time per request:       2031.939 [ms] (mean)
Time per request:       2.032 [ms] (mean, across all concurrent requests)
Transfer rate:          1614.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  160 912.4      0    9008
Processing:     0   28 174.7     12    4738
Waiting:        0   27 174.3     12    4738
Total:          0  188 987.5     13   12758

    这是台双核的机器,性能差不多提升了一倍,这就是多进程/多线程模式的威力。按照这个数据外推,在常见的8核处理器上,将达到2000req/sec的处理速度,甚至更高。
    当然,也不用高兴太早,我们看一下apache2的每线程模式:
测试指令: ab -n 10000 -c 1000 http://localhost:8000/
返回结果:
Concurrency Level:      1000
Time taken for tests:   6.147 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      3213925 bytes
HTML transferred:       453375 bytes
Requests per second:    1626.87 [#/sec] (mean)
Time per request:       614.678 [ms] (mean)
Time per request:       0.615 [ms] (mean, across all concurrent requests)
Transfer rate:          510.61 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0  111 398.3     59    3087
Processing:    28  126  99.0    113    1772
Waiting:       10  104  98.7     92    1745
Total:         78  237 423.1    175    3691

Percentage of the requests served within a certain time (ms)
  50%    175
  66%    188
  75%    207
  80%    217
  90%    235
  95%    256
  98%   1016
  99%   3222
 100%   3691 (longest request)
    这种效率在8路的CPU上,性能将达到6400req/sec。所以想用python实现真正高效的前端本身就是个错误的逻辑。

2009年11月10日星期二

MSN强制升级

    从前天开始,单位里的MSN8.5就无法登陆,老是提示我要升级。今天家里的MSN也无法使用了,被逼无奈,先用pidgin顶一阵再说。不过现在贝壳正在考虑MSN的用户搬迁工作,目标是迁移到Gtalk上,不行QQ。
    有几个朋友问贝壳,升级不就好了,何必兴师动众呢?首先,MSN8.5的安装程序只有20M,而MSN9的安装程序高达132M。其中多出来的100多M东西可不是白装的,他们大概会吃掉你30-40M的内存。而且9里面有很多插件(其实8.5也有,不过就一个,总算还好屏蔽),安装上去后,工作的时候做调试麻烦异常,工作机器上装这个纯粹给自己找麻烦呢。而且微软素行不良,有劣迹在前。盗版黑屏问题大家还记得吧?升级提示上说是安全修补补丁,结果装上去屏幕就黑了。不说黑屏现在如何了,就说这种欺骗用户安装的手段,有谁还相信这次的强制升级是为了安全问题么?微软系统安全是出了名的差,一个安全公司用测试用蠕虫在win7上跑,只有20%不到能被微软自己拦截。其中固然有安全公司危言耸听,但是测试过程是全公开的,做假不来。这还是微软主推的最新操作系统,安全性据说很好。如果真是为了安全问题,先把Windows里面那堆雷死人的安全问题解决了才是王道。
    反倒是QQ的强制升级政策我觉得尚算可以。 QQ协议分为2005/2006/2007/2008多个版本,通常而言可以使用当前版本和前一版本。就是说,现在用的协议是2008的话,那么2007协议还可用,而2006协议就不再支持了。通常而言,这种时候继续使用2006协议的人微乎其微,基本可以忽略不计。这个政策主要是给不愿意升级的人一个缓冲的空间。对于腾讯而言,实施这个政策其实比微软更有压力。因为微软的协议是公开的,而腾讯则是采取封闭协议,甚至打击第三方客户端的企业策略。我们姑且不论这个策略的得失,但是维持两个协议版本,就给破解协议的人留下了破解的时间和空间。因此对于腾讯而言,这个策略是和公司战略相违背的。
    更深一层的问题是,强制升级问题说明了我们所依赖的服务的脆弱性。MSN在中国占据的客户群体并不算大,远远不比QQ。然而就是这样一个客户群现状,微软就敢于强制升级。今天是强制升级,明天收费呢?所以说任何事情依赖一个公司是不行的。我还是会使用MSN,但是会逐步将用户迁移到Gtalk和QQ上,并以开心网和Facebook做补充。力争做到这三个IM中任意两个能覆盖大部分朋友群体,开心和Facebook保留所有联系可能。这样可以适当制衡某些软件公司(不仅是微软,还有腾讯),也可以减小出问题时的损失。
    其实要做到这点并没有任何困难。当你认识一个人的时候,只要和他保持两种以上的IM,并且在开心和Facebook(当然,这个没法强求了,毕竟中国的GFW...)上交换一下好友就好了。对抗强权,从小事做起就好。

2009年10月20日星期二

用python实现webserver(一)――Prefork

    要实现webserver,首先需要一个tcp server。作为python的设计原则,最好是使用SocketServer或者封装更好的BaseHTTPServer来复用。不过既然我们的目的 是为了学习,那么就不能用这两个内置对象。我们先实现一个最古典的每进程模式实现。而我们标题上的Prefork,则是apache服务器对这个模式的称 呼。
    每进程模式,顾名思义,就是每个新连接开启一个进程进行处理。首先创建一个socket,bind到一个套接字上。当有请求时,accept。(好多英 文,不是我有意cheglish,全是api的名称)accept会返回一个通讯用的socket,这时fork出一个新的进程,处理这个socket。 主进程在每次进入accept后阻塞,子进程在每次进入recv后阻塞。这样会带来几方面的好处。首先是模型分离,即使一个子进程崩溃,也不会影响到其他 子进程。其次是身份分离,当你需要让http server以高于常规运行(常规都是以apache, www-data, nobody运行的)用户的权限进行工作时,每进程模式是唯一安全的模式。其他模式都会造成同一进程内的其他session也暂时获得这个权限的问题。但 是同样,这样有几方面的问题,主要就是性能问题。
    由于每个连接都需要fork出一个新进程去处理。因此针对大量小连接的时候,fork和exit消耗了大量CPU。问题更严重的是,由于用户进程总数是有 限的(PEM或者ulimit都会限制这个数量),因此压力大到一定程度时(通常是1024或者2048),就会出现无法创建连接的情况。而对小型服务器 而言,在压力还没大道这个程度以前,服务器就会由于性能达到限制而造成段错误。以下是实际试验指令和结果:
测试指令: ab -n 10000 -c 100 http://localhost:8000/py-web-server
服务器报错:
[20090924 05:51:18]: Traceback (most recent call last):
[20090924 05:51:18]:   File "main.py", line 19, in <module>
[20090924 05:51:18]:
[20090924 05:51:18]: sock.run ();
[20090924 05:51:18]:   File "/home/shell/py-web-server/server.py", line 30, in run
[20090924 05:51:18]:
[20090924 05:51:18]: while loop_func (): pass
[20090924 05:51:18]:   File "/home/shell/py-web-server/server.py", line 56, in do_loop
[20090924 05:51:18]:
[20090924 05:51:18]: if os.fork () == 0:
[20090924 05:51:18]: OSError
[20090924 05:51:18]: :
[20090924 05:51:18]: [Errno 11] Resource temporarily unavailable

测试指令: ab -n 1000 -c 100 http://localhost:8000/py-web-server
返回结果:
Document Path:          /py-web-server
Document Length:        1320 bytes

Concurrency Level:      100
Time taken for tests:   14.189 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      1361000 bytes
HTML transferred:       1320000 bytes
Requests per second:    70.48 [#/sec] (mean)
Time per request:       1418.851 [ms] (mean)
Time per request:       14.189 [ms] (mean, across all concurrent requests)
Transfer rate:          93.67 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   18 328.4      0    9000
Processing:     4  109 211.0     95    3335
Waiting:        4  100 211.1     86    3324
Total:          8  127 498.3     95   12332

    为什么只有100并发?因为200并发的时候测试机上的服务器已经崩溃了。而且我们看到服务器的效率大约是70req/sec。等过两天,讲到 Thread模式的时候,大家可以对比一下Thread模式的效率。基本上说,针对普通服务器,个人觉得Prefork模式并发数量尽量控制在 100-800这个级别比较合适。更高的也许能承受,可是就可能发生不稳定(原因上面有说,就是进程数量限制)。那么Prefork模式通常用在哪里呢? 数据库!Oracle和Postgresql全是Prefork模式的(其中Oracle的Prefork模式还经过一次分发,更复杂一些)。压力通常在 100-200这个级别,连接基本不断开,连接的请求和销毁开销很小,但是处理的过程开销很大。并且,由于处理过程复杂,一个链接的处理错误不能殃及整个 系统。对于这种问题,最好采用Prefork模式进行处理。同类的问题还有一些EJB服务器,复杂中间件等等。
    那么反过来,作为客户,我在面对Prefork模式的时候,如何才能高效处理呢?——对,大家都想到了,连接池模式。通过连接池存放空闲连接,避免连接的建立和释放开销,从而增加服务器性能。
    另外,python实现其实性能是很有问题的,我们对比一下apache2的测试结果:
测试指令: ab -n 1000 -c 100 http://localhost:8000/py-web-server
返回结果:
Document Path:          /
Document Length:        45 bytes

Concurrency Level:      1000
Time taken for tests:   7.914 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      3204355 bytes
HTML transferred:       452025 bytes
Requests per second:    1263.56 [#/sec] (mean)
Time per request:       791.413 [ms] (mean)
Time per request:       0.791 [ms] (mean, across all concurrent requests)
Transfer rate:          395.40 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   70 432.8      3    3028
Processing:     0  193 733.0     88    6629
Waiting:        0  190 732.4     85    6621
Total:         46  263 950.7     93    7895

--
与其相濡以沫,不如相忘于江湖

2009年10月9日星期五

用python实现webserver(零)――导言

    本系列文章的所有代码,都发布在http://code.google.com/p/py-web-server/。项目的目的,是通过写作一个可用的http web server,学习服务器程序编写中的一些方法,以及http协议的细节。
    如同我在项目介绍中说的,项目遵循以下几个设计原则。
  1. 精简,容易阅读和学习。
  2. 自注释,重代码轻文档。
  3. 代码核心,不需要对使用者友好。
  4. 灵活配置,多种实现。
  5. 效率,安全性,特性不是最重要的。
    有兴趣的,可以也通过本文的介绍,不看代码写一个类似的东西。而后对比代码,找出设计上的异同和优劣。如果您也设计了一个,请告诉我,我很高兴能够得到大家的指正。

2009年9月13日星期日

软件自由英雄谱

    谨以此缅怀那些为了今日软件事业的自由做出贡献的先辈们。(注1: 多数人没牺牲,谢谢)(注2: 排名不分先后)(注3: 科普作品,大家别怕)
    我在撰写这篇文章的时候,避免使用自由软件这个词,而改为更普遍意义上的软件自由。因为自由软件是RMS提出的一个专有词语,指软件的开源,复制,协作等 特质。而我试图通过软件自由这个词,表达人们在使用软件上的自由,以及使用软件来为我们获取自由。我们拥有知道软件一切内幕的自由,我们拥有修改软件的自 由,我们拥有思考的自由,我们拥有挑战老系统的自由,我们拥有拒绝通过软件收费的自由,我们拥有通过软件获得信息的自由,我们拥有不受任何人,包括政府监 控的自由。为了这种自由而付出的,不仅是自由程序的拥护者,也有商业程序的拥护者。
1.Richard Matthew Stallman
    大名鼎鼎的RMS,GNU的核心人物,自由软件的布道者。要是在这个列表上没有他的名字,那我不知道还有谁能留在这张表上。具体可以看这里(http://zh.wikipedia.org/zh-cn/%E7%90%86%E6%9F%A5%E5%BE%B7%C2%B7%E6%96%AF%E6%89%98%E6%9B%BC)。简单来说这家伙最大的几个成就:创立了GNU和FSF,为自由软件的传播奠定了基础。制作了emacs,当今黑客世界两大编辑器之一(另一个是VIM)。制作了GCC,世界上使用最广泛的编译器。
    RMS的核心想法是,因为软件而收费是罪恶的,这种人是撒旦(当然,Bill Gates是其中最大的那个)。他认为软件应当自由分享,程序员从中收取的应当是服务费。今天,RedHat正是继承了这一模式。通过免费的软件和收费的服务来进行持续的开发。
2.Linus Benedict Torvalds
    常常和RMS并提的一个家伙,具体在这里(http://zh.wikipedia.org/zh-cn/%E6%9E%97%E7%BA%B3%E6%96%AF%C2%B7%E6%89%98%E7%93%A6%E5%85%B9)。 一个低调又火爆的家伙,没有什么太多言论,但经常语出惊人,最有名的是以“一群自慰的猴子”(OpenBSD crowd is a bunch of masturbating monkeys)来形容OpenBSD的团队。最大的成就就是写了个操作系统——没错,就是叫Linux的那个。
3.Donald Ervin Knuth
    哈,这个人就不像上两个那么广为人知了。他(可不能叫这家伙,得敬老)有个中文名字,叫高德纳,页面在这里(http://zh.wikipedia.org/zh-cn/%E9%AB%98%E5%BE%B7%E7%BA%B3)。 最大的成就是写了本书,叫做《计算机程序设计艺术》。有意思的是,写到一半的时候,觉得现在(那是上世纪80年代的事情)的排版软件不爽——于是自己下 手,写了一个叫做Tex的排版系统——然后再回来继续写书。这本书算起来已经写了30多年了,估计成书时间和《浮士德》有的一拼。而Tex是当今高端排版 中最流行的系统(多数都不是直接拿来用,而是用了LaTex之类的包装),如果有向国际期刊投稿过的应该有印象。Tex也是被誉为最接近完美的程序,它的 介绍在这里(http://zh.wikipedia.org/zh-cn/TeX)。他的版本号是以圆周率为基准的,头一个版本叫3,后一个叫3.1, 以此类推。目前的版本号是3.1415926,刚好是祖冲之的密率。高伯伯曾表示,等他死之后,版本号就改为π,剩下的bug就作为程序的功能放在那里。
    有一个未经证实的故事。据说上世纪Internet还没出现的时候,美国军方找人设计了TCP/IP协议,他们希望有人为他们实现基于Unix的TCP /IP协议栈。于是他们花了四千万美金,找人写了一个协议栈,并且拿到高伯伯的学校去用。对此高伯伯非常不满意——别误会,我指的是实现的效果。于是就自 己花了点时间写了一个,结果比原版的协议栈更快速而稳定。美国军方觉得非常困惑,问他是怎么做的。高伯伯说,读你们的协议,然后编码。
4.Andrew Stuart Tanenbaum
    这个知道的人也不会太多,当然,职业玩家例外。当初AT&T禁止UNIX7的代码公布,因此大学里面都没什么实际产品可以用来教操作系统这门课。 于是,有个叫AST的老师就怒了,你不让我干,我自己干。于是写了一个叫做Minix的系统,并且还写了本书,叫做《操作系统:设计和实现》。后来有个学 生,觉得这个系统改改能干别的,于是给AST去信。AST说,改什么改,我写这东西是拿来教书的。于是这个学生就自己写了一个系统——对了,这个学生就是 上面的Linus,而那个系统,就是大名鼎鼎的Linux。
    时至今日,Minux已经发展到了第三版(他的版本号是跟着书走的,第一版,第二版,第三版...),是大多数大学里面教授操作系统基础原理的标准教材。 同时,也在嵌入式系统等领域有非常大的应用。但是,由于AST还是坚持他的教学和精简原则,因此在桌面和服务器领域就别指望了。关于AST,大家可以看这 里(http://en.wikipedia.org/wiki/Andrew_S._Tanenbaum)。
5.Ian Murdock
    这个人很多人都听过,不过看着名字还是认不出来。他是Debian系统的作者,具体可以看这里(http://en.wikipedia.org/wiki/Ian_Murdock)。
    Debian有什么特殊呢?其实就本身来说,Debian并不算特别成功。但是Debian有庞大的衍生系统群,更有Ubuntu这样充满活力的发行。 Linux世界有所谓三大发行,四大包管理系统之说。其中三大发行指三个在世界上最广泛用于服务器的发行版本,即RedHat Enterprise Linux,SuSe, Debian,其中只有Debian是无服务商支持的。而四大包管理系统就是指RH的RPM系统,Debian的APT系统,arch的PCMAN系统, 和Gentoo的emerge系统。
6.Ken Thompson
    有没有听说过?至少看着眼熟吧。这家伙是贝尔实验室的,最大成就就一个:Unix作者。详细内容请看这里(http://en.wikipedia.org/wiki/Ken_Thompson)。
7.Dennis Ritchie
    没听说过?也很眼熟?这家伙和上面那位是朋友,最大成就也就一个:给上面那位提供了基础语言,C语言。详细内容请看这里(http://en.wikipedia.org/wiki/Dennis_Ritchie)。
8.Bjarne Stroustrup
    又是一个怎么看怎么眼熟的家伙?那当然。他和上面两位不怎么熟,不过他们都是一路的。他是C++的作者,详细内容请看这里(http://en.wikipedia.org/wiki/Bjarne_Stroustrup)。
9.Phil Katz
    这个就很少有人知道了吧,不过大家肯定天天和他打交道。大家用记事本打开任意一个ZIP文件,开始的两个字肯定是PK,这就是Phil Katz,具体请看这里(http://en.wikipedia.org/wiki/Phil_Katz)。
    这是一个有点悲剧的人物。在上个世纪的时候,大家还在BBS上混。由于速度有限,因此下载站的资源都是压缩提供的(当然,直到今天肯定还是如此)。最初的 压缩格式大多是ACE的,这是一家商业公司,直到今天还活着。由于PK不满意这家公司的压缩软件,压缩率低,速度慢,而且还不断提出高昂的收费。因此他决 定自己写一个压缩软件,就是最初的PKZIP。由于软件免费提供使用,压缩率高,解压速度快,因此很多站长自发的将数据格式转换为ZIP。后来PK就干脆 开了PKWARE软件公司,免费发行压缩程序代码,同时提供方便使用的图形界面版本。但是非常可悲的,由于格式开放,因此这个软件有个非常大的竞争 者,winzip。我想有些Win95时代的老用户还记得这个软件。PK在软件开发上很有天分,但是在市场策略上却不很成功。WinZip对ZIP格式的 熟悉其实比不上PK(那当然,人家是原作者),然而WinZip却拥有很多用户友好的特性,右键菜单解压,虚拟解压(将压缩包的内容临时虚拟成一个目录, 用户可以无缝的使用,XP中集成了这个功能,但是WinZip的虚拟解压很容易撤销)。所以最终PK的软件公司破产了。他本人在2000年4月14日因饮 酒过度,在一家小旅馆内死去。
    至于WinZip呢?碰到了一个更强大的对手,WinRar。功能类似,但更简洁,最主要是支持大多数流行的压缩格式。因此目前压缩软件领域还是WinRar占据着主流,市场就是这么残酷。
10.Phil Zimmermann
    这个人基本没人知道,但是却是这张表里面最典型和突出的一个人。他是PGP的作者,具体可以看这里(http://en.wikipedia.org/wiki/Philip_Zimmermann)。他的成就很难用一句话说明,要阐明他的成就,就必须从美国的国家安全出口管制说起。
    在上个世纪,美国政府有一种观点,他们需要能随时随地的窃听任何一个人和其他人的通讯。同时,作为延伸,他们制定了国家安全出口法案,将密码产品作为军用 管制品,限制出口。这其实是很荒谬和不合逻辑的,任何公开的算法都可以被多个人独立的实现。只要算法是公开的,即使产品不允许出口,国外也可以没有任何阻 碍的实现出来。而如果算法是不公开的,则会出现两个弊端。一个是阻碍密码学的交流和进步,更麻烦的是,根据密码学的内在逻辑,这样的系统,由于验证不完 全,因此比公开的系统更加不安全。
    在1991年前后,PZ制作了PGP软件,用于保障当时备受争议的电子邮件的安全(小常识: 电子邮件默认是明文的,安全程度和你写在明信片背面寄给你父母的句子差不多)。这个软件使用了1980年以来提出的现代密码系统几大密码系统,实现了签名 安全和秘密安全。这里我们小小的讲解一下电子邮件的两大安全系统,对此无爱的人自行跳到下一段。签名安全就是指,你收到一个邮件的时候,能够确信,这个信 的内容是原始发件人的真实意思表示,而不是被篡改过的。秘密安全就是指,当你收到一个信的时候,你能够确信,除了你没有别人能够偷看到内容。对此,一般采 用公钥系统来实现两者的安全。所谓公钥系统是这样一种系统,用公钥加密必须用私钥解密,用私钥加密必须用公钥解密,私钥很容易计算出公钥,公钥非常难计算 出私钥。当你要签名安全的时候,将邮件内容用自己的私钥加密再发送一次(实际是将内容hash了再加密的),接收者解密后对比。由于篡改者只有公钥,因此 虽然可以拦截和修改内容,但是无法伪造出一对匹配的内容,用公钥解密后刚好一致。而秘密安全则是用对方的公钥加密。对于更高层级的要求,你的公钥不仅要求 公布,而且必须在国家认可的部门公布,这样就由国家认定了你的公钥和你的身份的一致性。当你对一个内容签署的时候,只要能用公钥验证签名,就可以认定内容 是你的真实意思表述,并被法律所承认。
    当时的PGP当然还没有这么复杂,但是对于当时缺乏任何安全性特征(当时连TLS都没有)的电子邮件来说,是非常必要的补充。可是我们上文说了,美国禁止 出口这些产品。于是,PZ免费的将软件的最初版本散发给同事和其他人使用,而这些人又可以免费的分发出去——这和自由模式非常的吻合,除了我找不到具体信 息标明当时PZ是否从授权上同意他们做这个事情。法律上说,PZ并没有“出口”密码产品,但是实际上,是他实现并且向全世界推广了高强度的电子邮件安全系 统。从某种意义上说,PZ可以说是叛国者。非法散布军用管制品,危害美国的国家安全(这还不像中国那种含糊不清的指控,这里的军用管制品定义是明确的,并 且是由国会制定的)。于是,PZ受到了三年的官司和五年的调查,直到96年的时候,克林顿签署了新的法案,放松了密码产品的出口限制。其实也没松多少,从 40位到56位——大概就是从5个字符到7个字符的区别。反之,我们改变观点,从世界的角度说,由于他的勇气和决心,我们每个人从中受益匪浅。
    必须得说,其实这一改变很大程度上并不是PZ个人努力或者公民运动的结果,其中有巨大的商业力量。IBM,微软和Lotus之类的跨国软件巨头在出口产品 的时候,由于受到出口限制,因此在海外产品上的安全性一直很成问题。很多时候他们因为这个问题受到了巨大的挑战。在这一问题上,他们有足够的理由去游说白 宫,改变出口限制的要求。关于这个案件的其他资料,可以参考这里(http://cyberlaw.stanford.edu/~prz/ZH/faq/index.html)和这里(http://www.techcn.com.cn/index.php?doc-view-130949)。
    在今日,PGP仍旧是一个非常强大的加密系统,并且是开源的——理所当然,如果不开源,我们会担心其中是否有漏洞和后门继续危害我们的安全。并且,从密码 学内在的逻辑来说,不公开的系统是不安全的。不过他仍旧受限于美国国家安全出口管制条例,原因是因为由于今日强大的计算能力,因此密钥通常的长度是 1024,2048,4096位长的——远远超过美国国家限制数十倍。因此这一软件的强密钥版本只有英文版,因为不用考虑出口。对于海外人士来说,我们更 推荐OpenPGP,同样是开源的,而且基于开源模式开发的GNU自由软件。能够充分保证你的信息安全。
11.Lawrence Edward Larry Page
    哈,在所有人中,这个是最出名的。不过在这个列表中列出此人,并非因为Google的成功,而是因为其公司“不作恶”的信条。直到今日为止,Google还良好的保持着不作恶的信条。
结尾
    我们遍数评论一个个的软件自由英雄的时候,才会发现,无论在哪里,通向真正自由的路都坎坷而血腥。RMS直到快50还一直单身,到处流浪。他没有自己的汽 车、电视和房产。PZ面临了政府的指控,三年的官司,五年的调查,以及叛国者的骂名。PK更是直接挂了。当然,其中也不乏成功者,Donald Knuth和Andrew.S.Tanenbaum的书都卖的不错。Linus Torvalds和Ian Murdock也算是软件白领,收入不菲。Larry Page更是名列世界级的富豪榜。然而我们必须知道两件事情,没有他们的存在,我们就没有安全的通讯,没有廉价而优质的软件。因此,照RMS的最大对手所说的,即使没有这些人,人类也应当把它们造出来。

2009年9月8日星期二

计算机中的海森堡效应和罗素悖论

    有点标题党,海森堡测不准原理大家都知道吧,你观测一个东西以获得他精确的描述,然而你测量行为本身就会干扰这个东西的存在,从而永远无法准确测量。
    近日贝壳碰到一个计算机中的海森堡效应,因为工作需要,贝壳需要获得/proc/loadavg中的load参数。这个参数在uptime时会显示,大致意义是这一秒内平均的活跃进程数。(对电脑无爱者请自行跳过以下内容到下一段)准确的计算方法是在一秒内的所有tick上,累加当前的待运行线程列表长度,而后除以一秒内的所有tick。当tick趋于无穷小时,相当于对活跃进程的定积分除以横轴长度,即平均值。
    同个文件内有另外一个值,活跃进程数,是当前的待运行队列长度。从理论上说,如果贝壳要计算一个小时(或者其他大尺度时间)的loadavg,可以高速取样该值,在一小时内求平均,即复现load参数的意义?
    想法很好,不过实际上差很多。开发服务器上的loadavg大约是0.01-0.05,但是贝壳按照后者算出来的load总大于1。问题在哪里?
    记住一点,当你去获得loadavg的时候,你当前的线程永远是在运行的。因此你获取的行为会增长活跃进程的值,哪怕其他时间什么都不做,这样会将取值的瞬间的load提高至少1。而内核的计算的时候,是不会把自己的行为计算为活跃进程的。
    那么将值减去1对不对?也未必。在知道上述问题的同时,我们可以想象。在高压力下,你的线程什么时候会获得运行的机会?只有在最高优先级的任务空闲的时候。因此,你取得的值会严格的小于真实的压力。
    因此,不要相信当前活跃进程数,那个值永远大于1,并且不总正确。如果那个值是0,那逻辑上讲,你就碰到了罗素悖论。
    咳咳,又来一个问题,什么是罗素悖论?
    很简单。如果说真话的人永远说真话,说假话的人永远说假话。有人对你说:“我在说谎”。你就听到了罗素悖论。同理,如果理发师只给不给理发师理发的人理发,而所有理发师的头发都有人理,那你也碰到了罗素悖论。同样,如果有程序告诉你,我读取了当前的活跃进程数,但是这个数表明我不活跃。
    同样,你也碰到了罗素悖论。

2009年9月3日星期四

搭建家用的OpenVPN服务器

    啥都不说了,贝壳最近搞了一个家用的OpenVPN服务器,任何机器,随时随地可以穿到家里来,很方便。用VPN干啥?这就多了。我可以用vpn操作 Windows上的vnc,使用Windows的共享文件服务,直接向Linux Server放文件(这样别人可以用http下载),查看摄像头(被网络公布了)。将来如果有其他网络设备(例如冰箱和空调),也可以一并管理。不过最直 观的——可以很方便的打游戏,我们根本就在一个网络里面。要点是,这些服务要分别开映射端口非常麻烦。而且有的服务从安全起见,根本不能开端口(例如臭名 昭著的Windows文件共享服务)。
    具体原理上,贝壳有一台Windows,上面用Vmware搭建了一台Debian Linux,两者使用桥接模式。从概念上看,就是一台通向公网的路由器,里面放了一台Windows和一台Linux。现在,贝壳想通过某种方法,将外部 的一台机器接入内部的局域网中,就如同随身携带着一根通向家里路由器的网线一样。
    下面直接上具体配置:
-----------filename: /etc/network/interface-------------------
auto lo
iface lo inet loopback
iface eth0 inet static
        address 0.0.0.0
iface tap0 inet static
        address 0.0.0.0
auto br0
iface br0 inet static
        bridge_ports eth0 tap0
        address 192.168.1.IP
        netmask 255.255.255.0
        network 192.168.1.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        dns-nameservers 192.168.1.1
        dns-search home
-------------------------------------------------------------
    使用上述配置的原因是,vpn只能联通你机器上的逻辑网卡和服务器上的逻辑网卡。单就vpn自身而言,是无法让你连到服务器上的内网网卡的。因此,我们需要通过网桥的配置,将eth0和tap0配置成网桥。这样,你的服务器就如同一台交换机一般,联通了两个网段。
    而后,我们设定服务器配置。
-----------filename: /etc/openvpn/server.conf----------------
local 192.168.1.51
port 1194
proto udp
dev tap0

ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh2048.pem

server-bridge 192.168.1.IP 255.255.255.0 192.168.1.100 192.168.1.149
push "route 192.168.1.0 255.255.255.0"
keepalive 10 120

user nobody
group nogroup

persist-key
persist-tun

cipher DES-EDE3-CBC # Triple-DES
comp-lzo

verb 3
status /var/log/openvpn-status.log
;log openvpn.log
log-append openvpn.log
-------------------------------------------------------------
    其中的server-bridge是因为我们采用网桥的关系,100-149是向外部拨入分配的IP池。贝壳的2-100是内部固定IP保留,150-199是内部DHCP池,200-254保留。这个大家可以按照自己的情况配置。
    需要特别注意的是,由于上文我们已经建立了tap0这个设备,因此才dev中必须指定tap0设备。如果你仅写tap,那有可能是新建一个设备出来。到时候就好玩大了...
    上文中,我们使用了ca cert key dh四个密钥文件选项。下面我们说说如何产生这些密钥文件。
    首先,你需要复制usr/share/doc/openvpn/examples/easy-rsa/2.0/到你的个人目录,并修改其中的vars文 件。将其中的一些东西修改为你需要的参数(很简单,我假定大多数人都会用,这个是基于SSL的),而后source vars,执行下述命令。
./clean-all
./build-ca
./build-key-server server
./build-dh
#需要�入密�的
./build-key-pass username
#不需要�入密�的
./build-key username
    最后两个可以随便签署,想发多少密钥就给多少人签署。不过请注意,easy-rsa的默认脚本中,是没有ns-cert-type server的设定的,因此*千万不要*在配置中加上这个设定。否则会导致TLS handshark failed。
    最后,启动vpn,并且修改你的防火墙和路由器映射,贝壳这里使用的是udp1194端口(默认)。再给客户分发配置和key,具体如下:
------------------filename: home.ovpn-----------------------
remote shell909090.3322.org 1194
client
proto udp
dev tap

ca home.crt
cert shell.crt
key shell.key

resolv-retry infinite
persist-key
persist-tun

cipher DES-EDE3-CBC
comp-lzo

verb 3
-------------------------------------------------------------
    其中home.crt是服务器上的server.crt,shell.crt和shell.key是刚刚签署的用户密钥。如果有密码,需要设定密码,或在连接时提供。

--
与其相濡以沫,不如相忘于江湖

2009年8月20日星期四

互联网的黄金时代

    今天,一个朋友推荐我看了篇《创业成功80%是运气?》的文章,作者可能是雷军。里面说,99年是互联网成就的年代,几大互联网巨头都是在99年成就的。 因此作者推测,09年也是互联网成就的年代。前者我认为很有道理,后者就纯粹在胡扯,拉人去投资了。退一步说,即使是对的,也是蒙上的。
    为什么?我们首先得看,为什么99年是互联网成就的年代。这就得讲到98年以前,电脑是什么样的一个形态。记得贝壳95年刚接触电脑的时候,那时用的是 286。和现在完全不同,电脑最主要的功能是文书处理。因为当时根本没有互联网建设,电脑用户沟通的途径主要通过点对点拨接的BBS(不用了解是什么东 西,贝壳自己都不怎么明白)。这种BBS和现在的BBS完全不是一个概念,但是BBS这个词却来自于当时的这个形态。这种沟通方式非常不方便,也非常贵。 因此用的人很少,基本都是专业人士和各个高校,这等于限制购买电脑后只能单机使用。由于电脑根本是单机使用,因此但凡要增加功能就必须买盗版盘。要 WPS,盗拷(最早还没有盗版光盘呢),要看电影,买盘。于是电脑的主要形态被限制到了预设的几个功能上,而不是根据客户的想法随意定制。而这几个功能中 呢,最常用和实用的就是文书处理。96年的时候,最火的就是UCDOS和WPS。凡讲电脑入门如果没有这两个那就是落伍,是怪胎。而在98年的时候,接连 发生了几个事情,因此才酝酿出了风起云涌的互联网大潮。
    首先,98年前后,Win95/98在中国大量普及。在此之前,由于受到文字,版权,习惯,配置等诸多限制,大家还是停留在dos6.0的年代不肯出来。 Win9X系列的普及(当然,主要是盗版普及)对电脑降价和普及起了不可磨灭的作用。也许有人听不懂了,软件的普及能降低硬件的价格?话是这么说的。从总 体来说,DOS6.0的入门难度高,高到要维持一个能够运转的DOS系统,就非要经过专业的,正二八经的学习不可。而Win9X的入门和维护难度基本是 零,你就算不明白,也不阻碍你的使用。因此,有大量的普通用户可以使用电脑,电脑的组装量就大了。更具有决定作用的是,由于DOS的入门难度高,因此很多 客户必须购买专门的电脑公司的电脑系统,即所谓的“品牌机”。使用品牌机的最主要理由是需要电脑公司的服务,来维护电脑系统。而Win95安装维护简单, 任何一个人都可以拿着盘装套系统出来。除去偶发的硬件故障,着实没必要非买品牌机不可。于是,当时品牌机对市场的垄断被打破了。大量的小作坊稍微经过培 训,就可以拿着一堆电脑配件组装起一台电脑来。教客户几分钟,他就可以自行安装起Win9X和Office。而后机器如果出现故障,顾客也可以很轻松的重 装。于是大量的小作坊相互竞争,使得电脑的价格直线下滑。我记得96年时主流电脑的价格在2W上下,98年时只有1W上下,01年时更是只有5000。注 意这里比较的是主流电脑的价格,不是同等硬件。里面固然有着摩尔定理的作用,也相当的得益于Win9X的普及。
    而此时,更具标志性的事件是国内大多主要城市,都开始了电话拨号上网的业务。虽说中国从89年就开始接入互联网了,然而真正标志着普通民众上网的事件还是 98年前后的163/169电话拨号上网业务。大家可以想像一下,要是没有网络了,你的电脑还能干什么?怕是只剩下看书(还得买盘),听歌(也是买盘), 放片而已了吧?我们今天所用的大多数功能,都是以网络为基础,或者要基于网络获取数据的。电话拨号业务一开,等于就开启了一扇通向无限可能的大门。虽然当 时的价格大约是1.6元/小时,而速度一般只有5K/s。这种流量下基本无法承载什么复杂业务,多数都是基于文字的业务。例如QQ,当时肯定只能做文字, 不能做视频聊天。又例如BBS,当时也是以文字为主,图片点缀一下。要是哪个搞不清楚放一堆图片上去,站长到还没头痛呢,用户先受不了了。
    现在我们看到,98年的时候,互联网具备了大量的潜在用户,也打开了通向无限可能的大门。可谓是万事俱备,只欠东风。而东风从哪里来呢?所谓的东风,就是 亚洲金融风暴和2000年互联网泡沫中的时间差。在98年的时候,东南亚发生了非常严重的金融风暴,相信大多数人都有所耳闻。而98年的时候,正是互联网 飞速发展的时候。2000年的互联网泡沫还没有提前到来,投资回报比高到吓人。在金融风暴中损失惨重无处容身的热钱,碰到了一个飞速发展回报极高的产业, 就如同火柴碰到了汽油一般,瞬间就无可阻挡的燃烧起来。而引爆点,就是互联网门户和娱乐。腾讯,百度,携程等互联网公司,都在那个时候纷纷发展起来。金融 环境的影响究竟有多大呢?我们不妨想像一下,如果是2000年的时候,用户和网络才准备好。这时金融相对稳定,金融风暴中跑来跑去的热钱也该投资的投资, 走的差不多了。而互联网公司普遍表现不好,美国各大网络公司一片惨红。这时候,中国的各个网络公司才组建起来,他们还能顺利的拿到融资,完成由小到大的华 丽转身么?
    当然,当年之所以成为互联网的黄金年代,还有其他的很多因素。但是就贝壳的浅见来说,当时互联网的成功,和广大的新增客户群,新出现的网络,还有相对良好 的投资环境是分不开的。现在,中国的网民已经发展到了极限,12亿人口4亿网民,即使还有发展空间,也是屈指可数的事情。不像我们的前任,永远会出现新的 客户(这里顺便提一下,实际上互联网大量出现用户的时间大约是在05-06年前后,宽带包月普及的时候)。我们的投资环境呢?不利,很不利。美国经济刚刚 打了个喷嚏,现在全世界人民都在重感冒,没空搭理中国一堆互联网公司的脑残想法。那么,我们的下一个黄金年代在那里?
    接下来,我们有几件事情会引发互联网的大革命,不过贝壳和大家一样头痛的是,我们谁都不知道这些事情会什么时候到来,是否会一同到来。
    首先,是真正的3G网络。现在所谓的3G网络都是花架子,没有什么实际意义的,3G最大的优势在于低廉的随时在线成本。当前,所有客户上网都是通过电脑拨 号,而电脑是需要了再开机的。但是我们的很多应用需要客户随时在线,例如IM类业务,对客户在线就有严格要求,微博客也有类似问题。为了能让用户随时在 线,就必须让客户在手机上使用电脑的应用。问题是,如果没有一个廉价的网络接入,哪个客户愿意付出N高的网络费用就为了用个IM?那还不如打电话。现在的 3G曾有个笑话,什么叫3G?一秒3元,所以叫3G。这个价格至少要下降到一个月100-200的范围内(流量不限制,甚至还要在其中包括有线的接入费用 和电话费),才有大量用户愿意入网。更好的接入模式是两台手机一根ADSL线路,包含电话/手机/电视/网络/3G在内的所有通信业务,总价200上下。 不过以目前的垄断形式而言,大家可以口水收起来了。
    其次,是全球经济复苏。要是大家都没钱,是没人愿意投资电脑产业的,也没人愿意用。
    而后是取消互联网备案和审查制度这滩狗屎,建立一个真正公平公正的法律环境。众所周知,互联网属于服务业,而服务业对于环境的公正性要求是最高的。即使经 济复苏,也绝对不会有一个投资者愿意把钱投资到一个政策整天变化,商业运作随时为政策让路的地方。以饭否为例,如果某个投资者投资了,而后饭否因为种种不 明原因关闭了,那么投资者的损失谁来负责?对于这类问题,必须有个公正的,公平的政策,提前说明。如果投资违背了政策,那么损失没什么好多说的。如果没有 违背政策,那就不应该让投资者受到损失。而不是暧昧不清的制订一个根本实行不了的政策,然后看谁不顺眼就关谁,对其他人的违法不闻不问。只要这个大山不真 正的走开,中国的互联网就不可能真正的走入下一个黄金时代。