2013年1月26日星期六

文件描述符传递方式的开销

以前提到过用文件描述符传递方式解决多进程惊群问题。最近实际测试了一下这种实现,发现实际效果不佳。较多进程无锁方式(nginx的实现减少进程锁)差得多,仔细思考了下,理论上应该这样解释这个原因:

1. 进程间文件描述符传递方式在接收一次连接时,整个系统会有 accept, sendmsg, recvmsg, epoll_ctl四次系统调用

2. 多进程无锁方式尽管有惊群效应,但接收一次连接时,最多N进程 × 1(accept)次系统调用,而且sendmsg调用开销远较一次accept为大。

3,文件描述符传递方式还存在进程间切换,以及发送接收数据的时间开销

综上,Nginx的实现方式尽管复杂,却是最高效的方式。

2012年11月25日星期日

一种HTTP模拟全双工Socket通信的实现

最近几天把很早之前构思过的一种HTTP模拟全双工Socket通信的方法在Snova/GSnova C4上实现了,效果不错,这里简单介绍一下实现方法。若有其他对此感兴趣的朋友,可以一起研究讨论。
Snova C4利用双HTTP连接 + Chunked transfer encoding 模拟实现一个全双工通信的TCP Socket。具体HTTP代理实现流程文字描述如下:
  • 浏览器发送HTTP请求到本地C4;
  • 本地C4创建两个HTTP连接到远端C4,其中一个携带加密后的HTTP请求内容,另一个则只携带读请求;
  • (重要)远端C4收到第一个HTTP连接后,将HTTP请求解开,创建到目的Site的连接,发送具体HTTP请求,之后到本地C4连接马上返回;
  • 远端C4收到第二个HTTP连接后,阻塞在第一个HTTP连接中创建的Socket读上,每读取一段内容,则将内容加密通过HTTP应答消息体返回给本地C4;注意这里的应答内容必须通过Chunked transfer encoding 方式发送;
  • 本地C4收到第二个HTTP连接的应答后,不断读应答消息体,将解开的内容写回到浏览器。至此整个Proxy过程大致结束。

若是HTTPS代理的情况,稍有不同:
  • 浏览器发送Connect请求到本地C4;
  • 本地C4创建两个HTTP连接到远端C4,其中一个携带加密后的Connect请求内容,另一个则只携带读请求;
  • (重要)远端C4收到第一个HTTP连接后,将Connect请求解开,创建到目的Site的连接,发送具体HTTP请求,之后到本地C4连接马上返回,携带“200 Established”应答内容;
  • 远端C4收到第二个HTTP连接后,阻塞在第一个HTTP连接中创建的Socket读上,每读取一段内容,则将内容加密通过HTTP应答消息体返回给本地C4;注意这里的应答内容必须通过Chunked transfer encoding 方式发送;
  • 本地C4收到第二个HTTP连接的应答后,不断读应答消息体,将解开的内容写回到浏览器;
  • 同时本地C4不断读取浏览器连接Socket,将读取的内容通过第一个HTTP连接发送到远端C4;远端C4收到后,则不断写到socket中。
  • 以上两步同时循环执行。
若是其他非HTTP协议的TCP代理,过程类似HTTPS的情况。

其实,Chunked transfer encoding默认在HTTP协议中是请求/应答都可以携带的,若在HTTP请求中也采用类似上述应答的方式,效果应当更好。不过在目前的几个PaaS平台中,几乎都不支持HTTP请求带Tansfer-Encoding。
最终的实现的效果相当不错,相比之前的心跳ping机制(也可以模拟全双工Socket通信),实时性大大提高,甚至访问视频网站这种对socket通信连接稳定性要求较高的场景也表现良好。
题外的话:大部分PaaS限制了一个HTTP请求的最大时长,一般是30s。所以在C4的实现中是用一点小技巧绕过这个限制,需要实现类似机制的朋友可以提前注意一下。

2012年6月12日星期二

此时彼时的惘然

旅途的间隙中,终于于手机上读完了《1Q84》。

据说,村上春树号称这是一部向乔治.奥威尔的《1984》致敬的一部小说,读毕之后却发现,《1Q84》只是一部纯粹的爱情小说而已,和《1984》这样的充满政治预言的批判小说的性质相差甚远,尽管村上春树也用了大量的笔墨进行似有所指的超现实描绘。也许过段时间会有另外的感受,大凡意识流一派的小说,都以摸棱两可的语言给人这样的模糊的感觉。

在整部书中,青豆和天吾自十岁起互吸引,却无法传递彼此的心意到对方。相距了二十年才在超现实的”先知”帮助下得知彼此的心意,彼此的存在。全书的最后,青豆和天吾终于二十年后见面了,并一起逃离了超现实的1Q84年,来到了现实的1984年。全书的剧情就此终止。

现实的生活可不会像小说描述的那样,这里没有任何的超现实的先知来告知你彼此的想法,来做沟通的桥梁,错过了便真的可能永远错过了。“此情可待成追忆,只是当时已惘然”。此时彼时的惘然,大都只会留待以后来追忆。

2012年6月6日星期三

分裂的神经

