喷
大刘新买了一个7吋的掌机,能上网能听音乐能看书能玩游戏当然看高清也不是问题,我觉得如果加上触控就是一台Tablet PC。他的购买动机也挺简单,原来那台屏太小,看着不爽,尤其是看pdf的时候。pdf这种有版式的文档,在小屏幕上显示总不太好看,这也是我想处理掉手机那台5吋的汉王,再换过一台7吋的sony reader的原因。不同之处在于我是比较容易分心的,如果看上的家伙功能齐备,我就不会安心看书了。
c6h6很惊讶我到现在也没有看完《一九八四》,其实这一点也不奇怪,S60手机功能如此丰富,我大概只有在网络全断的时候才会想着打开Anyview看一会儿书。这个月也就读了四成的样子,还有大半文字没有过眼,书评当然是写不出来的。不过并没有觉得这书中所述人生像小刘说的那样和现实社会“一样一样”,倒反觉得很是不同。现实生活中没有电幕,没有思想警察,没有业余纠察队。尽管我们有安全局会关注某些人,有国宝会关照某些人,还有小黑屋会关禁某些人,但总的来说,比之《一九八四》中的情形还是宽松许多,至少《一九八四》还没有被禁掉。官员也并非都如湖北省长在记者会上那样粗犷,伍皓先生面对满天纷飞的五毛纸币也能心平气和地畅所欲言。
真正禁锢的是自己。不知道从什么时候开始,自觉地把一些词汇用“敏感词”代替了,起先比如“六四”或者“法轮功”,后来又如“艾未未”以及“谭作人”,再后来至于连“胡萝卜”和“温习”都要煞有介事地冠以“敏感词”的称谓。于是论坛里、QQ上、校内的签名、cB的评论,话读起来总不怎么朗朗上口。这一句两句,是嘲讽,泛滥之后,却似乎是刻意把自己放在了别人曾经设置的界限里,不愿意出来。久而久之,就成了强迫幻想。听到反对的声音就会紧张,看到批评的严辞就会恐惧,有时哪怕没人反对、批评、禁止、迫害,也会自己树起一个假想敌,然后一个劲儿控制自己。一次次在blog评论中自觉委屈地哀诉“博主不让人说话”,一次次强调对方“把一群人一棍子打死”。真可笑!不是也没删帖么,何必急得说不出来一二三,就高呼“不让说话”?
那压抑的心情,思前想后的踌躇,畏首畏尾的决策,延伸到每一根神经。以至连玩一盘合作对抗游戏都不敢随性而动,怕死,怕队友批评,怕不知所以的自我蛮怨……不想说,不想做,不想改变一切,希望能逃到一个静如止水的世界,希望能拥有冻结时间的力量,希望像小说作者一样超越“我”的界限观察每一个朋友。
何不像火山一样喷?让思想自由漫溢,争一回强势,主动输出观点,据理力争,反驳每一个反对者。在餐厅尽情地笑,开口跟哥们骂脏话,分享低俗段子,去想去的地方旅游,对央视主持人吹毛求疵,写敏感词的本来样子。那又怎样?不可能天下大乱。防微杜渐本属扯蛋,那不过是表面的平稳和真实的积怨。
别让自己背离朋友,别让自己背离正常的心境,别让自己背离从来的生活,就是积极和优秀。
举国哀悼
明天是女儿的生日,恰巧又是青海玉树地震的全国哀悼日,不能庆祝,所以考虑调整到阴历,庆祝三月廿四。身为中国人很庆幸,生日有两个可以过;身为中国人也很不幸,一纸政令能干涉所有老百姓的自由。
玉树地震远远没有像汶川地震那样给我造成强烈的震惊和伤痛。这或许是因为青海地广人稀,死难人数大大少于汶川地震;或许是因为中宣部管控得力,新闻媒体不能充分报道;亦或许是因为汶川地震和之后的种种让我神经变得麻木,以至于得悉此般灾难降临,心底竟只能挤出一句“是么?”。没有给玉树人民捐款,我已基本停止了捐款这样的行动。社会中太多的毒瘤,让人变得冷漠,我几乎不敢用道德的犀利目光审视自己。
但当我看到给四川的捐款逾八成流入政府帐户,使用细则却迟迟不见公开;看到军警以“昆明市专供水库”为名禁止干渴的村民取用;看到矿难发生后,只谈救人奇迹,不谈安全责任……这一个又一个的惨痛事实摆在我的面前的时候,我对这个社会失去了信心,也失去了敞开荷包的念头。我想:只帮助那些我认识的人,并且摒弃所有中间环节,让财与力直接发挥作用。
终究还是要哀悼的,虽然不能像艾未未那样把每一个孩子记住,年复一年地追思,但总可以在哀思之余能想想清楚,希望在哪里。
考虑更改图标
考虑更改图标,新版围绕桄欣结设计,并且将喜欢的字母u、v、w、x、y、z融入其中。用更柔和的色调和曲线设计,放弃以前图标的黄色调设计和尖锐棱角。
上传到twitter之后被自动截断成48×48正方图标,倒有点像DNA图标了。不过没有关系,也挺好看的。
PS:想把它输出成svg,但是一下子没有找到把fla/swf转换成svg的有效办法。网上提供的在线转换都不能用,悲剧。
PS2:这个图标的文字版是“>o<”或者“906”,文字版没有版权,反正好玩就好。
谈谈网络服务器设计(甲)- 基于同步阻塞式IO接口设计
最近开始尝试研究网络服务器软件的编写,参考了书上的几个网络服务器例子,然后又了解了Apache和lighttpd的设计架构,整理总结了几种常见的服务器设计思路把它们记录下来。网络服务器设计的关键在于解决并发问题,因为服务器都是对大量不同客户端执行相同的业务逻辑。优秀的并发设计能够提高服务器的请求承载量,保障数据安全,提供崩溃恢复能力,让服务器宕机损失最小化。
单客户端的服务器流程
首先考虑只有一个客户端请求服务的情况,服务器需要先开启一个Socket端口监听连接请求,然后接受一个客户连接,接着读取网络数据处理并发回结果,最后还要关闭网络连接。用传统的Socket函数描述,整个网络服务过程经历了bind、listen、accept、receive、send、close几个步骤,其中receive和send经历多次循环。由于receive、send等函数都是阻塞式的,没有完成接收(发送)就会等待而不往下执行,所以无法实现同时向多个客户端提供服务。
fork方式实现并行
既然单个客户端会在收发数据的时候阻塞整个程序的执行,一个简单的实现并行处理的方法很容易想到——创建多个进程(或者线程),分别服务不同的客户端。这就是fork方式的基本思路:主进程被创建之后,开启和监听端口,每每有请求的连接建立,都fork一个子进程来负责处理,主进程可以继续等待下一个客户端请求。对于每个被创建出来的子进程,都可以独立地接收和发送数据,执行服务器逻辑,完成操作关闭连接之后,子进程被销毁,资源被操作系统回收。
用一个比喻阐述fork方式的服务器就是:你(主进程)只负责接受生产订单,然后雇人(fork子进程)执行生产任务(服务器逻辑),交付产品之后将其解雇(销毁子进程)。
fork方式是最简单的网络服务器实现方式,它有着显著的缺点:fork模式大量地创建和销毁系统进程会造成巨大的系统开销。操作系统在创建进程的时候需要分配资源,复制父进程内存数据,而处理完毕后销毁进程时又需要回收内存释放资源资源,再加上大量进程存在时,系统的进程调度也会造成不小的额外开销。当然它也有显著的优点:所有客户端服务进程相互隔离互不干扰,一个进程的意外崩溃不会影响到其他进程的正常工作,对于像Web服务这样要求高度稳定、互不干扰的情况十分适合。
著名的Apache服务器至今仍在使用这种方式实现服务,就是在Apache中被称作prefork的工作方式。当然,实际用于生产环境的服务器稍微复杂一些,Apache的prefork还实现了初始进程数量控制,延缓销毁进程等技术以提升并发访问承载力。
worker方式
fork方式中进程提供的服务是一次性的,和客户端连接断开后就会销毁,这样整个服务器会同时有大量的进程需要创建和销毁。是否可以回收完成服务的进程,并让他们对新的客户连接提供服务呢?这就是worker方式。统计数据证明worker方式是相当值得使用的:一般工作的网络服务器,并发请求中大约有60%到80%是处于连接发起和等待响应状态,只有很少的部分是已经建立连接,正在服务的;而且并发访问量在短时间内是相对稳定的,很难想象服务器会遇到这一秒连接数量50,下一秒连接数量5000的情况,据此可以认为,只要有少量长期提供服务的进程或者线程就足以应对大量的并发访问。
worker方式首先创建一个独立的worker管理进程来负责创建和管理worker进程,称作worker管理器。然后主进程监听和接受请求,并把任务交给worker管理器负责。worker管理器接到任务之后,会在它维护的多个worker进程中找到一个空闲的来处理这个任务。worker进程负责具体的数据收发,服务器逻辑的执行。完成任务关闭连接之后,worker进程不是被销毁,而是通知worker管理器已经完成工作,处于空闲状态。worker管理器会考虑将下一个任务交给它。
用比喻阐述worker方式的服务器就是:你(主进程)只负责接受产品订单,请一个管家(worker管理器)负责打理生产事务,管家会长期雇佣若干工人(worker进程),你将生产任务交给管家,管家就找一个没事干的工人生产(执行服务器逻辑),工人完成任务后不会被解雇(销毁进程),管家会被下一个生产任务交给他。
worker方式实现服务器较之fork方式有不小的改进,虽然设计起来更加复杂,但和带来的收效相比是值得的。难点主要在于worker管理器的设计,为了有效的应对访问压力的变化,worker管理器需要能动态地创建和销毁worker进程,以便在访问高峰时提供更多的服务进程,访问低谷时占用更少的系统资源,并且还要能够发现并销毁出现错误僵死的worker。
worker方式的优点显而易见,缺点倒是也有不少。worker的软肋在于worker管理器进程,假如这个进程出现错误崩溃,那么整个服务器就宕机了。Apache从2.0版开始提供worker模式供选择,作为生产服务器,Apache同时使用多线程和多进程结合的方式。以worker模式启动之后,Apache会启动多个worker管理器进程,每个worker管理器会创建多个worker线程来负责具体请求。这样的设计一方面能利用更轻量级的线程机制降低worker的系统开销,方便worker管理器设计,另一方面通过增加worker管理器的冗余,提升抗风险能力——即使一个worker管理器崩溃,服务依然不会中断。
event方式
如果多个客户端交互信息量很大的话,服务器逻辑不得不大量使用同步锁定和进程间通信机制,大大增加了额外的系统开销,也造成许多死锁的风险。lighttpd服务器另辟蹊径,化整为零,利用Linux系统事件通知和异步网络IO操作的方式实现一个单线程的Web服务器。其具体实现和利弊将在下一篇文章中具体介绍和讨论。