计算机网络技术架构中,哪些设计中使用了pipeline技术

By操作的功能而不再需要用户编寫自定义的JavaScript例程。

 3 每个阶段管道限制为100MB内存如果一个节点管道超过这个极限,MongoDB将产生一个错误。为了能够在处理大型数据集,可以设置allowDiskUsetrue来在聚合管道节点把数据写入临时文件这样就可以解决100MB内存的限制。

Document大小限制为16M可以通过返回指针解决,版本2.6中后面:DB.collect.aggregate()方法返回┅个指针可以返回任何结果集的大小。

    先根据$group在计算平均值,只会针对数字的进行计算,会对字符串忽略

 
 





1、我们通过相同的产品类型来進行分组然后查询每个相同产品卖出的数量放在数组里面





将表达式的值添加到一个数组中(无重复值),这个值不要超过16M不然会出现錯误


$first:返回每组第一个文档,如果有排序按照排序,如果没有按照默认的存储的顺序的第一个文档


$last:返回每组最后一个文档,如果有排序按照排序,如果没有按照默认的存储的顺序的最后个文档




}

随着无线通信技术和计算机网络技术无线网络技术的发展移动通信系统和无线连接方式逐步成为人们关注和研究的热点。第四代移动通信系统(4G)集多种无线协议融为一体而多协议无线设备需要系统内ADC具有多样化的输出精度和工作频率。为了满足多协议无线设备的需求并从降低系统功耗和芯片面积出发,本文在动态配置ADC系统与电路设计方面开展系统性研究研究精度与工作频率可配置的AD...  

相关论文(与本文研究主题相同或者相近的论文)

同项目论文(和本文同属于一个基金项目成果的论文)

}

    这个题目有点大我在此仅限于技术层面。

    这篇文章呢很早就想写真正促使我付诸行动的是大约两个月前我开始给Mimas team讲街机模拟器的设计,大家普遍很漠然大概完全搞鈈懂我为什么要讲这种东东,而且还是用离嵌入式开发工程师似乎很遥远的JavaScript / HTML我的本意是想通过一个不是太复杂而且具备一定趣味性的案唎,让大家体会怎么对已有的代码做重构怎么提高软件的可重用性。至于为什么选择用这样一个案例基于以下考虑:

    首先,我觉得这個东东比较好玩而且那个实现有比较详细的教程,能让大家快速理解GameBoy CPU架构和模拟器设计思路毕竟一个8位的CPU已经使模拟工作足够简单了。这个案例是我在PDUCC的时候注意到的后来我曾经对它做过一些改动。我印象中应该给Atlas team发过一个链接同时还附带着一个JavaScript写的X86的模拟器

其次,JavaScriptLua其实很像(不是指语法啊)他们都是基于原型的语言,我们学习起来并不困难而且,我们还需要提高的一项技能就是快速的学习能力像这种语言类的学习周期一般就是两三天搞定基本内容和脉络,当然一些高级特性可能需要更多的时间去体会我真的不希望再看見当初LuaSocket这种一两个小时就能搞懂的库,报价要好几天

第三,Web发展到今天已经有很强的表达能力了桌面应用和Web应用的界限正在变得模糊,尤其是HTML5出来之后大家去看看ChromeApplication就能体会到了,而且很多的手机前端应用已经开始用Web开发这是一个值得关注和学习的领域。当Java刚出现的時候我鄙视了半天,跑得又慢GUI又丑,而且还想做个大而全的平台结果我错过了学习Java最好的时机,导致了我今天依然只能做非常平庸嘚Java设计曾经也很鄙视早期的Web开发,不就是写写HTMLCGI么木有什么技术含量。结果今天Web技术如日中天你会发现整个Web技术栈现在已经相当复雜了。我20年前就接触过LispAutoCAD的二次开发语言是AutoLisp)那个时候不可能明白Functional Programming,而且我看见Lisp的前缀表达式就头大因为当你面对一个长长的表达式嘚时候,你一眼看不出来那是个啥可绘制图纸那满篇的都是计算坐标和尺寸,所以当时我很反感Lisp(为了蹭机器用只能忍了,那是个连鼠标都是奢侈品的年代你能想象我很多时候画图都得手工输入命令,如果画一个三维的图我该多抓狂)谁会想到Functional Language在多核时代又抬起头來了呢。所以今天我不敢轻易看低任何事情再说,你怎么就知道未来的交换机软件里会不会跑JavaScript呢其实并不是不可能啊,比如用Node.jsOAM后端如果你玩过Beaglebone Black,你就会发现它提供了基于JavaScriptIO库和完整的Node.js环境对于这么popularJavaScript,居然木有人肯多看一眼我也是相当的纳闷啊。

    这个案例呢实質上折射出的是是我们要学习什么和怎么学习的问题我就发表一下个人的看法,从某种程度上讲也可以算做是在我的年假变为20天之际回顧一下我在公司都干了些什么以及我在做一些决定的时候的思路和背景 

每年我们都会列一堆学习目标,最终结果如何我就不清楚了公司不是学校,这就注定了其实没有多少专用的学习时间给我们平心而论,参加一个几天的课程对设计功力的提升是微乎其微的很大程喥上我把它看作是公司的福利和提供给一个有相关经验工程师的一个总结和回顾的机会。我的确在很多年前参加过Rational为期一周的OOAD培训但在此之前我已经有了很多的OO设计经验和理论知识。除了业余时间工程项目应该是学习的一个非常重要的途径。对公司而言实质上它不太關注项目的过程,结果决定一切但对我们自己的成长而言,这个过程的重要程度绝不亚于结果在项目中学习不是单纯的指理解这个项目的设计和实现过程,事实上它涉及到一系列的深层次的思考我就以前几个月的Spitfire Chassis的设计尝试为例。这个项目如果纯看结果很negative啊,很大程度上我们自己左右不了有人问我有失落感没,我开玩笑说哪能啊公司又没少发我钱。(再说项目乃至产品被Cancel这种事情经历的还少么:-))其实在每个项目执行过程中,我都会思考很多东西这足以弥补这个结果给我个人带来的负面影响,这里跟大家分享一下

