tag:blogger.com,1999:blog-60123857560733746872024-03-14T12:38:45.813+08:00春露如冰杂七杂八的腹中之诽Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.comBlogger24125tag:blogger.com,1999:blog-6012385756073374687.post-15737415575574706432013-01-26T21:20:00.001+08:002013-01-26T21:20:41.674+08:00文件描述符传递方式的开销<p>以前提到过用文件描述符传递方式解决多进程惊群问题。最近实际测试了一下这种实现,发现实际效果不佳。较多进程无锁方式(nginx的实现减少进程锁)差得多,仔细思考了下,理论上应该这样解释这个原因:</p> <p>1. 进程间文件描述符传递方式在接收一次连接时,整个系统会有 accept, sendmsg, recvmsg, epoll_ctl四次系统调用</p> <p>2. 多进程无锁方式尽管有惊群效应,但接收一次连接时,最多N进程 × 1(accept)次系统调用,而且sendmsg调用开销远较一次accept为大。</p> <p>3,文件描述符传递方式还存在进程间切换,以及发送接收数据的时间开销</p> <p>综上,Nginx的实现方式尽管复杂,却是最高效的方式。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-11068402106523465122012-11-25T20:52:00.001+08:002012-11-25T20:57:39.593+08:00一种HTTP模拟全双工Socket通信的实现最近几天把很早之前构思过的一种HTTP模拟全双工Socket通信的方法在Snova/GSnova C4上实现了,效果不错,这里简单介绍一下实现方法。若有其他对此感兴趣的朋友,可以一起研究讨论。<br />
Snova C4利用双HTTP连接 + <a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding">Chunked transfer encoding</a> 模拟实现一个全双工通信的TCP Socket。具体HTTP代理实现流程文字描述如下:<br />
<ul>
<li>浏览器发送HTTP请求到本地C4;</li>
<li>本地C4创建两个HTTP连接到远端C4,其中一个携带加密后的HTTP请求内容,另一个则只携带读请求;</li>
<li>(重要)远端C4收到第一个HTTP连接后,将HTTP请求解开,创建到目的Site的连接,发送具体HTTP请求,之后到本地C4连接马上返回;</li>
<li>远端C4收到第二个HTTP连接后,阻塞在第一个HTTP连接中创建的Socket读上,每读取一段内容,则将内容加密通过HTTP应答消息体返回给本地C4;注意这里的应答内容必须通过<a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding">Chunked transfer encoding</a> 方式发送;</li>
<li>本地C4收到第二个HTTP连接的应答后,不断读应答消息体,将解开的内容写回到浏览器。至此整个Proxy过程大致结束。</li>
</ul>
<br />
若是HTTPS代理的情况,稍有不同:<br />
<ul>
<li>浏览器发送Connect请求到本地C4;</li>
<li>本地C4创建两个HTTP连接到远端C4,其中一个携带加密后的Connect请求内容,另一个则只携带读请求;</li>
<li>(重要)远端C4收到第一个HTTP连接后,将Connect请求解开,创建到目的Site的连接,发送具体HTTP请求,之后到本地C4连接马上返回,携带“200 Established”应答内容;</li>
<li>远端C4收到第二个HTTP连接后,阻塞在第一个HTTP连接中创建的Socket读上,每读取一段内容,则将内容加密通过HTTP应答消息体返回给本地C4;注意这里的应答内容必须通过<a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding">Chunked transfer encoding</a> 方式发送;</li>
<li>本地C4收到第二个HTTP连接的应答后,不断读应答消息体,将解开的内容写回到浏览器;</li>
<li>同时本地C4不断读取浏览器连接Socket,将读取的内容通过第一个HTTP连接发送到远端C4;远端C4收到后,则不断写到socket中。</li>
<li>以上两步同时循环执行。</li>
</ul>
若是其他非HTTP协议的TCP代理,过程类似HTTPS的情况。<br />
<br />
其实,<a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding">Chunked transfer encoding</a>默认在HTTP协议中是请求/应答都可以携带的,若在HTTP请求中也采用类似上述应答的方式,效果应当更好。不过在目前的几个PaaS平台中,几乎都不支持HTTP请求带Tansfer-Encoding。<br />
最终的实现的效果相当不错,相比之前的心跳ping机制(也可以模拟全双工Socket通信),实时性大大提高,甚至访问视频网站这种对socket通信连接稳定性要求较高的场景也表现良好。<br />
题外的话:大部分PaaS限制了一个HTTP请求的最大时长,一般是30s。所以在C4的实现中是用一点小技巧绕过这个限制,需要实现类似机制的朋友可以提前注意一下。Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com2tag:blogger.com,1999:blog-6012385756073374687.post-49911328415902269532012-06-12T07:34:00.001+08:002012-06-12T07:34:45.195+08:00此时彼时的惘然<p>旅途的间隙中,终于于手机上读完了《1Q84》。</p> <p>据说,村上春树号称这是一部向乔治.奥威尔的《1984》致敬的一部小说,读毕之后却发现,《1Q84》只是一部纯粹的爱情小说而已,和《1984》这样的充满政治预言的批判小说的性质相差甚远,尽管村上春树也用了大量的笔墨进行似有所指的超现实描绘。也许过段时间会有另外的感受,大凡意识流一派的小说,都以摸棱两可的语言给人这样的模糊的感觉。</p> <p>在整部书中,青豆和天吾自十岁起互吸引,却无法传递彼此的心意到对方。相距了二十年才在超现实的”先知”帮助下得知彼此的心意,彼此的存在。全书的最后,青豆和天吾终于二十年后见面了,并一起逃离了超现实的1Q84年,来到了现实的1984年。全书的剧情就此终止。</p> <p>现实的生活可不会像小说描述的那样,这里没有任何的超现实的先知来告知你彼此的想法,来做沟通的桥梁,错过了便真的可能永远错过了。“此情可待成追忆,只是当时已惘然”。此时彼时的惘然,大都只会留待以后来追忆。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-26442903004153565592012-06-06T22:55:00.001+08:002012-11-25T20:14:52.311+08:00分裂的神经技术:<br />
继续在X项目花费零碎时间。这几天一直纠结于一个问题,抽象成计算机语言描述就是:<br />
一个二级int hashmap(key为int),即hashmap的value是另一个int hashmap, 如何按照规则A输出其中指定起始位置,指定个数的元素,元素在第二级hashmap的value中。<br />
规则A:按照元素所属的hashmap间隔排列,即一级hashmap含10个二级hahsmap,若输出10个元素,则10个元素分属10个hashmap;<br />
直觉的实现应该是全部将元素输出到数组,按照上述规则排序并输出。这种方法效率非常低,增加了一倍的空间存储临时元素,并耗费大量CPU排序,当元素个数巨大时,这样的算法对系统的影响是非常大的。<br />
今天专门抽出时间仔细思考了这个问题,用了一种方法简洁的实现这个需求:用vector代替第二级hashmap,这样输出元素时,记录每次的输出的vector下标,即可近似的用二维数组的输出规则输出元素。这样的实现只用了20行左右代码,效率也相当高,算法复杂度等同于顺序迭代访问每个元素。这里的要点在于用vector代替原先hashmap。<br />
有时,针对某些问题,用另外一种思维方式会取得意想不到的效果。<br />
<br />
胡思:<br />
重又将20余年前的历史在wiki上回顾了一次。每次看都有不同的感受,不同的思考,特别是在读过《1984》,《俄国人》之后。李贺诗言”临岐击剑如铜吼“,大概就是目前这种感受。<br />
村上春树也在《1Q84》中描绘了一个初始以社会主义为目的后逐渐演变为类邪教的组织。大约持统一思想论的组织,无论高尚与否,大都最后都会异变。<br />
“没人要和你玩平等的游戏 每个人都想要你心爱的玩具”——《亚细亚的孤儿》Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-83137115701561509432012-06-02T23:05:00.001+08:002012-06-02T23:06:58.165+08:00磨损胸中万古刀前两日,读到唐代的刘叉的一首小诗:<br />
<br />
日出扶桑一丈高,<br />
人间万事细如毛。<br />
野夫怒见不平处,<br />
磨损胸中万古刀。<br />
<br />
自己胸中的那把刀,如今已是磨损大半。非唯是见多了不平,更有面对现实的无力感。<br />
如今这个时代,将来究竟如何,未知的依然很多,改变也会很多。只是在将来四顾心茫然时,希望依然能从胸中拔出一柄刀,即便其已磨损到已无锋刃。Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com1tag:blogger.com,1999:blog-6012385756073374687.post-26077827631203731812012-05-28T20:57:00.001+08:002012-05-28T20:57:40.103+08:00Linux下传送文件描述符的几个问题<p>这两日仍抽空忙于项目的设计开发,遇到了两个关于Linux下传送文件描述符的问题,记录如下:</p> <p>1. Linux不支持类似SystemV的流管道传递文件描述符(即非FIFO/tcp socket等),只支持通过UnixSocket方式。目前只有类似Solaris的系统支持前者。</p> <p>   不得已,修改了arch中相关代码,单独打开了一对UnixSocket专用于文件描述符传送。</p> <p>2. 64位系统下,接受文件描述符侧进程在recvmsg调用返回后结构<strong>struct msghdr</strong>变量中<strong>msg_controllen</strong>大小较结构<strong>struct cmsghdr</strong>变量中<strong>cmsg_len</strong>大4个字节;在32位系统下两者相等。</p> <p>    在64位系统只传送1个文件描述符的情况下,前者大小为24字节而后者20字节。若按照APUE中代码的判断规则则是失败的,按照UNP中则可以通过。(Ubuntu 64/32)</p> <p>尤其是后一问题,折腾了许久才发现32位与64位的不同,目前参考UNP修改了判断语句以规避此问题,后续有时间的话还需要对原因进一步探讨。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-79932188954602786542012-05-26T16:08:00.001+08:002012-05-27T10:07:26.067+08:00腹诽31. 如今地域歧视,地域攻击的现象已经非常严重了,网络论坛上板砖横飞,有不小的一部分就是这些。甚而影响到生活中,如择婿,择友,择工等。这应当是古已有之的陋习,算作中国的劣根性之一吧。《<b>古今谭概</b>》里记有这么一个崇明人(上海崇明岛)反驳太仓人(江苏):”崇明人固不才,然非我;太仓人固多才,然非汝。何得相欺!“ 。这句话可做大部分地域歧视攻击的反驳之语。<br />
2. 有试图扮人生导师的,教导我们说“如果一个人只是质疑并不建设的话,那就只会走向扭曲”, 却不知苏格拉底的主要工作就是整天在街头诘问他人,留下的遗作还是柏拉图整理的言论。(且不说结论有些来得莫名其妙)<br />
3. 记录一下“SICK”这个词,和前段时间欧债危机是的“PIGS”有异曲同工之妙。不同的是国内媒体是不可能大肆宣传的。<br />
4. 想起当初高中时候被物理黄金时代的一些如爱因斯坦,波尔,海森堡这些人物所激,还有志于物理这一行的,却因种种选择了"程序猿“,不胜唏嘘。<br />
5. 17世纪的基督教中有一种命定说:人即使行了足够的善行,没有神恩之助绝不足以获得拯救“,主要理由是“基督为拯救全人类而死,若只是夸张善行以获得救赎,则使基督为拯救人类而死变得似乎是多余的了”。帕斯卡(即物理中的用于压强单位命名之人,同时亦为一著名哲学家)极度支持这种说法,相反教皇教廷却刻意压制这种理论。压制是通过下发圣谕进行的,有趣的是其并未刻意反驳禁止命定的学说,而且其中有这样一条”任何人说基督是为了所有的全人类而死,是一种半柏拉杰派的异端“。<br />
6. 帕斯卡的名言:人不过是一根芦苇,自然界中最脆弱的东西,但他是一根有思想的芦苇。<br />
7. 看了近来大火的《舌尖上的中国》,联想起一个问题:若所有的大小”公仆“们都看了这纪录片,却也非幸事。<br />
8. 边听久石让的音乐,边写代码,算作一小小快事。Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-3981110845435473512012-05-24T22:56:00.001+08:002012-05-26T08:25:18.809+08:00仰视皇天白日速最近从零开始写一个创业项目的后台代码,十余天的功夫竟已吭哧吭哧写了上万行代码,可谓“高产”了。同时遇到的并纠结的实际技术问题还是不少,例如mysql无异步C API,NFS存放图片,HTTP服务,protobuf,缓存,关键词搜索等问题,都需要时间一一解决。 不过好在尚有“先见之明”,前年底就开始独力写了一个已用到生产项目中的arch框架,为此次项目省事不少。<br />
这段时间也随手总结加强了几条在后台C/C++开发上的经验/教训:<br />
1. 尽量用进程协作方式,而非多线程<br />
2. 设计实现中,考虑对栈对象友好的方式而非堆对象<br />
3. 异步协议,而非同步协议<br />
4. 尽量避免对象池的应用,用优化的malloc实现代替,如tcmalloc,jemalloc等。(Boost的对象池在大量小对象(10w级)性能糟糕)<br />
5. 通用的功能考虑拆分到独立进程中实现,其它组件通过协议/进程间调用来访问。<br />
6. std::list的size方法不是常量时间,随list长度增加(这倒是以前没想到过的)<br />
7. 默认的G++编译器4.0之后已经提供了部分tr1实现,如hashmap->unordered_map等。<br />
凑足七条,算作“呜呼七歌兮悄终曲”吧。<br />
<br />
后记:<br />
1. 这两天读了几篇李商隐和杜诗,愈读愈发觉得积聚了不少沉郁之气。<br />
2. 联想到当下及数月之后,竟隐有“筵席渐散”之感。<br />
<br />Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-27453838067690236072012-05-21T23:03:00.001+08:002012-05-21T23:03:36.151+08:00尼龙,鱼玄机与薛涛<p>今日继续看一本介绍路易十四时代的书,读到一处介绍一个当时有名的女贵妇,甚至吸引了国王路易十四的沙龙主持者尼龙时,联想到的第一个中国类似的人物是唐代的鱼玄机,出身乐籍,交际广泛。不过却是早夭,不得善终。</p> <p>回头又想起唐代的另一个女诗人薛涛,应该是更类此人。薛涛亦是出身乐籍,也和当时名流颇多唱酬应和,年高七八十才辞世。《红楼梦》中有几节提到“薛涛笺”,典故即是出自此人。</p> <p>唐代还有几个类似的人物,唐末宋初似乎还有个花蕊夫人比较有名,不过过了宋代李清照之后,女性中便很少有这类才华横溢的人物出现了,在元明清几乎是绝迹的,这当和逐渐禁锢的社会思想有关。</p> <p>不过,又想到《红楼梦》中描写的却是另外一番景象。难道竟是明清之时,易安居士之流皆不出深闺?</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-71563533598738272552012-05-20T11:53:00.001+08:002012-05-20T11:57:25.615+08:00风干的豹尸<span style="font-size: small;">昨日重又翻看了半日的海明威的短篇集,忽而想起了杰克.伦敦,一个和海明威有些类似的作家。两人终身示人以硬汉形象,最终都因不为世人知的原因自行了断了自己的生命。</span><br />
<span style="font-size: small;">为何自杀?论者纷纭,探幽者众。不过据自己观察,</span><span style="font-size: small;">海明威是把答案放到了《老人与海》,《乞力马扎罗的雪》,还有另外一篇记斗牛士之死的短篇等作品中。杰克.伦敦则在半自传《马丁.伊登》里回答。</span><br />
<span style="font-size: small;">雄奇者自绝于世俗,或可言以激烈的方式超脱于俗世。</span><br />
<span style="font-size: small;">附记:</span><br />
<span style="font-size: small;">摘抄《乞力马扎罗的雪》的开头如下,一个非常出色的开头,尚还没有像《双城记》的开头那样被用至滥俗:</span><br />
<span style="font-size: small;">"乞力马扎罗是一座海拔19710英尺的长年积雪的高山,据说它是非洲最高的一座山。马基人称西高峰为'鄂阿奇-鄂阿伊',意为上帝的庙殿。在西高峰的近旁,有一具已经风干冻僵的豹子尸体。豹子到这样高寒的地方来寻找什么,没有人作过解释。"</span>Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-33925738293616938222012-05-19T14:22:00.001+08:002012-05-19T14:36:44.176+08:00“活剥”《诗经》一句前两天不知怎么突然想起“既见君子,云胡不喜”一句,默诵数遍,倒是有些意味。<br />
默诵既多,兼被当天Twitter的“反动”信息浸染了一次,遂活剥生吞成“既为愤青,云胡不忿”。看起来似乎颇符一般愤青心态,兼志吾心。<br />
最后,仍然想不起为何无由来想起《诗经》中的这一句话,颇觉奇怪。<br />
——附注:昨天特意Google了下,发现知道此句当是从《神雕》一书中得来,而非《诗经》原文。想起此句之因仍是模糊难定。Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-74197342531792048882012-05-01T17:26:00.001+08:002012-05-19T14:34:46.923+08:00一种代替dynamic_cast的模版RTTI实现在arch框架中,存在这样一种场景:一个IO Channel上顺序注册了一组handler,分别处理不同类型的事件消息,则当某个事件消息到达时,需要依次判断handler是否能处理该类型的消息。(参考自Jboss-Netty的设计)。这类操作是在网络服务是进行,执行次数最多,因此需要考虑一个高效的实现。<br />
最初的实现是模仿Netty中Java的实现,用dynamic_cast判断(Java中是InstanceOf判断),但用dynamic_cast总觉得不太优雅,性能可能也存在问题(参考附注)。<br />
最近有些空闲时间,重新思考了下这个问题,用了另外一种方法代替dynamic_cast实现<br />
1. 注册handler接口方法用模版方法代替,将该携带类型信息的handler注册到一个和该类型相关的模版类中,如红色框部分。当然,在handler析构时需要去注册 <a href="http://lh4.ggpht.com/-LIkOz2quzso/T5-sAD0o3fI/AAAAAAAAACQ/U6-Rz4IsM40/s1600-h/image%25255B6%25255D.png"><img alt="image" border="0" height="154" src="http://lh4.ggpht.com/-or1q86pAVeY/T5-sEn3qPTI/AAAAAAAAACY/7KQkDDOY1GE/image_thumb%25255B4%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="578" /></a><br />
<a href="http://lh6.ggpht.com/-T5nJpIanBMs/T5-sFn8ghzI/AAAAAAAAACg/W9EEWLWtSEQ/s1600-h/image%25255B28%25255D.png"><img alt="image" border="0" height="150" src="http://lh6.ggpht.com/-MMX4KOcfw9E/T5-sI_mzDlI/AAAAAAAAACo/kamNxEwjqqc/image_thumb%25255B18%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="584" /></a><br />
2. 和该类型相关的模版类用静态set保存注册信息;<br />
<a href="http://lh6.ggpht.com/-H_mPmW9Guvk/T5-sJi2YcEI/AAAAAAAAACw/coX8NVImoRQ/s1600-h/image%25255B18%25255D.png"><img alt="image" border="0" height="147" src="http://lh4.ggpht.com/-_buiWdXAHkk/T5-sKpoqEDI/AAAAAAAAAC0/O3gIGhnMqoo/image_thumb%25255B12%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="578" /></a><br />
3. 判断事件类型与handler相关联信息,则可调用该模版类的静态方法。时间复杂度为set的实现决定。这里用tr1::unordered_set保存指针,时间复杂度为O(1)。 从理论上应当比用dynamic_cast快的多。(测试发现新方案较dynamic_cast实现快60%以上)<br />
附注:<br />
1. Google的编程规范强烈建议不要在产品代码中使用dynamic_cast。<br />
2. 据一份评测报告显示,一次dynamic_cast可能消耗数十微秒,这个评测待验证。数十微秒显然太慢了。Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com2tag:blogger.com,1999:blog-6012385756073374687.post-78337773835285526952012-04-22T21:07:00.001+08:002012-05-19T14:34:13.644+08:00仲宣楼头,千丈白发,怅盘桓而不能去 读杜诗《短歌行赠王朗司直》有感Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-70115021983849171432012-04-07T22:35:00.001+08:002012-05-19T14:34:21.222+08:00大量短连接的Server中的惊群问题<p>最近继续完善自己的多进程非阻塞网络服务框架arch,对于所谓的惊群(Thundering herd)的问题,查看了在这个问题上nginx源码以及其它一些非开源代码,公司内部代码中的处理方式,有以下的思考:</p> <p>惊群问题(Thundering herd problem),wiki上的解释简单说是“大量处理进程/CPU阻塞在一个调用上,由于某个触发条件导致都被唤醒,但只有一个进程能继续处理,其它均失败”。惊群现象会浪费较多的CPU。这种现象可以出现在很多场景中,以下讨论的具体场景为处理大量短连接的Server中的惊群。</p> <p>这种场景以Web Server为典型,一般有多个进程/线程同时监听80端口(poll非阻塞IO方式),则当有一个客户端连接上来时,所有的等待者均被唤醒,继而都调用accept处理,但只有一个能成功,其它均失败。</p> <p>目前较多的实现是基本不考虑惊群问题,如检查的第一个公司内部实现代码,lighthttpd。Redis因为是单进程单线程的实现,故没有考虑此问题。</p> <p>Nginx是用进程锁的方式解决该问题,即确保在某一个时刻,只有一个进程监听端口处理接收的连接;后续通过比较复杂的手段在多个进程间切换监听工作达到负载均衡的效果,仍然用到进程锁。</p> <p> </p> <p>Nginx的实现对于我来说过复杂了。我在arch中用了一个较为简单方式解决这个问题。</p> <p>arch是一个多进程的框架实现,故这里先讨论多进程模型下的一种较简单的解决方法:</p> <p>1. 一个主控进程(Manager)监听指定端口,将FD加入到非阻塞IO集合中,用类poll方式监听(select/poll/epoll)</p> <p>2. 启动N(N=CPU个数)个工作IO进程(Worker),建立Worker和Manager之间的通信连接(Linux下只能用UnixDomainSocket, 某些Unix可用Stream管道)</p> <p>3. 以上是进程初始化时的工作,当一个连接发生时,Manager接受此链接,马上将该连接的文件描述符发送到一个Worker进程(同时关闭文件描述符),马上返回到自己的等待状态等待处理下一个连接;(这里的选择Worker进程即是复杂均衡的判断逻辑,一般来说轮询选择就可以达到较好的平衡状态)</p> <p>4. Worker进程接收到文件描述符后,加入到自己的非阻塞IO集合,读取数据处理业务逻辑</p> <p>同Nginx的实现一样,arch也避免了惊群现象,不同之处在于arch用到了进程间文件描述符传送,避免了复杂的锁实现;而Nginx用了进程锁,避免了文件描述符传送的系统调用;后续会比较一下两者性能区别。</p> <p> </p> <p>多线程模型下较为简单,只需要采用类似Nginx的锁方式,结合arch的manager+worker模型:</p> <p>1. 启动Manager线程,监听定端口,将其加入到非阻塞IO集合中,用类poll方式监听(select/poll/epoll)</p> <p>2. 启动N(N=CPU个数)个工作IO线程(Worker)</p> <p>3. 当一个连接发生时,Manager接受此链接,马上将该连接的文件描述符交给一个Worker线程马上返回到自己的等待状态处理下一个连接;(这里的选择Worker进程即是复杂均衡的判断逻辑,一般来说轮询选择就可以达到较好的平衡状态)</p> <p>4. Worker线程接收到文件描述符后,加入到自己的非阻塞IO集合,读取数据处理业务逻辑。</p> <p>不过,对于编写C/C++的Server程序来说,多线程应当是尽量避免的。这倒是题外话了。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-19249987965911094132012-02-04T21:57:00.001+08:002012-05-19T14:34:21.215+08:00畏友<p>苏浚《鸡鸣偶记》: "道义相砥,过失相规,畏友也;缓急可共,死生可托,密友也;甘言如饴,游戏征逐,昵友也;利则相攘,患则相倾,贼友也。"</p> <p>以之观“方韩之战”,某些“公知”以及“队友”的言论明显只能归为”昵友”之列,不过倒还未堕落至“贼友”之属。唯有立场,罔顾是非,这一类人还侈谈“德先生”,若变革后的中国是这一类人当道,危险。</p> <p>最近颇对某些“公知”渐起警惕之心,以上志之。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-32719225189587491932012-02-04T21:24:00.001+08:002012-05-19T14:34:27.369+08:00《古今笑》一则<p>读《古今笑》,谬误部第五中开篇第一则颇为有趣,说的是乡下人经常以讹传讹,将寺庙,神像之原名附会为一些可笑的名称。如谐音“杜拾遗”变为“杜十姨”,“伍子胥”称为“伍髭须”;“文宣王”因为年代久远只余一“王”以及“宣”字中的“一”字,故被附近的和尚附会为“一字王佛”。及乡下人认为“伍髭须”没有老婆,而将“杜十姨”移到“伍髭须”相配,更是令人绝倒。</p> <p>另外从这则里也得到一个典故:吴王夫差在伍子胥被迫自杀后,以鸱夷盛伍子胥尸沉之江中,故称伍子胥为“鸱夷子”。《史记·越王勾践世家》也记载范蠡”变姓名,自谓 鴟夷子皮”,可能与伍子胥有一些关系。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-45849162130715313892012-01-20T22:33:00.001+08:002012-01-20T22:53:35.949+08:00Snova的C4在几个免费PaaS平台上的部署(Openshift, CloundFoundry, Heroku, Jelastic)<p>C4主要是从snova-heroku部分移植,修复了一些bug,性能大大增强,实用性大为增强,不再只是玩具试验性质的东东了。</p> <p><font size="3"><strong>Openshift</strong></font></p> <ul> <li>注册帐号</li> </ul> <p>          到这个链接注册<a title="https://openshift.redhat.com" href="https://openshift.redhat.com">https://openshift.redhat.com</a></p> <ul> <li>安装工具</li> </ul> <p>          安装命令行工具rhc,安装依赖ruby以及gem, <a href="https://openshift.redhat.com/app/express#quickstart">https://openshift.redhat.com/app/express#quickstart</a></p> <p>          注意, gem安装rhc可能被防火墙中断,可能需要设置代理,代理可以用snova设置,如</p> <p>                   <font size="2">gem install --http-proxy </font><a href="http://127.0.0.1:48100"><font size="2">http://<font color="#000000">127.0.0.1</font>:48100</font></a><font size="2"> rhc</font> </p> <ul> <li>部署</li> </ul> <p>           将snova-c4-server-[version].war 放到一个创建的空目录下,然后在命令行下进入该目录,逐个执行下面的命令:</p> <pre class="csharpcode"> rhc-create-domain -n <domainName> -l <yourId> -p <yourPassword> 创建主域名, 部署新应用是这一步可不执行<br /> rhc-create-app -a <appName> -t jbossas-7.0 -p <yourPassword> 创建app<br /> cd <appName> 进入上一步创建的目录<br /> mv ../snova-c4-server-[version].war <appName>/deployments/ROOT.war<br /> git rm -r src pom.xml<br /> git commit –m “delete”<br /> git push 以上三步重新部署同一个app时可不执行<br /> git init <br /> git add .<br /> git commit –m “deploy”<br /> git push</pre><br /><br /><p><strong><font size="3">CloundFoundry</font></strong></p><br /><br /><ul><br /> <li>注册帐号</li><br /></ul><br /><br /><p>          注册, <a href="https://my.cloudfoundry.com/signup">https://my.cloudfoundry.com/signup</a>, 注意,注册不是马上成功,似乎是第二天才会收到注册成功的邮件</p><br /><br /><ul><br /> <li>安装工具</li><br /></ul><br /><br /><p>          安装命令行工具vmc,安装依赖ruby以及gem,和openshift的工具rhc安装过程类似</p><br /><br /><p>          <a href="http://start.cloudfoundry.com/tools/vmc/installing-vmc.html">http://start.cloudfoundry.com/tools/vmc/installing-vmc.html</a></p><br /><br /><ul><br /> <li>部署</li><br /></ul><br /><br /><p>          将snova-c4-server-[version].war放到任意的空目录下,然后在命令行下进入该目录,逐个执行下面的命令</p><br /><br /><pre class="csharpcode"> vmc target api.cloudfoundry.com<br /> vmc login<br /> vmc push <appname> —— 此处appname为任意名称,为域名一部分,此命令执行后有后面的交互,参照下面的输入Y/N<br /> Would you like to deploy from the current directory? [Yn]: Y<br /> Application Deployed URL [<appname>.cloudfoundry.com]: <回车><br /> Detected a Java Web Application, <span class="kwrd">is</span> <span class="kwrd">this</span> correct? [Yn]: Y<br /> Memory Reservation (64M, 128M, 256M, 512M, 1G, 2G) [512M]: <回车><br /> Creating Application: OK<br /> Would you like to bind any services to <span class="str">'snova4'</span>? [yN]: n<br /> Uploading Application:<br /> Checking <span class="kwrd">for</span> available resources: OK<br /> Processing resources: OK<br /> Packing application: OK<br /> Uploading (843K): OK<br /> Push Status: OK<br /> Staging Application: OK<br /> Starting Application: OK</pre><br /><style type="text/css"><br />.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }</style><br /><br /><p><font size="3"><strong>Heroku</strong></font></p><br /><br /><p> 参考snova中heroku的wiki即可</p><br /><br /><p><strong><font size="3">Jelastic</font></strong></p><br /><br /><ul><br /> <li>注册帐号</li><br /></ul><br /><br /><p>          <a href="http://jelastic.com">http://jelastic.com</a></p><br /><br /><ul><br /> <li>部署</li><br /></ul><br /><br /><p>          完全图形化的操作,无需安装工具,按照说明将war上传并deploy到ROOT下即可</p><br /><br /><p>          <a href="http://jelastic.com/docs/upload-deploy-application">http://jelastic.com/docs/upload-deploy-application</a></p><br /><br /><p><strong><font size="3">后记:</font></strong></p><br /><br /><p>这几个所谓的PaaS平台中,粗略观察下,纯以平台IO性能而言,似乎Openshift较差,CloundFoundry最好,已接近或超过AppEngine;部署上,Jelastic部署最为简单,完全界面上操作,其它几个则相对复杂,需要安装各种复杂的命令行工具部署,简直到了”非程序员不能为也的地步”了。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com1tag:blogger.com,1999:blog-6012385756073374687.post-22797781567726335252012-01-09T22:50:00.001+08:002012-05-19T14:35:32.297+08:00字符串匹配算法<p>今日,研究了一天的字符串匹配算法,小有所得。主要是从这个链接学习, <a href="http://www-igm.univ-mlv.fr/~lecroq/string/">http://www-igm.univ-mlv.fr/~lecroq/string/</a></p> <p>理论上,这里算法都比glibc中strstr的算法复杂度小,但在实际场景中,特别是和目前的开发的产品中关键字匹配场景下,无论是<a href="http://www-igm.univ-mlv.fr/~lecroq/string/node14.html#SECTION00140">Boyer-Moore</a>还是<a href="http://www-igm.univ-mlv.fr/~lecroq/string/node8.html#SECTION0080">Knuth-Morris-Pratt</a>等这些经典的算法实现都比strstr慢得多,而strstr的默认算法仅是一种高度优化过的<a href="http://www-igm.univ-mlv.fr/~lecroq/string/node3.html#SECTION0030">Brute Force</a>实现(Linux下C的测试结果证明如此,java下根据默认string.IndexOf算法看来,可能另有差别,需要进一步证明)。</p> <p>目前得到一点结论是,这些经典的算法中都有预处理阶段,而<a href="http://www-igm.univ-mlv.fr/~lecroq/string/node3.html#SECTION0030">Brute Force</a>实现并无此阶段,当是预处理阶段耗时较多造成的差别。</p> <p>(从200字节中查找20字节字符串1000000次, strstr:0ms, 其它最优的实现是250ms+)</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-12592326383573249202012-01-07T18:31:00.001+08:002012-05-19T14:34:36.204+08:00关于《郭嘉传》的一事<p>维基上关于林彪的条目中有一段说1966年9月,毛让林读《三国志》中的《郭嘉传》和《宋书》中的《范晔传》。</p> <p>重读《郭嘉传》,契合当时环境下最重要的就是是曹操在郭嘉死时对大臣们说的一段话,就是毛对林的暗示,以太祖自喻,以郭嘉喻林。(林也是较为年轻,亦是多病之身)</p> <p>毛这里借曹操之口告诉林值的以天下事相托,不过另外半句从《范晔传》中传达的信息却是险恶万分,这里暂且不谈。</p> <p>”及薨,临其丧,哀甚,谓荀攸等曰:「诸君年皆孤辈也,唯奉孝最少.天下事竟,欲以後事属之,而中年夭折,命也夫!」“ ——《郭嘉传》</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-79329058870165251592012-01-02T22:54:00.001+08:002012-05-19T14:34:46.929+08:00百年一遇的2011<p>2011已经结束了, 无论是说今年是辛亥百年还是今年有世纪光棍日,这都是百年难遇的年份,似乎注定会发生不少值得纪念的事情。于己而言,在2012的开始,目前船票尚无的状态下,应该有必要对过去的一年写些什么。</p> <p>2011年是我到目前这家公司的第二年,年中的时候开始了一个大的项目,由于在2010年底开始参考Netty实现断断续续地写了一个C++的多进程的网络服务框架,借助这个框架,倒是比较顺利地完成了这个项目(4人4个月的时间83,000L,代码稍多,这当中很佩服其中一位女程序员,可能是我见过的最聪明的一位女生了),另外最主要的成果是这个框架也已经成熟了,可以用在以后的工作中,另外若有机会,也可以考虑包装宣传一下。开源也可适当考虑。</p> <p>另外,业余的开源项目方面,之前发布一年有余的一个开源项目在工作中的项目开始前不久就完全停滞了,一直到工作项目发布上线后一个月才想起;后来的一段时间基于前段时间的工作中的感悟,完全重构了这个开源项目,更名为snova,性能,扩展性都大幅提升,心里也有了小小的成就感,算是2011的善终吧。</p> <p>2011发生的太多事情也使自己愈发变得愤青,却仍然奉行犬儒主义,不发一言,亦无任何行动,或是民族的劣根性?  这一年遇一所谓的“官二代”,其人其行其为于己格格不入,于此同时重读《俄国人》一书,感受良多,却仍只是慨叹“天凉好个秋”。读完乔治.奥威尔的《1984》也给自己相当长时间的震撼,同时试图研究卢梭,无果。</p> <p>到年底,高高兴兴地过完百年难遇的世纪光棍节后,除了开始重构开源项目外,倒是"天下承平,四海无事“。 年底的最后,在政府的感召之下,开始萌发一丝拥有”广厦“一间的幻想,当然,大部分的幻想在破灭之前都真实地触手可及。</p> <p>在2012的开始展望一下2012,发现除了随太白慨叹一句”欲渡黄河冰塞川,将登太行雪满山“以外,竟无一语其他。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com1tag:blogger.com,1999:blog-6012385756073374687.post-56088626505988580532012-01-02T20:57:00.001+08:002012-01-02T21:04:12.199+08:00关于snova-heroku的一二三<p> </p> <p>大约圣诞节前一天,发现了heroku这个PaaS平台,看了一下wiki以及heroku.com上的介绍,觉得有些意思;后来正好工作上没多少事情,花了半天仔细看了一下这个平台相关技术架构,虽然不甚了了之处仍有不少,不过大致上已经了解到从技术角度而言对于heroku,可以用来做些什么以及不可以做些什么。</p> <p>heroku本质上是一个分布式环境,但对于开始的免费账户只提供一个dyno(heroku的特有概念,类似Instance),CPU大约是750h/month,带宽没有限制。支持的语言较多,主要是ruby,另外python/java目前也支持。Runtime上限制远比Google的AppEngine为少,以Java为例,从语言角度来看几乎没有任何限制,目前观察到的唯一“限制”就是App的input只能是HTTP请求,当然这是基于Web的PaaS的必要条件,也谈不上限制了。</p> <p>后来的一天,着手写了一些代码,初步验证开始的想法正确;由于之前一段时间写了一个基于GoogleAppEngine的proxy,而这个proxy有不少Appnegine平台的限制,正好heroku没有这些限制,于是开始着手实现基于heroku的proxy。</p> <p>实现的过程总体上是顺利的,除了当中偶发奇想用一些P2P技术代替HTTP请求耽搁了几天,最后大约2011.12.30完成所有实现。之后两天主要修改项目上的wiki以及snova项目的其它子项目,在2012到来的第一天正式release。</p> <p>注:1. 用一些P2P技术代替HTTP请求从原理上任然是可行的,不过相对目前的实现几乎没有任何性能优势;2. 目前的实现通过异步IO+定期轮询绕过了较多的技术限制,但这种技巧在分布式环境中算是一种错误方法,只不过由于免费环境只有一个dyno才得以利用。</p> <p> </p> <p><a href="http://code.google.com/p/snova/wiki/HerokuInstallation">http://code.google.com/p/snova/wiki/HerokuInstallation</a></p> <p>2012.01.02 小恙中记</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-69986272143374750432010-11-17T22:03:00.001+08:002012-05-19T14:34:55.382+08:00从季札许剑开始<p>       季札心欲许徐君宝剑, 然”徐君已死,于是乃解其宝剑,系之徐君冢树而去。从者曰:‘徐君已死,尚谁予乎?’ 季子曰:‘不然。始吾心已许之,岂以死倍吾心哉!’“。 </p> <p>       这一段如果单独从《史记》中摘出来放到《世说新语》中,基本是看不出有何突兀之处的,但现在从《史记》中看到这样一个人物,倒是有突兀之感。《史记》这往前亦或往后,都找不到这样的一个令人击节的人物,多是帝王将相建大功立勋业者。此外,季札”好论音乐,论时政,臧否人物,逃而不受王位“也和一般意义上的魏晋名士形象有太多相似之处。所以,所谓的魏晋名士这一形象,可能源头在这里,而发扬光大于魏晋。</p> <p>       太史公最后用仁义道德评价季札”仁心,慕义无穷“,倒显得有些道貌岸然了,有为蛇画足之嫌。</p> Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-82817724415859356292010-10-23T00:06:00.001+08:002012-05-19T14:34:55.400+08:00腹诽2<p>1. 奇文共赏 <a href="http://bbs1.people.com.cn/postDetail.do?view=1&id=103783099&bid=6">http://bbs1.people.com.cn/postDetail.do?view=1&id=103783099&bid=6</a></p> <p> 对错姑且不论,以糟糕的制度下产生的畸形的人是否自愿来论证这个制度是否合理可谓可笑之极。论证过程中的思维方式/角度尤为可恨。</p> <p>2. “History is written by the victors.” </p> <p>3. “报纸是教育人民的工具,必须使其为国家而服务。”--- 戈培尔</p> <p>4. "虞卿以魏齐之故,不重万户侯卿相之印",太史公以为庸夫尚知其不可。吾以为实乃为友知其不可而为之。</p> <p>5. 程序员应该具备类似数学推理的思维/才能,这一点在检查软件崩溃时遗留的“尸体”时尤为重要;但目前似乎并没有这方面的一个完整的理论体系</p> <p>6. 人是思想的苇草</p>Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0tag:blogger.com,1999:blog-6012385756073374687.post-25474315324747390262010-01-10T18:23:00.000+08:002012-05-19T14:34:55.369+08:00腹诽1<div id="blogDetailDiv" style="font-size: 16px;"> <p>1. Obviously, there is too many rule makers with profittering nature.<br />2. 不仅仅科学领域缺乏哲学思辨的传统。卢梭之《社会契约论》的形成也是哲学思辨的结果,政治制度形成仰赖于此。<br />3. They claim that they are doing something noble, and over 87.53% of people support them. In the meantime, you can find so many evidences on TV, radio, website.<br />4.柏拉图的囚徒困境中,面壁的囚徒其实并不知道其囚于穴居之中——也许穴居之外之人也刻意告诉他们其实在穴居之外。(.....)<br />5. There are so many people, include me, claim that they believe some principles and trust an orgnization. Well, sometimes they lied,and we all know that.</p> <p>6. “不求有令名于天下,但求令名于君上。”</p> <p>7. Remember you are in the mainland of China if you are shocked by some news.<br /></p></div>Anonymoushttp://www.blogger.com/profile/12858849710842386126noreply@blogger.com0