Archive for June, 2007

阿穆,回去吧

Saturday, June 9th, 2007

阿穆成为今晚第二个被淘汰的选手。我觉得这对他是最好的归宿。长沙不适合他,更确切的说,这样的一种以选秀为目的的比赛不适合他。在今晚演绎的三首歌中,马头琴伴奏下的《狼》,阿穆表现得比原唱要有豪情的多。《我的未来不是梦》也展示了阿穆宽广的音域,蒙语歌没听明白,然而情深意真,配上他清澈的眼神,让人感动。

我去过新疆,然而没有机会见到一望无际的草原。我却深深的知道一个生长在视野不受阻碍的地方的人,来到高楼林立的都市那种无助与慌张。热爱音乐没有错,当音乐被这样一种方式包装出来的时候,从话筒里发出的声音,那么,还是当初想表达的那个声音吗?方仲永被拉出去秀了几圈后最终“泯然众人矣”,我不希望看到这样的阿穆。

一直非常非常喜欢那种原生态的声音,不要任何包装的声音。那迂回百折却又扶摇直上的曲风,让人无论身在何处,心却被带着飞上云霄。有很多很多人喜欢这种音乐,阿穆,即便以你现在音乐成就,仍然还有很远的路要走。

回去吧阿穆,回到草原,回到有马头琴,大草原,天低得伸手就能触到的地方,聆听昆仑神的声音,聆听来自西域真正野性的声音,让这些声音,借你的歌喉,传递给我们这些生活在视线不超过100米的人们,让我们暂时忘掉俗陈事务,让心涤荡在苍凉的天地之中吧……

双向流模拟同步HTTP连接

Friday, June 8th, 2007

AJAX毫无疑问,增强了单个用户的体验。然而,对于如何能够增强“参与感”的技术,能够见到的论著寥寥无几。例如,聊天室,如何能有效、低延迟、高伸缩性的进行多人聊天?我们能够想到的方式有如下几种:

* HTTP pull. 通常的实现方式是隐藏帧刷新,或者XMLHTTP访问。每隔一段时间(2秒或者更多)对服务器进行访问从而获得更新信息。
* HTTP Push. 现在有了一个更流行的名词:Comet。基本实现原理是通过服务端向客户端回复一个永远不会断开的连接。通过不断输出可以直接执行的javascript代码,或者一块可以被应用程序解析的字符串,达到相互通信的目的。

第一种方法的缺陷一目了然:效率低,延迟高。由于并非每一次请求都会有返回的数据,当次请求的返回值则毫无意义。而这其中建立HTTP 连接的时间,服务器处理的时间,客户端消耗时间等,让这些请求毫无价值。没有数据的请求让服务器疲于应付无效请求,浪费了计算资源。另外,由于没有一个合理的请求频率策略,导致应当及时返回的消息在最坏的情况下于延迟时间返回。例如,用户在00:01发送了一条消息,系统每隔2秒扫描一次,在00:03秒,另外一个用户才得到这个消息。当然在聊天应用没有关系,但是实时性要求更高的场景下这些往往不一定可以接受。

第二种方法解决了实时连接的问题,然而这要求更高超的服务器端编程技巧。现在看到的WEB服务器都并非为长连接而设计,你可以看到将这种方案部署到常见的Web应用服务器上的时候性能下降得多么厉害。更为现代的Web服务器,如twisted, 基于MINA的asyncWEB采用了event driven IO以及线程重用等技术,在这方面表现很好。然而,这种长连接最大的问题是,无状态架构不能很好的被应用,从而影响了系统的伸缩性。

目前更好的一种方案是:BOSH。这种原本为了jabber设计的规范,在应付这种需求的时候显得格外合适。它的基本原理不是常见的采用1条HTTP通道,而是不多不少的两条。策略如下:

* 系统启动后,客户端向服务器端发送请求(通道1)
* 如果有消息,服务器直接向客户端返回消息。客户端收到消息后,除了完成业务处理外,还立即向服务器发送一条新的请求。
* 如果没有消息,服务器保持通道1的请求。如果这个时候客户发来另外一个请求(通道2),服务器立即向通道1返回空响应,并保持通道2的请求。
* 如果很长一段时间没有任何消息(例如,30秒),服务端返回空给持有的通道。这个消息立即会触发客户端的一个新的请求。
* 如果很长时间没有接到用户的请求(30秒,例如),服务器断开客户端相关的session信息并清理相关资源。

我们看看有没有解决上述的问题:
* 效率:可以看到,只有当有数据的时候才会真正的完成请求(完成传输),无效的传输大大减少。通过规划合理的心跳检查时间,可以最大化传输的有效性。
* 延迟:由于在任意时候都有一条HTTP通道保持连接,因此可以想象延迟降到了最低。
* 伸缩性:由于采用两条通道轮换处理,常见的无状态架构可以被应用,不会影响伸缩性。

可以看到,通过增加一条HTTP通道进行轮换处理,提升了传输效率,降低了延迟同时不牺牲系统的可伸缩性,值得尝试。