从坏的设計中学习,而不仅仅是抱怨

  对于我们这些在大外企里的开发人员来讲不是每个人都有机会去做一个全新的设计,很多时候我们都在維护Legacy的代码而且是运行了一二十年的古董,里面鱼龙混杂精华和糟粕并存。我们经常会发出抱怨或听到抱怨:这是什么狗屎设计!你居然会抱怨了太好了,说明你不麻木其实呢,你会发现你所经历过的每个项目都很烂,只不过烂的程度不一样而已我相信若干年後一定会有人跳出来抱怨我们自己正在写的代码。如果你在职业生涯中能在Legacy系统中遇见过让你惊艳的设计那么你很幸运,我很羡慕你峩迄今为止还没有过这样的机会。而且很多时候我们不得不忍受着和烂代码打交道因为不管我们喜欢不喜欢,它毕竟事关我们的饭碗洳果仅仅停留在抱怨,除了释放一下负面情绪我们得不到什么。大部分代码一开始的设计意图肯定很高大上只不过之后的各种妥协,姩久失修导致了动不得也扔不得的两难境地。这其实是给我们的第一个警示一定要频繁的有意识的做代码重构,否则代码会腐烂的很赽我刚到公司的时候,写的第一个程序就是扫描ETOS所有的代码自动生成各个组件的依赖关系图,可以指定任意一个组件画出它依-赖的組件和依赖于它的组件图。我清楚地记得那是一个周五的下午我坐在公司大厦的过道里,一直干到晚上七八点钟代价是被蚊子叮了一個大包。看了那些乱麻一样的依赖图之后我就断念死心了,绝对不会动对ETOS做结构性重构的念头会死人的。如果再深入一步我们需要知道这个设计哪里做得不好。进入Spitfire项目之后我扫了一下文档和code,发现很令人费解尤其是告警处理,我根本就看不懂为什么那样做直覺告诉我这个设计不是很合理。(我认为一个好的设计一定是一个易于理解的设计)所以我紧接着对整个 PAd/CMS/CMSP 做逆向工程,生成了类图然後又花了很大精力对照代码补全类图和重新布局,这个时候我就能从结构上感知它的缺陷在哪里其实我当时生成这样一个图的一个主要目的是为了直观的告诉别人这个设计哪里不好,还真不是留给我自己用的我知道了这个东西烂,也知道了它为什么烂那么我会问自己,如果是我我会怎样去做。当然很多情况下我们根本没机会做这种重构或者重新设计,但在脑袋里演练一番其实就是一个自我提升的過程这就是PAd重新设计的想法出炉的始末。当然这里的一部分想法其实也源于我对 ETOS 抱怨之余的思考

Legacy系统的维护中,如果我们不得不沿著旧的路线走我们需要保持头脑清醒:我现在这样做是因为各种条件的限制,但我也知道其实还有更好的方式去做我们要警惕温水煮圊蛙的效应,这其实类似于一个洗脑的过程如果我们长期按照某种方式行事,我们很可能会倾向于潜移默化的接受它它会逐渐成为我們习惯的一部分,会让我们淡忘我们曾经认为它是不合理的在以后的设计中可能会不自觉沿用它。

刚才提到了抱怨也是一个好的开端,起码它让你发现系统什么地方可以做改进做一个懒惰的设计人员有助于你发出更多的抱怨,然后你需要做得就是如何消除这些抱怨懶惰是人的天性,设计人员倾向于做懒惰的人用户更是懒惰的人,设计要适应人的本性而不是有意识或无意识的创造各种门槛。我在team裏常说要注重Usability当你设计一个软件的时候,你要首先站在client(无论是外部客户还是内部developer)的角度考虑如何最大限度的简化client和目标软件的交互(包括需要传递的信息量和流程)。软件是写给别人看得表达一定要清晰简洁。你哪怕能省掉一个参数它其实就降低了使用者的记憶负担,降低了可能产生的潜在依赖关系最终提高的是软件的可维护性。我不知道Mimas的同学是否记得在做SP400 Chassis模拟器的时候我们需要一个类RPC嘚服务,开始的时候想基于IPOS IPC三天过去了,我们还没有一个能跑得哪怕是sample程序我当时和team说如果你不能在一天之内跑起来一个client-server,那至少说奣那个库的接口设计是失败的因为它不是通俗易懂的,想一想我们能不能用Javasocket类接口或类似的商业类库很快的写一个TCPCllientServersample程序所以峩当时决定我们用UDP自己实现,那至少一天也能出来东西吧而且额外的好处是跨平台了,我们可以在PC上测试我们写的大部分代码 

    抱怨的偠义就是能多简单就多简单,能少干就少干当你发现别人的代码你看不懂,当你发现做某件事情相当繁琐当你发现你需要知道太多的細节才能做一件事情,请毫不犹豫地大声抱怨你可以抱怨:

  1. 什么?一个Chassis的适配层居然有250K+行代码我认为50K差不多了吧?
  2. 天哪加一个告警居然有将近20步个步骤?谁能告诉我这是为什么我能做些什么使这个过程得到最大程度的简化?
  3. 整个IPOS居然没有一个通用的告警处理系统
  4. 告警的处理为什么会有多次的数据结构的变换,我真的没搞懂耶!
  5. 一个告警不就是一条记录么为什么还会对每个告警派生一个告警类?
  6. 怎么引入新的告警类型告警数据库的class定义都需要跟着变啊?我不喜欢这样哦
  7. 怎么会有AL Interface这么古怪的东东?一个PAd组件凭什么要暴露出1000+API伱想烦死我啊?我不写了你来。
  8. AL Interface为啥要直接由PAd的类去提供啊万一哪天AL Interface废弃了,不得改得鸡飞狗跳么
  9. 这个系统中怎么会存在一些这么巨大的class来颠覆我的三观?
  10. 拜托一些八竿子打不着的板卡都堆砌在一起,代码和目录结构就不能再划分的清晰一点么
  11. 我没兴趣知道PAd的具體细节,哪位神仙姐姐能告诉我加一块板卡怎么做能不能不在PAd里东刨一下西刨一下?我需要这些扩展集中在一个地方
  12. 现有的模拟器不恏玩,无法任意定义硬件状态我需要一个更加聪明好用的模拟器。
  13. 我已经接触过数个产品的Chassis设计了大家都在做相似的事情,可每个都囿独特的气质我厌烦透了,我能不能做一个能最大限度重用的设计
  14. 我厌倦了C/C++了,开发成本这么高还有无数的坑,我想做的更happy和傻瓜┅点

    可以说,我们前一阶段的设计基本上就是针对着这些抱怨来的 

Filter设计的第一天,还对IPOS一无所知的情况下就把原方案否定了因为我認为不能让人去干那种体力劳动,第一那是浪费公司的钱,第二那是一个完全不可以重用的方案,第三这种做事方式降低开发人员嘚成就感,直觉告诉我一定有更好的办法来解决这个问题机器才是干体力活的最佳候选,我们完全可以让机器去自动修改code重建Parse

因为我足够懒,所以看到公司居然在嵌入式产品推广JCAT这样一个单元测试框架去驱动产品的集成测试的时候感到非常的不可思议你能想象我们招聘测试工程师的时候并没有要求人家有多少编码的技能,然后突然要求大家都写Java代码大家要学习Java语言,Java平台JCAT框架还有访问测试仪的库,还有比这更抓狂和扰民的事情么我们的测试工程师更熟悉的是CLIPerl/Tcl之类,而不是Java政府行为我们无力抗拒,但至少我们想办法让自己过嘚更轻松一点所以我做了一个JCAT测试例自动生成的Innova(当然没过多久,我们又被拉进了CBA的怀抱JCAT就不了了之了)。当时的基本想法就是设计┅个更high levelDSL代替Java语言描述测试用例,然后自动生成符合JCAT要求的Java代码我花了整整一周的时间用JRuby实现了一个DSL engine,然后把对测试仪的调用封装成叻CLI操作这样在脚本中对目标box和测试仪就都统一为CLI交互了。不可否认那个Innova有骗钱的动机在。刚进公司的时候没有关注过Innova,因为当时觉嘚Innova是件很神圣的事情当有一天re-orgPDU MW,发现这里贴着满墙的Idea立刻认识到了我们Innova庸俗的本质,惊觉失去了很多变现的机会 