技术:
继续在X项目花费零碎时间。这几天一直纠结于一个问题,抽象成计算机语言描述就是:
一个二级int hashmap(key为int),即hashmap的value是另一个int hashmap, 如何按照规则A输出其中指定起始位置,指定个数的元素,元素在第二级hashmap的value中。
规则A:按照元素所属的hashmap间隔排列,即一级hashmap含10个二级hahsmap,若输出10个元素,则10个元素分属10个hashmap;
直觉的实现应该是全部将元素输出到数组,按照上述规则排序并输出。这种方法效率非常低,增加了一倍的空间存储临时元素,并耗费大量CPU排序,当元素个数巨大时,这样的算法对系统的影响是非常大的。
今天专门抽出时间仔细思考了这个问题,用了一种方法简洁的实现这个需求:用vector代替第二级hashmap,这样输出元素时,记录每次的输出的vector下标,即可近似的用二维数组的输出规则输出元素。这样的实现只用了20行左右代码,效率也相当高,算法复杂度等同于顺序迭代访问每个元素。这里的要点在于用vector代替原先hashmap。
有时,针对某些问题,用另外一种思维方式会取得意想不到的效果。

胡思:
重又将20余年前的历史在wiki上回顾了一次。每次看都有不同的感受,不同的思考,特别是在读过《1984》,《俄国人》之后。李贺诗言”临岐击剑如铜吼“,大概就是目前这种感受。
村上春树也在《1Q84》中描绘了一个初始以社会主义为目的后逐渐演变为类邪教的组织。大约持统一思想论的组织,无论高尚与否,大都最后都会异变。
“没人要和你玩平等的游戏 每个人都想要你心爱的玩具”——《亚细亚的孤儿》

2012年6月2日星期六

磨损胸中万古刀

前两日,读到唐代的刘叉的一首小诗:

 日出扶桑一丈高,
 人间万事细如毛。
 野夫怒见不平处,
 磨损胸中万古刀。

自己胸中的那把刀,如今已是磨损大半。非唯是见多了不平,更有面对现实的无力感。
如今这个时代,将来究竟如何,未知的依然很多,改变也会很多。只是在将来四顾心茫然时,希望依然能从胸中拔出一柄刀,即便其已磨损到已无锋刃。

2012年5月28日星期一

Linux下传送文件描述符的几个问题

这两日仍抽空忙于项目的设计开发,遇到了两个关于Linux下传送文件描述符的问题,记录如下:

1. Linux不支持类似SystemV的流管道传递文件描述符(即非FIFO/tcp socket等),只支持通过UnixSocket方式。目前只有类似Solaris的系统支持前者。

   不得已,修改了arch中相关代码,单独打开了一对UnixSocket专用于文件描述符传送。

2. 64位系统下,接受文件描述符侧进程在recvmsg调用返回后结构struct msghdr变量中msg_controllen大小较结构struct cmsghdr变量中cmsg_len大4个字节;在32位系统下两者相等。

    在64位系统只传送1个文件描述符的情况下,前者大小为24字节而后者20字节。若按照APUE中代码的判断规则则是失败的,按照UNP中则可以通过。(Ubuntu 64/32)

尤其是后一问题,折腾了许久才发现32位与64位的不同,目前参考UNP修改了判断语句以规避此问题,后续有时间的话还需要对原因进一步探讨。

2012年5月26日星期六

腹诽3

1. 如今地域歧视,地域攻击的现象已经非常严重了,网络论坛上板砖横飞,有不小的一部分就是这些。甚而影响到生活中,如择婿,择友,择工等。这应当是古已有之的陋习,算作中国的劣根性之一吧。《古今谭概》里记有这么一个崇明人(上海崇明岛)反驳太仓人(江苏):”崇明人固不才,然非我;太仓人固多才,然非汝。何得相欺!“ 。这句话可做大部分地域歧视攻击的反驳之语。
2. 有试图扮人生导师的,教导我们说“如果一个人只是质疑并不建设的话,那就只会走向扭曲”, 却不知苏格拉底的主要工作就是整天在街头诘问他人,留下的遗作还是柏拉图整理的言论。(且不说结论有些来得莫名其妙)
3. 记录一下“SICK”这个词,和前段时间欧债危机是的“PIGS”有异曲同工之妙。不同的是国内媒体是不可能大肆宣传的。
4. 想起当初高中时候被物理黄金时代的一些如爱因斯坦,波尔,海森堡这些人物所激,还有志于物理这一行的,却因种种选择了"程序猿“,不胜唏嘘。
5. 17世纪的基督教中有一种命定说:人即使行了足够的善行,没有神恩之助绝不足以获得拯救“,主要理由是“基督为拯救全人类而死,若只是夸张善行以获得救赎,则使基督为拯救人类而死变得似乎是多余的了”。帕斯卡(即物理中的用于压强单位命名之人,同时亦为一著名哲学家)极度支持这种说法,相反教皇教廷却刻意压制这种理论。压制是通过下发圣谕进行的,有趣的是其并未刻意反驳禁止命定的学说,而且其中有这样一条”任何人说基督是为了所有的全人类而死,是一种半柏拉杰派的异端“。
6. 帕斯卡的名言:人不过是一根芦苇,自然界中最脆弱的东西,但他是一根有思想的芦苇。
7. 看了近来大火的《舌尖上的中国》,联想起一个问题:若所有的大小”公仆“们都看了这纪录片,却也非幸事。
8. 边听久石让的音乐,边写代码,算作一小小快事。