因为我足够懒,鈈想在乱麻一样的代码中迷失所以用Python编写工具分析log,自动画出ETOS软件升级的一个状态机子集 

    因为我足够懒,所以会在某次ETOS意图降低软件耦合的运动中(当然那是个可望不可及的梦)用Python写了一系列工具去分析某类Passive Object API集合被哪些模块调用,某类Message在哪里被引用并自动生成相应嘚excel表格。 

Master的时候不想忍受每次编辑完excel表格,还要手工抄写任务列表贴在白板也无法忍受需要手工设定一个sprint理想的Burndown chart,而且还需要手工刨除各种假期所以我会用Python写了那个excel模板的处理工具,可以自动生成要打印的任务列表小贴贴和更新burndown chart

Wrapper。虽然上面没同意但在team里我是要求叻的。且不说OpenSAF本身如何从接口设计角度来讲,绝不能算是一个优雅的软件随便一个组件就有几百页的编程手册,连个Log的手册都一百页我简直都要跪了。API里指针的指针'**'就开始让人晕了它居然还有不少'***'。如果没有一个简单明了的C++ Facade这得浪费多少人的生命啊。

注重提升通鼡计算技术的功力

我曾经在各种场合下提过我们需要注意提高自己的通用计算技术这是我接触过的大部分嵌入式开发人员的短板。做一個产品我们需要掌握领域知识和计算技术交换机恰恰是对领域知识要求比较高的,所以我们大部分人的精力其实是放在学习和掌握领域知识上了计算技术的不足反而被领域知识给掩盖了,我感觉很多人是在凭着直觉写程序作为一个有潜力的开发人员,我认为他应该不僅仅是熟悉领域知识而且还应该是一个计算专家,也就是说在我们的知识结构中领域知识应该和计算技能得到均衡的发展。领域知识決定了要表达的内容领域知识的不足将导致我们没法写出满足用户需求的软件;计算技能决定了系统的表达方式和骨架,计算计能的缺乏将使我们不清楚软件能不能以合理的代价完成对一个开发人员来讲,领域知识相对来说很大程度上是能速成的而计算技术是需要长期的理论和实践积淀的。从我个人的观点来看我们OAM部门开发人员的知识结构中应该是计算技能远重于领域知识,因为相对于L2/L3我们的领域知识还是比较容易掌握的。我在这里无意贬低大家掌握的特定产品的特定OAM相关的知识那是你在公司安身立命的前提条件和资本,我想表达的是大家在学习过程中要注意均衡和取舍从长远来看有些知识在你的知识体系中未必会处在最重要的位置,特别是特定硬件特定平囼相关的知识很可能就是过眼云烟。在 DOS的时代(那是个自力更生的年代至今仍怀念那个让我打下扎实的软件基础的时代),我曾经从朂基本的画点、画线、区域涂色开始利用BIOSOS、视频控制器开发过一个比较完整的GUI环境,我曾关注过如何通过控制软盘控制器做出各种千渏百怪的磁道(早期的软磁盘加密是削尖脑袋在软盘上写上独一无二的无法复制的签名比如在用高密度的访问方式在低密度盘两个磁道Φ间写几个扇区,或者格式化出一个非标准磁道还有人变态的造出螺旋型磁道),我曾关注过DOS下病毒如何去感染磁盘文件如何加载自巳和取得控制权,我写过在DOS单任务环境中用多个栈模拟多任务切换我学习过XMS/EMS只是为了在DOS实模式下访问扩展内存(1MB以上的地址空间),但隨着计算机网络技术软硬件技术的发展眨眼间这些知识统统变成了昨日黄花,很多秘笈就被无情归零了从此之后,我学乖了很多在佷specific的知识上的投资比重是比较小的,除非绝对必要通用计算技术背后的支撑就是坚实的理论基础,我们今天的一些绚酷的应用技术在十姩之后很可能就烟消云散了但其背后的计算机网络技术科学、数学、逻辑的知识依然是有效的。

由于各种原因一个软件开发人员很少會长期固守在某个领域,如果不注重计算技能的提升当切到一个全新的领域时候,他很有可能会感到茫然我个人参加工作以来做过移動网络NMS的应用层,做过光网络NMS的适配层做过EMSSNMP适配,做过交换机的L2/L3做过P2PDPI,做过P2P网络的搜索做过手机应用,做过交换机的OAM当从一個领域到另一个领域的时候,从来没有过不适应的感觉因为我知道那只是运用我的计算技能去解决一个新的问题而已,和我以前做的事凊没有什么本质区别当然你可以认为那些大部分还是跟电信有关联的,但是如果现在把我扔到互联网领域或者游戏领域我相信我还是能很快找到感觉的。 

有一点需要澄清的是我说某些知识相对没有那么重要,并不意味着在运用这些知识时获得的技能不重要换句话说,我们要善于总结和提炼在这个过程中获得的通用计算技能事实上,那个DOS下的GUI组件库的设计奠定了我的OO设计基础我在看Ardunio的时候又想起叻我曾经做过的DOS多任务,然后我就上网查发现已经有人提供类似的库了。在Chassis开发过程中Kane同学曾经表达过学习Lua的良好愿望,我的建议是單纯的Lua令测试工程师获益不多Lua设计之初也没想作为Full Stack的开发语言,如果觉得Perl老旧了还不如学习PythonRuby但我认为更重要的一点是我们对目前基于PerlARTS平台的深层次的理解,想比之下Perl语言本身并没有那么重要当前的设计有什么优点?又有哪些缺陷有没有改进的余地?如果想从測试工程师向开发工程师的方向迈进一步我觉得更应该关注表象之下的设计理念,否则结果就停留在又学习了一门时髦的语言而已

特別对我们OAM部门转做嵌入式系统的前Java工程师(尤其是前端工程师)建议,大家以前在应用层的设计经验非常重要应用层的很多设计理念在這里依然适用。很多人认为前端设计是机械的活就是摆摆控件,写一些简单逻辑错!在我心目中把前端做好是一个技术活,首先这关系到人机界面设计关系到Usability的意识,工程师得时刻站在用户的角度思考如何降低操作成本,其次前端软件很容易做烂,尤其是业务流程复杂的时候界面逻辑很容易和业务逻辑搅在一起,这就是为什么大家一直在不厌其烦得提MVC的原因前端软件和后端软件一样需要良好嘚架构设计,需要考量一系列的质量属性第三,个人感觉一个好的前端工程师对OO的理解是比较深刻的一个GUI类库(比如Java Swing)能体现出很多嘚OO设计准则,而且前端设计中我们常常不满足于标准控件提供的功能而去设计定制的控件(看看我们AndroidiOS手机应用就知道了,很多花里胡哨的界面都是标准类库里没有的)一个可重用可扩展的控件设计往往需要扎实的OO基础。最后一点有前端的基础,更有助于写出方便友恏的工具提高生产效率。

    我们做软件的过程实际上就是一个表达的过程,我们需要寻求一种清晰的描述来表达一个业务问题是如何转換为一个可计算的问题的也就是如何从Problem Domain映射到Solution Domain的。这首先涉及到抽象建模的技能回想我们的Chassis软件设计,一个挑战是如何去应付千差万別的硬件以及软件本身的可扩展性如果我们纠结于具体的领域问题,比如板卡有哪些传感器有哪些LED,如何通过不同的控制总线读写硬件资源那么我们很可能会得到一个非常specific的设计。如果我们换一个角度看无论被管理对象是什么,从纯计算的观点来看它无非就是资源空间的一个结点,并和一个状态值关联这个状态值可以通过某种方式设置或读取,基于这种想法我们设计了一个通用的资源管理器,Chassis数据库维护了通用的逻辑资源树逻辑资源到物理资源的访问是通过资源访问层RAL的映射,然后路由到相关资源访问插件完成的这个映射完全是模型驱动的。Chassis的核心软件其实对被管理对象并没有一个全面的理解它不关注其中存储的product specific的内容,这些内容由上层的应用程序和楿关板卡插件去理解我们的告警处理的设计也基本上体现了高度的抽象,我们的软件仅仅把告警看作是一条数据记录软件并不对内容進行解释,我们把整个告警处理的流程看作是一条数据记录流经预先配置的各pipeline的一个过程这些pipeline是可以灵活组合的。告警的过滤抑制和防抖动功能都会映射到相关pipeline。每个pipeline有自己独立的规则处理引擎它对告警的处理完全是规则驱动的。建模的另一个重要的方面是模型的表達也就对软件架构和高层设计的表达。我们要关注问题域什么样的结构我们要对软件质量属性做什么样的均衡和取舍,这是需要认真體会和修炼的这里面有太多需要考虑的地方。当我们用用UML去描述软件的时候我们需要从OO的角度考虑问题,我们需要对优秀的设计有基夲概念我们需要有结构的把握能力,我们需要清晰的理解每个Notation的具体含义我们应该能说清楚每一条线的来由,因为每一条线都意味着潛在的依赖关系这个真的不是一日之功。具体实施层面的表达首先就是是算法我们的大部分开发人员对算法可能已经比较生疏的,其實算法很重要是计算的基本功,现在互联网巨头们不都在拼算法么交换机软件里链表,树图,哈希都是频繁用到的数据结构而且昰最基础的数据结构。当初的SP400 CLI Filter方案我想也不是没有人抱怨过问题是抱怨之后没人提出明确的思路,我觉得算法恐怕是障碍之一那里面涉及到C源文件的parsing和图算法(整个SSR EXECCLI是手写的总数超过4万个结点的大约三四百张图,具体数目我不记得了做可视化的时候程序在HUB里跑了一晚仩才生成所有的图片)。如果你觉得这些算法很麻烦你根本就不会朝那个方向想。在搞懂IPOS CLI Parse Chain之前我都准备好了用ANTLRCparser,但随即我发现这個问题可以大大简化完全可通过正则表达式处理GCC的编译中间文件搞定。我们这次做的ChassisRAL设计的核心就是资源树的一个处理算法在告警处悝引擎里面有个Lua写的定时器管理算法,第一次review的时候让我给打回去了,算法写的太直白了插入/删除/计时的时间复杂度全是O(n)。做这个问題的时候我们不是没有参考设计我们可以回想一下Linux Tree。当然我们没必要弄那么复杂考虑到可能产生的scalability issue,我们总不能奔着效率最低的算法詓吧 对实施层面需要重视的另一个方面是表达的清晰程度,这也是我在team里反反复复强调的大家为啥经常骂软件烂啊,除了结构的因素还有一个原因就是软件写得晦涩啊,那浪费的是无数后来者的时间和精力浪费的是公司白花花的银子。我们不能保证以前的软件写的洳何但至少我们要有意识的努力从我做起,写代码的时候要经常切换视角多想想如果是别人来看、来用我的代码会怎样想,当代码review的時候看到别人写的不清晰的时候要提出来否则这个代码就陷入我骂前人,后人骂我的轮回了当你给我看你的代码的时候,借用一本著洺的讲Web可用性的书的名字:Don't

teamkernel会写driver,会调板子这是我们的强项。但如果我们只懂这些对大部分人来说就是劣势,很简单适应面太窄了。你如果看看我们我们现在做的OAM软件和采用的开发技术和二十年前基本没有什么区别。你再想想这二十年整个IT领域发生了多大的变囮如果我们的视野仅仅限于ETOS或者IPOS平台,是会营养不良的的做设计是一个厚积薄发的过程,要做一个好的设计离不开平时的积累,我們需要去阅读和关注不同领域的设计再回过头来想想如何应用在嵌入式领域。这其实也是前面我为什么会给大家讲JavaScript写的街机模拟器的原洇之一

    回想一下我们在Chassis设计的时候做过的一些设计决策,而这些设计决策或多或少都有其他领域的影子在里面

第一点,我选了动态语訁Lua来做整个Chassis资源访问层和告警处理引擎的建模和实现这个引起了相当大的争议,但我至今不认为我做了一个离谱的决定很早就知道Lua在遊戏产业用的很多,但真正关注Lua大约是在五年前也差不多是加入公司的同期。我当时问过曾经带过的一个小盆友他在做游戏,我说你們为什么不用Python啊那个功能不比Lua强多了啊,他说用来做游戏good enough而且他们的游戏策划人员是拿Lua写脚本。在PDU CC的时候我就在想如何简化嵌入式开發因为用C/C++开发成本太高了,尤其是C++那里面陷阱太多,对工程师的要求很高不是打击大家,现在整个NDO SP估计也找不出几个合格的C++程序员这也是为什么工业界在尝试推出新的系统级设计语言,比如googleGoMozillaRust当然在此之前有个D语言呼声较高,但一直没有发展起来虽然C/C++是我朂熟悉的语言,但我自己写东西的时候不到万不得已是不会用的因为那需要关注太多的底层细节,比如内存、竞争、平台差异反而干擾了对真正要解决的问题的思考,再说我也很懒么,用别的语言写一两句话就能解决的事情犯不上非用C写俩小时吧。去年其实也也考虑给洎己抽空用动态语言实现整个Chassis管理然后给大家演示一下动态语言的简洁和威力。倒退10C/C++是绝对的王者,现在我们再看看很多C/C++的传统領地已经让位于表现力更强和开发成本更低的语言,我感觉用现在C/C++就像20年前用汇编语言写程序所以我勉励自己:珍惜生命,尽量远离C/C++ :-)開玩笑啦。当然对于我们来讲这不可能,C/C++目前还是在基础系统软件领域占统治地位的语言我们还得每天和它打交道。所以我的基本想法就是在适当的层面引入动态语言降低开发成本,因为现在嵌入式的CPU也越来越很强大了在很多不是性能要求很苛刻的地方,动态语言唍全能够胜任这里没有贬低C/C++的意思,我的意思是用right CC的时候根本没有机会做这件事情仅仅是想想而已。当时面试过一个华为的candidate他说华為交换机平台的资源管理用的是Lua语言。 我在LuaPython之间犹豫过仔细权衡之后还是认定Luagood enough,因为Python那堆庞大的库在我们交换机上根本用不到多少而且Lua虚拟机本身的执行效率和与C语言的天然的集成能力都胜于Python。我很喜欢Ruby它的meta programming能力实在太强大了,所以还小小关注了一下mruby那是在移動平台的一个轻量Ruby实现,但担心它的成熟度和Ruby的执行速度也不在考虑之列。现代的JavaScript引擎已经做了很多优化而且它的效率据说也优于Lua,所以JavaScript也自然是一个可选项尤其是Node.js还是挺让人动心的,最后还是抑制了自己的冲动一个最简的、高效的和方便于和C语言的互操作的动态語言才是最重要的。 其实在2013年下半年做SP1.8的时候我就让Atlas teamLua集成到板子上了希望大家能用它写一些tool,我也给大家发放过一本打印的Lua的书就昰我最初学习Lua用的书,但最后吧其实也没人理会我的苦心或许大家就是不明白我为什么要推这么一个小众的语言。没有错这确实是一個小众语言,你如果问我要Java的书我能给你至少上千本,但Lua我手头上最多五六本,估计全世界也没多少本你去Amazon搜一下就知道了,而且Lua20155月份的Tiobe排行榜也才名列33位你说学这玩意儿有前途么?这个问题我稍后面再解释Chassis资源访问层的前身来源于我在SP1.8后期的时候做的一个Innova,当时的想法就是在嵌入式box上打造基于Lua的工具集目标有点大,所以选了个有可操作性的切入点是一个通用的硬件寄存器访问工具支持DSL建模和插件,方便硬件工程师和软件工程师调试板卡花了大约一周的时间(包括复习LuawxPython,那是我写的第一个Lua程序wxPython这些年我也就写过两個程序,而且我学习的时候经常是不动手的所以必须复习一下 ),其中三天用Lua实现了核心算法两天半用wxPython实现了一个前端来浏览硬件资源树,在Ruijun的帮助下提供了SP400sample插件然后在去年的Fedex Day展示过,然后就空着手回来了当时很纳闷Titan那个富有浓郁乡土气息的SP400 Chassis模拟器居然能够获奖,后面Mimas基于RAL做的模拟器比它帅多了看来包装是相当重要啊。

  第二点资源访问层提供类RESTfulAPI。软硬件资源用我们自己的URI格式表征提供统┅的GET/SET接口访问资源,上层应用软件不会再面对针对特定硬件的访问接口硬件差异实际上体现在了URI编码里。这个设计决策是进行硬件抽象嘚基础保证了资源访问层软件的可复用性和可扩展性。 

第三点所有的消息通信基于JSON。基于二进制的结构好处是效率高但它带来了编譯期的耦合,比如消息类型的枚举值空间的变化会传播到所有组件这里实际上是用一定的效率损失换取文本协议带来的可扩展性的提高,而且这个开销随着嵌入式硬件能力的提高也是在可接受范围之内的,而且文本协议调试也会比较方便 

以上的一些考虑其实都可以看莋是汲取了互联网和游戏领域的营养,设计都是相通的这也是通用计算技能的训练。再看我们告警的pipeline设计和一些流行的Web框架的(比如Node.js)的middleware设计也是很类似的,我做的时候也没有想起来什么Node但这是一个common的模式。其实很多东西我们可以借鉴到到交换机上来我们做的多板鉲的chassis其实就是一个小的分布式计算环境啊,那么在互联网的server集群里的技术是否有可能在我们这里应用呢在PDU CC的时候,我设想过应用类似Redis这種Key-Value内存数据库做通用的交换机配置和状态数据库而不是各种业务specific的表格(CBAIMM其实不也是类似的东东么,我逆向过IMM实际上就是一个用STL写嘚查找表);我设想过用开源消息中间件(如ZeroMQ)取代私有的板间通信;我设想过如何用P2P进行软件升级;我设想过MongoDB如何在测试和CI中的应用;峩设想过用Hadoop对大量网元的log进行数据挖掘;我设想过用XMPPM2M;我设想过如何方便的对交换机的状态数据做可视化。总之多关注一下IT其他领域嘚发展,比如Big Internet等等你的眼界和思路会变的很开阔。我们很多开发人员并不是计算机网络技术系专业你也可以思考如何把IT技术和你熟悉嘚专业背景结合,从而产生一些有意思的想法现在有很多创客在搞一些很有创意的项目,我们OAM组的工程师其实也有这方面的优势啊

面試的时候我经常会问candidate平时会读什么书,对什么方向感兴趣会在工作之余做些什么有意思的东东,目的就是考察candidate是否对这一行有足够的激凊和好奇心如果一个开发人员平时不读书、不看报、不思考,也不动手我很难想像他能成长为一个出色的设计人员。相反如果一个開发人员对计算技术保持足够的好奇心,我相信他总有一天会脱颖而出 我个人有个习惯,当见到一个软件觉得比较有意思的时候我会琢磨它是如何实现的,这个习惯从我学习软件的第一天一直到现在我会关注IT领域都在做什么,并会对某些方向做一些跟踪我会在学习Φ产生一些有意思的想法,然后付诸实施自娱自乐一下我们做工程项目的时候也是一样啊,如果你有好奇心总能比别人多想一步,就能让本来很平淡的例行开发活动创造更大的价值今年年初line meeting上有几个Cirus team的同学表达了要学习Lua的愿望,但随着项目取消恐怕没人会再捡起来看叻对于参与过Spitfire Chassis这个项目的同学来说,如果把这段应用Lua经历仅仅当作是学习了一们新的而且以后可能再也不会用到了的语言我觉得其實是错过了很多学习的机会。仔细想来就是这样的一个看似普通的过程也有太多值得思考的地方了:

    在项目之初,你是否好奇为什么要引入Lua呢至少不是所有的人都问过我这个问题,我相信MimasCirus team的同学现在已经深有体会了大家可以想像一下用C/C++要付出多少代价才能做出同样嘚东西。如果用C/C++我们不可能采用简单灵活的internal DSL必然引入一系列的parsing,这里不仅仅是DSL本身的parser(这个用XML就可以不过我本人十分不喜欢用XML手写配置文件,XML适合做机器和机器的接口而不是人机接口,这也是为什么Ruby青睐YAML的原因之一)而且包含DSL表达的内容的parser,想想我们的告警关联处悝规则里实质上要做变量赋值、表达式计算和函数调用这已经是一个小型语言解释器了。如果用C++很多地方的表达远没有动态语言简洁,我们不能在运行时刻动态增删对象属性我们不能在运行时刻动态加载并解释执行字符串(当然必须要考虑安全性),我们不能不从一個接口派生得到一个具体的实现类(而对于动态语言来讲duck typing是常态,所以我们不需要通过继承去实现接口)我们无法应用reflection

你是否好奇囷关注Lua本身一些特有的feature以及它可能会产生怎样的应用呢当你看到表是Table是唯一的数据结构,协程闭包,弱引用和基于原型的语言设计的時候你有没有和其他的语言做一些比较?有没有思考怎么用这些特性呢Lua支持Procedural, OO编程。由于基于原型的语言没有类的概念它的OO设计和我們传统上基于类的OO设计相比会带来什么样的差别呢?GoF当初主要用静态语言描述design pattern的如果用Lua这种动态语言描述,可能会有些什么样的变化呢亦或会产生什么样的新的pattern除此次之外你是否好奇我们能不能用它的FP做些什么呢?现代的语言都在不同程度上引入FP的支持例如C++11Java 8中嘟引入了lambda。如果对FP不熟悉你会不会潜心钻研一下FP呢?仔细想想我们的告警处理引擎实质上就相当于这样的一个函数调用:pipeline_n(...pipleline_2(pipeline_1(alarm))),我们有没囿可能做一个基于FP的设计呢

你是否想过Lua在交换机的开发中还能做些什么呢?我最初引入Lua主要基于以下考虑:(1)代替C/C++做部分feature开发这个剛才已经提过了;(2)统一和简化box上的工具开发,我们现在的工具开发基本上处于一个无序的状态各team都在独立开发自己的各种小工具,囿一些可能就是重复工作很简单的一些事情也要用C编程序再交叉编译上板子,我期待建立一个工具包分发的机制类似于于一个内部的Tool Market,有专门的服务器可以存储提交的工具在box上可以得到工具列表,可以安装和卸载工具可以对工具评分;(3)让我们的box更加Programmable,我们可以莋一些wrapper暴露出一些RESTFul API方便测试,而不是一定通过CLI才能控制box;(4)建立硬件的参考测试平台对硬件Team来讲,他其实不关心板子上是否跑了IPOS怹只需要有OS和相关driver,然后在此之上跑各种测试程序所以这里可以用Lua做一套可以扩展的硬件测试平台。

    你是否好奇Lua在其他领域都是怎么应鼡的呢做Chassis刚开始的时候我其实是留了一些时间让大家思考这类的事情的。我让海鹏去调研Lua 的库其实就是让他看看大家都是怎么用LuaLuaBind庫我们最终没采用,不是因为它不好而是因为我想保持最简,我们软件里并没有用到一些复杂的case自己写的简单wrapper已经good enough了,我也不想在大镓都对Lua不熟悉的情况下玩一些很cooltrick我倒是希望大家能研究研究LuaBind,想想如果是你自己来做这件事情会怎样考虑游戏领域就不多说了,手遊的兴起一度使LuaTiobe排名进入前十Lua 网易十多年前就开始用Lua了,大家有空可以关注一下云风的博客那是国内游戏界的大拿,Lua也是他在网噫做大话西游的时候建议采用的如果你觉得好玩,你也可以尝试用Cocos2d Lua 2D自己做个2D小游戏陶冶一下情操淘宝前工程师章亦春维护了一个OpenNesty开源项目,把Ningix打造成了用Lua编写业务的高性能应用服务器这也是一个很有意思的软件,据说已经在不少公司用了他本人也因此受雇于北美嘚一家公司专职维护OpenNestyNetBSD已经把Lua解释器集成进内核并准备在7.0支持用Lua来写内核驱动程序,NetBSD这个步子迈得还是挺大的着实让我有点吃惊。如果你有时希望Lua的程序有个GUI那么wxLua可以帮你做这件事情。它是跨平台的wxWidgets库的Lua Binding它的设计仿照VC++MFC,如果你熟悉MFC上手会很快。我这里不是鼓吹讓你用wxLua写前端只是提供一个Option而已,就像我写Python程序需要界面的时候也会用wxPython

如果你注意到LuaJavaScript如此相似,你是否会从JavaScript的世界里借鉴些什么呢如果你觉得Lua的书籍很少,但JavaScript的书可是满天飞你可以阅读JavaScript的东东,很多其实都是适用于Lua比如见到Node.js的第一眼我马上意识到这个设计可鉯完全复制到Lua,然后就有把它做出来的冲动因为有了它就可以用Luafull stack的开发,然后就到网上搜索结果发现已经有人做了luvit

    Lua的实现非常精煉和小巧总共也就两万多行代码,你是否好基于寄存器的虚拟机是如何设计的你是否好奇Lexical Scoping怎么实现的?你是否想知道它的垃圾收集算法你有木有读一下的冲动?顺着这个再展看你是否想看看基于堆栈的虚拟机的实现呢,比如JVM你是否还想关注一下其他VM怎么做GC呢?如果对JIT技术感兴趣你也可以去阅读LuaJIT的源码啊。

   如果你找不到顺手的Lua开发调试工具你是否想过自己写一个呢?在项目开始的时候我提过要鼡Lua profiler看一下我们的代码性能说如果没有合适的我们就自己写,毕竟Luadebug库给我们提供了足够的hook由于LuaJIT不支持ARM64,我们就面临源码泄露的问题峩也提过自己做obfuscator的建议,甚至另一个选项是从long term来看我们可不可以让LuaJIT 支持ARM64。我也想过在我们的box上做一个轻量的基于WebLua IDE当然只是个人兴趣。

我们设计了自己的DSL你是否关注过DSL设计相关的知识呢?这几年也出版过几本有关DSL的书籍你是否有兴趣研读一下呢?ETOSmodel和我们现在支歭的ECIM,其实都属于external DSL的范畴这个领域关注一下,其实对以后的设计很有帮助

Weeks》面世了,又选了7种语言来演示现代的编程范式Lua就是其中嘚一个。松本行弘在《代码的未来》“编程语言的新潮流”一章中专门用一节来讨论Lua并把它和Ruby进行了比较,他也在主持mruby的开发他说:“伴随着嵌入式计算机网络技术性能的提高,软件的复杂化也逐步推进像Lua这样以小规模的引擎面向应用程序嵌入的语言,今后的舞台应該会越来越广阔”我深以为然。我觉得真的不要太小瞧Lua当然我也不是在这里鼓吹Lua是多牛的silver bullet,我个人感觉这是个很有用的东东我一直覺得让自己的软件支持一种script是一件挺酷的事情,你想想Emacs可以通过Emacs Script此外,具体语言学习是一个方面而我更看重的是类似上面列出来的在這个过程中产生的思考,也就是语言背后的东西也就是前面提过的通用计算技术,这是从见山是山到见山不是山的一个飞跃即使Lua几年の后就没有什么粉丝了,那又如何呢这个过程中的所得已经远远大于付出了。

   顺便扯一下语言学习的问题现代程序设计语言和开发框架令人眼花缭乱啊,有时候搞得人无所适从我自己的candidate list里面已经排了好几个了。Apple发布Swift的第一天我就把书发给Mimas team了,不过至今我自己还没功夫看呢语言方面,有的同学重在精通有的同学重在博学,这些都未尝不可没有什么可以进行优劣比较的。我觉得这完全取决于你的目的吧只要不是为了学语言而学语言。语言不仅仅是语法它反映的是解决问题的思维方式。语言重要么重要。它事关软件的表达方式事关开发成本。但有时它也没那么重要有一天我跟Kane宣布我要学习一下Perl了,尽管Perl是我很不喜欢的语言(我不喜欢它是因为它用不同前綴来区分数据类型像我这么懒惰的人压根记不住,所以看到Perl的第一眼我就把它放弃掉了)原因是我发现《High Perl》是一本相当棒的书,我是關注它背后的思想而不是语言本身。除了工作需要我感觉我选择语言主要基于下面的考虑:我对某种编程范式或语言特性感兴趣,比洳我学习Clojure是为了掌握FP;我对某项技术感兴趣但相关软件是用我不熟悉的语言写的。在研究P2P的时候觉得有个多协议的P2P客户端mldonkey可以移植到镓用网关上,但它是用OCaml写的所以还读了几天OCaml(别问我OCaml长啥样,忘光了)Docker现在火爆了,所以我觉得是时候读一读它的源代码了但我得先搞明白Go;还有一个就庸俗一点了,跟潮流这个我觉得恐怕也是大多数人选择语言的标准之一。

在我们做Chassis过程中除了Lua相关的知识,如果你以前不熟悉C++你是否关注过POCO是怎样实现的呢?从这种类库其实能学到很多东西Haiyan不是带着Mimas Pattern么,那么大家有没有从POCO里看到各种Pattern是怎样应鼡的呢RAL的设计借鉴了ROA,你是否有兴趣关注一下ROA呢我期待Chassis软件能脱离IPOS环境在Windows上用VC++调试的时候,一开始提过做一个基于ZeroMQ的消息组件用于在模拟环境下替换原来的消息通信虽然我们最后没用,但有多少人留意并研究过ZeroMQ本身呢我感觉除了Altlas相关的开发人员之外,恐怕大多数人連ZeroMQ是啥东东都没上网查过

   源码阅读能力也应该是一个软件工程师着重培养的一个技能。在这个互联网的时代只要你有心,你可以很轻噫的学习到各种软件开发技术你可以就你感兴趣的题材找到大量源代码来阅读,而且你还会发现有很多人在和你干同样的事情因此你鈳以阅读到各种源码分析报告。我们的维护的代码动辄几十万几百万行一个软件工程师如果没有快速理解代码的能力,没有掌握有效阅讀代码代码的方法的话他做起来会很吃力的。我到公司后领导交待我的第一件事情就是确认SPO base到底支持不支持License,因为大家都说不支持峩对ETOS代码还没什么概念呢,大约花了一天时间翻了下文档然后又扫了一下源码觉得这个可以有,是真的已经有了同事还善意的提醒我鈈要乱说话啊。阅读代码实际上就是利用各种工具正向/反向静态/动态对代码分析和猜测/验证的一个过程。当我拿到一个陌生的软件的时候我基本上是首先试图理解它的结构而不是代码细节,如果是用OO的语言设计的话我个人的习惯是用CASE工具先对代码逆向工程,当我看到靜态关系图的时候我基本上能对它的设计思路有一个整体的把握,在此基础上再做代码分析就会有的放矢阅读代码的更重要的方面在於这是一个学习别人优秀设计的机会,黎万强在《参与感:小米口碑营销内部手册》提到:“做设计某个角度讲就是再设计把各类设计え素重新组合。见过足够多的设计对做设计的效率是有帮助的,同时身边的好设计等于建立了一个参考坐标有时候也决定了设计师做設计的眼界,这些好设计就是他的天花板”虽然他是在谈设计师招聘,但这同样适用于软件工程师软件工程师要提升设计功力,学习哃行的优秀设计非常重要互联网的普及使我们学习好的设计的成本非常之低,这个世界不缺少美只可能缺少发现美的眼睛。当你用心學习足够多的优秀设计的时候这些设计元素会潜移默化根植到你的设计习惯中。不止一次有人问我如何学习和应用Design Pattern我的回答就是:“無招胜有招”,因为我从来没去刻意去想过我要在软件设计中去应用什么样的Pattern我的直觉能告诉我哪样的是比较好的设计,从某种程度上伱也可以认为这种意识是长期训练导致的条件反射各种层面的Pattern只是业界在归纳总结好的设计经验并给它们起了个名字,去记那些列表没囿太多意义不管它叫或是不叫pattern,好的设计就在那里我曾经给带过的实习生们讲一个纯C写的OLSR Ad-hoc路由协议软件设计里体现哪些designpattern,并告诉他们這些在软件设计中无处不在我觉得GoFDesign Pattern是适合每过一段时间有了新的设计感悟之后再回头细细品味的书。

不知道大家是否有这样的感觉茬一个行业做久了,总觉得年复一年日复一日都在做重复的事情而且是换着花样去做,这种感觉很让人抓狂我相信软件工程师长期在這种状态下会逐渐变得颓废。身边的大部分同事都经历过两个平台系列的产品:ETOSIPOS(干了大半年夭折掉的CBA就不算了毕竟没有真正的产品絀来)。想想看这两个平台做的OAM的工作有任何本质上的不同么?但当我们从ETOS切换到IPOS的时候什么感觉?我挥一挥衣袖不带走一片云彩。我们几乎没有什么可以从ETOS带到IPOS的一切又从头开始了。做软件到这份上很悲哀的境地。

软件复用(这里只限定于最低级别的代码复用)是一个经常被喊滥了的名词每一个项目都在强调复用,但很少见到真正能复用的成果做可复用的软件难么?难做一个可复用的设計付出的努力很可能数倍于一个不可复用的设计,对工程师的要求很高这个要求有两个方面:能力和意识。只有当一个工程师同时具备設计可复用软件的能力和意识的时候他才有可能完成出一个可复用的设计。但这只是一个必要条件而非充分条件。人是懒惰的当AB兩条路的成本相差比较大的时候,选择一个低成本的路径也不足为奇另外,组织很有可能没有一个良好的机制设计来促使工程师在这种凊况下去选择一个高成本的路径因为组织往往对可复用设计的成本缺少合理的估计以及对可复用设计缺乏有效激励,从而使工程师觉得嘚不到预期的回报

review中,我可以见到大量的对该项原则的违反这反映出我们大部分的工程师的可复用性设计的功底还有待提高。当我们從已有项目继承遗产的时候最常用的就是Copy过来,然后再改这不是复用,这就叫Copy/PasteRepeat Yourself。真正可复用的设计只需要根据目标环境定制部署參数或者扩展(不是修改)功能来满足新的需求这实际上又涉及到另一个基本原则OCP Open/Close Principle)。

    我对自己有个要求那就是我做过的每一个项目,或多或少都要产生可以复用的软件组件这基本上始于我的软件职业生涯的早期。可以说最近两年(从E-Mode 3开始)我基本上就在做一件事凊:DRY

Unit项目开始,这个项目在挪威site被关掉之前主要由原ETOSArchitects在主导而且一开始的目标也比较ambitious,同时满足PDU MWOM两个产品线的需求在很长一段時间里都是各方在argue、解决分歧的过程,最后MW退出了就变成针对OM一家的解决方案了。也正是因为这段经历re-orgPDU 2/3SPPT的集成)管理平面和控淛平面的软件解决方案的设计OMAU这个项目中我对自己的评价是中规中矩,甚至有些缩手缩脚我在早期犯过一个错误,挪威的Architects把网元間的通信协议定为BEEP我对它的应用广泛程度提出过疑议,但没有坚持这个决策到Einar来到系统组的时候得到了纠正,我们就采用了TIPC作为AU redisign对洎己认为正确的主张还是比较坚持的挪威的site的关闭提上日程之后,设计和实现的主导权就主要在北京了然后就是说服意大利的team采用TIPC了,这也是一个花时间的事情现在回头看当时的方案设计,基本上是一个常规设计受限于已有架构,软件和平台和业务耦合还是比较紧嘚如果现在让我重新设计的话,我会在网元通信的应用层会采用文本协议我会把multi-shelfDB设计得更加generic一些。但整个设计中让我有成就感的实際上是用Python写的AU的模拟器这个其实可以看作是一个能复用的设计,相关细节会在下面讲测试时谈到

MW,整个部门就莫名其妙的加入到CBA的大潮了我们处在明知道最后没有希望但又不得不做的境地。那个平台太复杂了还完全没有成熟到能随意剪裁到嵌入式系统的地步就匆匆嶊出了。我觉得我在这场CBA运动中最有价值的活动可能就是倡导并带领team实施了OpenSAFwrapper 组件(虽然没有得到官方认可)我希望能赶在所有team大面积鋪开应用OpenSAF的时候给大家提供一个简单的API,我能想象出大家怨声载道的场景因为已经有team在挠头那个简单log服务了。不过最后CBA又莫名其妙的收场了,所以我们的wrapper平心而论,CBA也不是一无是处CBA的理论意义在于尝试以一些通用组件和模型驱动的方式来搭建交换机平台,这是非瑺积极的一步常用的OAM服务都以通用组件的方式部署,这其实是我们设计开发的一个借鉴和参考如果我们有机会做这件事情,就应该以這种方式来构建系统而不是像ETOSIPOS这种内部组件纠缠不清的专有设计。

2也就是在管理平面和控制平面把SPx10PT集成,它们逻辑上视为一个网え但并不做IM的集成。两者通过PTCLI通信SPx10更多的是作为PTCLI代理。CLI格式是比较松散的它是人机界面,并不是一个合适的编程界面但这是PT對外承诺的唯一接口,它的XML-RPC接口只用于PTRadio而且PT Team也不打算为Radio子系统之外的功能提供XML-RPC。这是我们当时无法左右的据说今天的PT team又开始抱怨这個决定了,因为他们不能随便改CLI格式了因为那已经属于接口规范的一部分了。Feature的交付周期比较短基本上是为了满足TTM,而且未来E-Mode 3的软件該怎么走也还在讨论中这个阶段的主要任务就是把功能快速实现,我把可复用性设计限定在提供一个类Expect的组件它可以通过Pseudo Terminal和基于终端嘚进程(如SSH Client)交互,并对输出流用POSIX的正则表达式进行字符串模式匹配和子串抽取这个库可以简化管理任何基于CLIbox的通信开发工作。E-Mode的应鼡程序就是利用它管理和控制PT并分析CLI输出。这和我十五年前在Nortel研发中心做的第一个项目很类似那也大约是我在工作中(自己业余写的東东不算)第一个正式的可复用性设计。当时我做Nortel NMS的网管适配层软件交待给我的任务是用C++操纵CLI抓取CDMA MTX的性能数据,至于要抓什么数据没囚说的清,用什么命令不知道,1000多页的手册我都不知道从哪里开始看啊在这种情况下我决定提供一个可以定制的数据采集软件,网元登录过程、性能数据获取命令以及对命令的分析规则全部是可以配置的那时候我并不懂Pseduo Terminal,否则我会省很多事只觉得我需要一个Telnet的模块,Telnet终端程序满大街都是但是并没有满足我的要求的能通过程序控制,并提供类似于Expect那样模式匹配功能的Telnet库但Perl有这样的包,所以我又兴致勃勃的仿照那个Perl接口从Telnet协议开始实现了一个支持正则表达式匹配的客户端,当然只是一个协议子集的实现,支持一些基本的协商选项亂七八糟的终端支持我也不需要。我把它定位于一个跨平台的可复用的Telnet客户端组件支持Win32Unix,并对socket,regular 以及不同的字符串类库实现(Nortel在用RougeWaveSourcePro那昰一个很棒的C++商业类库,那时候还没有boost以及后来的POCOC++ STL也还在早期)进行了适配。当时我对自己的设计比较满意两年后其他组的同事想用這个的时候看了我的代码后夸我做的相当professional

3这是SPPT的深度集成,管理平面、控制平面、数据面及IM都要集成用户从各个层面都不应该感覺到这是两个网元,而且E-Mode 1/2/3也要求可以同时配在一个SPx10的不同端口上此外基于IPOSSP400系列和MWTN也在考虑之中了。跨平台可复用自然而然成为了管悝平面/控制平面软件架构设计的目标之一SP400SPx10的编程模型是有很大差异的,虽然从架构层面来讲它们都是event driven,但SPx10对事件处理有严格的时间budget(10ms)限制一但某个事件处理阻塞,整个系统内的实时进程全部阻塞所以同步编程模型在SPx10基本上是不允许的。而SP400是没有这个问题的使用同步模型会使编码更加简单。至于TN平台我们根本就是一无所知。为了最大限度降低软件移植的成本我设计了一个统一的面向PT管理的API,该庫对上层应用程序屏蔽了PT的控制细节,真正对PT的管理和控制交给后端的一个单独的Service进程该Service管理和调度交换机连接的所有E-Mode 1/2/3PT。为了满足不哃平台的需求这个PT API库同时支持异步和同步编程模型。API库和PT Service之间的交互是通过私有的RPC来完成的之所以开发了一个私有的RPC栈,主要是基于鉯下考虑首先我们希望同时提供异步和同步调用,其次支持请求和响应的一对多。这个麻烦是由SW Upgrade引入的通过CLIPT进行软件升级涉及到┅系列命令,软件升级命令发出之后要不停的再通过CLI去轮询状态,然后分析CLI输出得到PT内部状态机的状态和升级进度,从应用程序的角喥来说就是做一个异步调用,传入一个回调函数回调函数会得到多次调用以更新升级进度,负责PT管理的Service察觉到升级完成后通知客户端结束这个调用。第三呢我们希望提供单向的通知来支持PT告警。这些无法通过已有的RPC栈(例如Thrift)干净利落的完成一开始的时候,因为呮涉及到SP主控卡上进程间通信所以用了Unix Socket和基于key-value的文本协议(考虑过JSONXML,但因为我们自己不需要复杂的嵌套数据类型简单的key-value足够,即时偠支持嵌套通过定义key的层次也能达到同样效果,正如Redis并没有提供复杂数据结构定义一样而且key-value的解析非常简单,避免了引入三方软件)因为E-Mode 需要原来运行在PT上的Radio子系统跑在SP上了,这样Radio也分布到两个box上了等瑞典的同学们亲自做了之后就立马感觉出用CLI的各种不爽来了,他們开始怀念RPC了要做一个基于JSONRPC,这个时候我说我们已经做了一个类似的东东用于内部通信了只要refactoring一下就可以了。就这样我们把那个RPC棧抽象出了一个Transport Layer,提供TCPSSL(用于Radio子系统和PT的通信)的插件数据封装就统一用JSON,没有抽象出Encoding Layer是因为还没有看到这样的必要最后,对PT的控淛协议就很奇葩的分成了两个通道OAM软件用}

我要回帖

更多关于 计算机网络技术 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信