- 浏览: 497289 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
hypercube:
markin'
配置D语言编程环境 -
qiezi:
qiezi 写道yangyang_08 写道1 ...
我的编程语言学习经历 -
qiezi:
yangyang_08 写道1、现在如果做并发服务器,楼主选用 ...
我的编程语言学习经历 -
yangyang_08:
1、现在如果做并发服务器,楼主选用什么样的语言架构?2、lua ...
我的编程语言学习经历 -
dearplain:
我也是语言爱好者,不过我一直坚持使用c。
我的编程语言学习经历
考虑到现有的项目使用erlang重写的复杂性和erlang对于某些数据库支持的弱点,想结合erlang的分布式、代码热加载、处理高并发方面的优势,和C++在性能上以及大量现有项目上的优势,实现集群部署。
考察了erlang和C进行交互的几种方式,ports受限于物理服务器分布,port_driver没测试成功,应该也是受限于本机,最后选定C nodes方式。
测试了c server和c client两种方式,感觉如果是server方式,还得用C写一套处理高并发的网络模块,也不方便升级,erlang的优势完全没发挥上,所以选定client方式。
大致的想法是这样的:
* erlang监听一个本地端口和一个对外的端口,本地的用于和c node通讯,对外的通过协议和客户交互。
* c node连接到本地端口后,就在erlang里面注册一个名字,这时候对外的端口上收到的数据就根据这个名字发给c node。
* c node上接收到数据以后就放队列,给线程池去消化,线程池处理完以后就通过端口发回给erlang节点,当然是使用erl_send (问题1)。
* erlang上面当然是由process“阻塞”处理,它收到结果以后,就发回给客户端,这个阻塞当然是假的,也正是利用erlang编程的便利。
* c node升级,只需要另开一个程序,注册另一个名字,比如名字加上版本号,连到erlang节点,再使用热加载把erlang代码更新,就可以在不停机的情况下更新服务器。更新完了再停掉旧版本的c node。
* 增加协议格式等操作都交给erlang了,C node保持不变。
不知道erlang应用于这种项目,上面这种方式是不是最优的?请有经验的朋友指点。
问题1:
erl_send是不是线程安全的?如果不是,我可能要做个发送线程去处理发送队列了。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
赞一个
原来如此。看到这些协议了:
4.2.1.1 LINK
{1, FromPid, ToPid}
4.2.1.3 EXIT
{3, FromPid, ToPid, Reason}
4.2.1.4 UNLINK
{4, FromPid, ToPid}
4.4.1 MONITOR_P
{19, FromPid, ToProc, Ref}
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.2 DEMONITOR_P
{20, FromPid, ToProc, Ref}
We include the FromPid just in case we want to trace this.
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.3 MONITOR_P_EXIT
{21, FromProc, ToPid, Ref, Reason}
FromProc = monitored process pid or name (atom)
ToPid = monitoring process
Reason = exit reason for the monitored process
看样子都是基于Process的,难道monitor_node实际上是用link或monitor_p协议做出来的?不过我看erts/emulator/beam/dist.c里面有个monitor_node_3,但没有以public方式开放出来。
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
我们公司是给自己做软件,作为WEB应用,稳定性比进度重要。通常逻辑也比较简单,只是要从系统架构上考虑任何一个点挂掉以后的备用策略。
----------------------------------------------------------------------------
这个帖子提到的erlang应用,我简单测试了一下还是可行的,简单总结一下用到的知识。
1、分布式结点发送消息注册服务:
{manager, 'a@xxx.xxx.xxx.xxx'} ! {reg_service, auth, self()}
2、监测节点退出:
monitor_node('a@xxx.xxx.xxx.xxx', true)
然后接收:
{nodedown, Node}
3、监测进程退出:
process_flag(trap_exit, true),
link(Pid)
4、远程节点心跳检测:
erl -heart
设置心跳间隔:
erl -heart -env HEART_BEAT_TIMEOUT 30 设置30秒心跳间隔,范围是10-65535秒之间。
有这些应该够用了。如果是C程序,如何发出monitor_node和process_flag/link呢?也可以从erlang节点上检测C节点,不过还是想知道反过来怎么检测。
出现长函数,或者模块划分不清楚,很多时候是由于开发人员没有清晰的分层意识,没有分清楚公用库和胶合代码。有时候有些库是从特定项目中重构出来的。在重构成库的过程中,没有考虑清楚这个库的主体功能,从而把一些胶合代码也被放到了库里面。导致这个库本身就依赖于太多的其他库。当需要使用这个库的时候,令人发狂的事情就开始了。
嗯,对于后台开发,很多复杂的情况,不用单元测试,可能还没那么容易模拟出来。单元测试一般来说,能够比较方便地模拟出自己想要的前提条件。
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。初期大家都不放心,不过负责的几个项目都是最稳定的,也就没什么疑虑了。这样我每周可以省很多时间,几乎所有的时间都是在写代码或看书。对我来说时间还是充裕的,只不过喜欢的东西太杂太多,每样都搞点皮毛,所以显得也很忙。通常服务器系统写完测试上线还需要监控一段时间,这段时间基本上是不分配任务的,定时上去监控看一下日志就好,一般这些时间有些同事在聊天、下棋什么的(好像公司不反对),我拿这些时间看书或写代码。多点练习也是好的,我刚来时公司有很多各方面的专家,很短一段时间以后,我就发现他们的很多理论是错误的,很多都是在做项目的过程中看过一些文档后就深信不疑,而我喜欢写代码验证,所以一段时间以后我的意见就能成为更有参考价值的。
又跑题了。难怪说:3页之内必跑题,如果没跑肯定是前2页已经跑了。。
跑题也没什么,话题都是扩展的,如果能把一个帖子的各个回帖打标签就好了,连在一起看时也可以知道是怎么跑到这个话题上的,分开看也价值。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
python应用这么广,公司大部分人都会,会C++的学python几天就可以上手,而且公司目前大力推广C++配合脚本语言开发业务逻辑,我带个头而已。erlang我还没应用到项目中呢,用的人毕竟是少,很多时候有些项目都是临时性的,解决一时的问题,过渡性方案,要求快速开发,用完就没什么用了,所以我经常会在各个项目里临时救一下火,或者是要快速做一下原型,你不得找个开发效率和运行效率都过得去的东西?另外模块化的开发很容易维护,都是分布式系统,协议兼容就可以了。倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我在公司基本上所有时间都在写代码,这是唯一爱好,一个项目完了如果有其它可选方案我肯定会试试,或者是其它语言来实现,你经常会看到我说用什么语言做项目,那是因为我完成了现有项目,多出来的时间我做些尝试而已,其他同事完成项目后都在聊天或看网站,我不过是做点不同的事而已。几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。你说做实验也可以,至少我没搞砸过一个项目,否则我早被开掉了。关于公司,在不到2年时间里,日浏览量目前已经接近搜狐,你要说没什么希望我也不需要反驳。。。每种公司都有自己的文化氛围,越是成功的公司越会鼓励员工尝试新技术,而不是以各种理由去阻碍。拍拍屁股走人更不是我的风格,我在过去工作过的地方时间都很长,不要拿自己的习惯去猜度别人。
又要成吵架帖了。最后说几句:
1、怀疑别人的人品的话不要说,除非你有证据证明我人品有问题。
2、明确的对别人说你讨厌他这种类型,很明显是一种挑衅行为,版规所不容。
qiezi 是怎么说服公司使用 erlang 的?我对这一点比较好奇
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
看具体情况吧,网游这种计算集中的,数据都从外部主动输入,当然是线程数少比较好,目前很多网游都是单线程跑逻辑。一些中间层服务封装数据库、远程服务调用和事务的,通常IO延时会比较明显,这时候多个线程效果比较好。这2种情况下erlang都是适用的。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
qiezi你在实现哪些功能的时候用了python?说说看,我想借鉴你的经验。
运行效率要求不是特别高的地方都可以用,比如日志服务器、文件服务器、大量的压力测试程序、文本处理等。
考察了erlang和C进行交互的几种方式,ports受限于物理服务器分布,port_driver没测试成功,应该也是受限于本机,最后选定C nodes方式。
测试了c server和c client两种方式,感觉如果是server方式,还得用C写一套处理高并发的网络模块,也不方便升级,erlang的优势完全没发挥上,所以选定client方式。
大致的想法是这样的:
* erlang监听一个本地端口和一个对外的端口,本地的用于和c node通讯,对外的通过协议和客户交互。
* c node连接到本地端口后,就在erlang里面注册一个名字,这时候对外的端口上收到的数据就根据这个名字发给c node。
* c node上接收到数据以后就放队列,给线程池去消化,线程池处理完以后就通过端口发回给erlang节点,当然是使用erl_send (问题1)。
* erlang上面当然是由process“阻塞”处理,它收到结果以后,就发回给客户端,这个阻塞当然是假的,也正是利用erlang编程的便利。
* c node升级,只需要另开一个程序,注册另一个名字,比如名字加上版本号,连到erlang节点,再使用热加载把erlang代码更新,就可以在不停机的情况下更新服务器。更新完了再停掉旧版本的c node。
* 增加协议格式等操作都交给erlang了,C node保持不变。
不知道erlang应用于这种项目,上面这种方式是不是最优的?请有经验的朋友指点。
问题1:
erl_send是不是线程安全的?如果不是,我可能要做个发送线程去处理发送队列了。
评论
28 楼
everlasting_188
2008-04-12
iunknown 写道
qiezi 写道
倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
qiezi 写道
几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
赞一个
27 楼
mryufeng
2007-07-31
erl的trace更是强大 erts\emulator\beam\erl_trace.c emulator的实现 还有更cool的 et_viewer 对整个message 的流向更是 尽收眼底, 对分布程序的调试真是太方便了
26 楼
mryufeng
2007-07-31
monitor是 erts\emulator\beam\erl_monitors.c 里面实现的 看下 .h的说明
/**********************************************************************
* Header for monitors and links data structures.
* Monitors are kept in an AVL tree and the data structures for
* the four different types of monitors are like this:
**********************************************************************
* Local monitor by pid/port:
* (Ref is always same in all involved data structures)
**********************************************************************
* Process/Port X Process Y
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid/Port(X) |
* +-------------+ +-------------+
* Name: | [] | | [] |
* +-------------+ +-------------+
**********************************************************************
* Local monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Process X Process Y (name foo)
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+
**********************************************************************
* Remote monitor by pid: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | [] | | [] | | [] | | [] |
* +-------------+ +-------------+ +-------------+ +-------------+
**********************************************************************
* Remote monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A (name foo)
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Atom(node B)| | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) | | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+ +-------------+ +-------------+
* The reason for the node atom in X->pid is that we don't know the actual
* pid of the monitored process on the other node when setting the monitor
* (which is done asyncronously).
**********************************************************************/
/**********************************************************************
* Header for monitors and links data structures.
* Monitors are kept in an AVL tree and the data structures for
* the four different types of monitors are like this:
**********************************************************************
* Local monitor by pid/port:
* (Ref is always same in all involved data structures)
**********************************************************************
* Process/Port X Process Y
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid/Port(X) |
* +-------------+ +-------------+
* Name: | [] | | [] |
* +-------------+ +-------------+
**********************************************************************
* Local monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Process X Process Y (name foo)
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+
**********************************************************************
* Remote monitor by pid: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | [] | | [] | | [] | | [] |
* +-------------+ +-------------+ +-------------+ +-------------+
**********************************************************************
* Remote monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A (name foo)
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Atom(node B)| | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) | | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+ +-------------+ +-------------+
* The reason for the node atom in X->pid is that we don't know the actual
* pid of the monitored process on the other node when setting the monitor
* (which is done asyncronously).
**********************************************************************/
25 楼
qiezi
2007-07-31
mryufeng 写道
节点间的通讯协议见otp_src_R11B-5\erts\emulator\internal_doc\erl_ext_dist.txt
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
原来如此。看到这些协议了:
引用
4.2.1.1 LINK
{1, FromPid, ToPid}
4.2.1.3 EXIT
{3, FromPid, ToPid, Reason}
4.2.1.4 UNLINK
{4, FromPid, ToPid}
引用
4.4.1 MONITOR_P
{19, FromPid, ToProc, Ref}
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.2 DEMONITOR_P
{20, FromPid, ToProc, Ref}
We include the FromPid just in case we want to trace this.
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.3 MONITOR_P_EXIT
{21, FromProc, ToPid, Ref, Reason}
FromProc = monitored process pid or name (atom)
ToPid = monitoring process
Reason = exit reason for the monitored process
看样子都是基于Process的,难道monitor_node实际上是用link或monitor_p协议做出来的?不过我看erts/emulator/beam/dist.c里面有个monitor_node_3,但没有以public方式开放出来。
24 楼
mryufeng
2007-07-31
节点间的通讯协议见otp_src_R11B-5\erts\emulator\internal_doc\erl_ext_dist.txt
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
23 楼
qiezi
2007-07-31
iunknown 写道
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
我们公司是给自己做软件,作为WEB应用,稳定性比进度重要。通常逻辑也比较简单,只是要从系统架构上考虑任何一个点挂掉以后的备用策略。
----------------------------------------------------------------------------
这个帖子提到的erlang应用,我简单测试了一下还是可行的,简单总结一下用到的知识。
1、分布式结点发送消息注册服务:
{manager, 'a@xxx.xxx.xxx.xxx'} ! {reg_service, auth, self()}
2、监测节点退出:
monitor_node('a@xxx.xxx.xxx.xxx', true)
然后接收:
{nodedown, Node}
3、监测进程退出:
process_flag(trap_exit, true),
link(Pid)
4、远程节点心跳检测:
erl -heart
设置心跳间隔:
erl -heart -env HEART_BEAT_TIMEOUT 30 设置30秒心跳间隔,范围是10-65535秒之间。
有这些应该够用了。如果是C程序,如何发出monitor_node和process_flag/link呢?也可以从erlang节点上检测C节点,不过还是想知道反过来怎么检测。
22 楼
iunknown
2007-07-28
引用
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2 或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
出现长函数,或者模块划分不清楚,很多时候是由于开发人员没有清晰的分层意识,没有分清楚公用库和胶合代码。有时候有些库是从特定项目中重构出来的。在重构成库的过程中,没有考虑清楚这个库的主体功能,从而把一些胶合代码也被放到了库里面。导致这个库本身就依赖于太多的其他库。当需要使用这个库的时候,令人发狂的事情就开始了。
引用
我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。
嗯,对于后台开发,很多复杂的情况,不用单元测试,可能还没那么容易模拟出来。单元测试一般来说,能够比较方便地模拟出自己想要的前提条件。
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
21 楼
qiezi
2007-07-28
iunknown 写道
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
iunknown 写道
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。初期大家都不放心,不过负责的几个项目都是最稳定的,也就没什么疑虑了。这样我每周可以省很多时间,几乎所有的时间都是在写代码或看书。对我来说时间还是充裕的,只不过喜欢的东西太杂太多,每样都搞点皮毛,所以显得也很忙。通常服务器系统写完测试上线还需要监控一段时间,这段时间基本上是不分配任务的,定时上去监控看一下日志就好,一般这些时间有些同事在聊天、下棋什么的(好像公司不反对),我拿这些时间看书或写代码。多点练习也是好的,我刚来时公司有很多各方面的专家,很短一段时间以后,我就发现他们的很多理论是错误的,很多都是在做项目的过程中看过一些文档后就深信不疑,而我喜欢写代码验证,所以一段时间以后我的意见就能成为更有参考价值的。
又跑题了。难怪说:3页之内必跑题,如果没跑肯定是前2页已经跑了。。
跑题也没什么,话题都是扩展的,如果能把一个帖子的各个回帖打标签就好了,连在一起看时也可以知道是怎么跑到这个话题上的,分开看也价值。
20 楼
iunknown
2007-07-28
qiezi 写道
倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
qiezi 写道
几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
19 楼
qiezi
2007-07-27
dustinth 写道
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
python应用这么广,公司大部分人都会,会C++的学python几天就可以上手,而且公司目前大力推广C++配合脚本语言开发业务逻辑,我带个头而已。erlang我还没应用到项目中呢,用的人毕竟是少,很多时候有些项目都是临时性的,解决一时的问题,过渡性方案,要求快速开发,用完就没什么用了,所以我经常会在各个项目里临时救一下火,或者是要快速做一下原型,你不得找个开发效率和运行效率都过得去的东西?另外模块化的开发很容易维护,都是分布式系统,协议兼容就可以了。倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我在公司基本上所有时间都在写代码,这是唯一爱好,一个项目完了如果有其它可选方案我肯定会试试,或者是其它语言来实现,你经常会看到我说用什么语言做项目,那是因为我完成了现有项目,多出来的时间我做些尝试而已,其他同事完成项目后都在聊天或看网站,我不过是做点不同的事而已。几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。你说做实验也可以,至少我没搞砸过一个项目,否则我早被开掉了。关于公司,在不到2年时间里,日浏览量目前已经接近搜狐,你要说没什么希望我也不需要反驳。。。每种公司都有自己的文化氛围,越是成功的公司越会鼓励员工尝试新技术,而不是以各种理由去阻碍。拍拍屁股走人更不是我的风格,我在过去工作过的地方时间都很长,不要拿自己的习惯去猜度别人。
又要成吵架帖了。最后说几句:
1、怀疑别人的人品的话不要说,除非你有证据证明我人品有问题。
2、明确的对别人说你讨厌他这种类型,很明显是一种挑衅行为,版规所不容。
18 楼
dustinth
2007-07-27
qiezi 写道
iunknown 写道
qiezi 写道
找了源代码看了,应该不是线程安全的,一个消息发送就有多个写操作,并发的写FD肯定有问题的。
HIDDEN NODE没有提供更多东西,只是隐藏而已,其它没区别。
这个架构准备在项目中试用一下了,以后服务调用、服务器间通讯都是走erlang节点了。
HIDDEN NODE没有提供更多东西,只是隐藏而已,其它没区别。
这个架构准备在项目中试用一下了,以后服务调用、服务器间通讯都是走erlang节点了。
qiezi 是怎么说服公司使用 erlang 的?我对这一点比较好奇
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
17 楼
mryufeng
2007-07-25
There are two different interfaces, the old 'erl_interface' and 'ei'.
The old interface is to depend on the new one, not the other way arount.
Erl_interface should bze "thread safe", i.e. you should be able to
handle connections, convert data etc from different threads.
Ei should be "reentrant" or "async safe", i.e. no locks should be set
so that if an ei function is called inside an signal handler there
could be a deadlock.
VxWorks call the operating processes "tasks". These are to be handled the
same way as Unix threads, i.e. there can only be one C node for all tasks
using the old interface.
The old interface is to depend on the new one, not the other way arount.
Erl_interface should bze "thread safe", i.e. you should be able to
handle connections, convert data etc from different threads.
Ei should be "reentrant" or "async safe", i.e. no locks should be set
so that if an ei function is called inside an signal handler there
could be a deadlock.
VxWorks call the operating processes "tasks". These are to be handled the
same way as Unix threads, i.e. there can only be one C node for all tasks
using the old interface.
16 楼
mryufeng
2007-07-21
cnode的实现非常薄 没有任何防护措施 这不是erl_interface的错。 ei的价值在于给你一把匕首 你能够很方便地切肉吃 当然有可能伤到手。
15 楼
Trustno1
2007-07-19
以前potain提醒过,cnode非常不稳定.运行几天就会有没有原因的内核crash.
14 楼
qiezi
2007-07-18
firebody 写道
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
看具体情况吧,网游这种计算集中的,数据都从外部主动输入,当然是线程数少比较好,目前很多网游都是单线程跑逻辑。一些中间层服务封装数据库、远程服务调用和事务的,通常IO延时会比较明显,这时候多个线程效果比较好。这2种情况下erlang都是适用的。
13 楼
firebody
2007-07-18
qiezi 写道
firebody 写道
有个疑问:
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
12 楼
mryufeng
2007-07-17
个人感觉是cnode是做些比较难用erlang实现的东西如和操作系统或者硬件交互之类的事情,调用的频率不是很高。 但是实现和调试起来又比较麻烦的场合。
11 楼
qiezi
2007-07-17
firebody 写道
有个疑问:
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
10 楼
firebody
2007-07-17
有个疑问:
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
9 楼
qiezi
2007-07-17
javavsnet 写道
qiezi 写道
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
qiezi你在实现哪些功能的时候用了python?说说看,我想借鉴你的经验。
运行效率要求不是特别高的地方都可以用,比如日志服务器、文件服务器、大量的压力测试程序、文本处理等。
相关推荐
在Erlang开发中,rebar是一个非常重要的构建工具,它可以帮助我们管理和编译Erlang应用程序,同时支持发布功能。本文以nitrogen_2.0.4框架为例,详细阐述使用rebar进行Erlang项目开发和发布的全过程。 ### 一、环境...
标题中的“在erlang项目中使用protobuf例子”指的是在Erlang编程环境中使用Protocol Buffers(protobuf)这一数据序列化工具。protobuf是由Google开发的一种高效、跨语言的数据表示和序列化格式,它允许开发者定义...
2. **分布式特性**:Erlang的分布式节点通信,分布式数据管理,以及如何在多台机器上部署和运行Erlang应用。 3. **故障恢复与容错**:Erlang的错误处理模式,如监控树(supervision trees)和故障检测,以及如何...
**Erlang 在国外的成功项目** 1. Ejabberd - 开源XMPP服务器 2. RabbitMQ - 开源消息代理和队列服务器 3. CouchDB - 开源JSON文档型数据库 4. Mochiweb - 用于构建高效的Web服务器和HTTP客户端的Erlang库 5. Disco -...
视频可能详细展示了如何在实际项目中实施热代码替换。通常,开发者会在新版本的代码中实现`code_change/3`函数,这是一个关键组件,用于处理从旧版本到新版本的数据转换。该函数接收旧状态、旧版本号和新版本号作为...
在Erlang mode中,还可以进行一些其他的配置,例如设置Erlang shell的节点名、添加Erlang函数到imenu菜单等。 readers可以根据需要进行相应的配置。 搭建Erlang开发环境需要安装Erlang OTP、Emacs W32、Distel等...
标题中的“使用rebar工具开发erlang工程项目和发布erlang工程项目借鉴”指的是使用名为rebar的Erlang构建工具来管理和构建Erlang项目的过程,以及如何使用该工具来发布Erlang应用。描述中提到的是通过nigrogen2框架...
6. 热代码升级:学习如何在不中断服务的情况下更新运行中的Erlang应用程序。 7. 源码分析:书中可能包含一些实际项目或示例代码,帮助读者深入理解Erlang和OTP的实践应用。 书中的"Manning.Erlang.and.OTP.in....
在建立一个 Erlang 工程项目时,需要首先安装 Erlang 和 Git 代码管理系统。在 Ubuntu 10.04 下,可以使用以下命令安装 Erlang 和 Git: ``` $ sudo apt-get install erlang $ sudo apt-get install git-core ``` ...
总而言之,Erlang9.rar是一个包含Erlang/OTP 20.0 Windows 64位安装程序的压缩包,主要用于安装Erlang环境,以支持像RabbitMQ这样的Erlang应用。Erlang以其独特的并发模型和强大的错误恢复能力,广泛应用于需要高...
- **Rebar3**:Erlang的构建和依赖管理工具,帮助你组织项目结构、编译代码和管理依赖。 - **OTP(Open Telephony Platform)**:Erlang的核心库,包含大量预先设计的模块,用于处理常见的系统任务,如错误处理、...
Erlang以其强大的并行处理能力、容错性和易于构建大规模分布式系统的特点,在电信、金融和互联网等领域广泛应用。Erlang22是Erlang的第22个主要版本,它包含了对语言特性的改进、性能优化以及一些新的库和工具。 在...
- 在Erlang应用程序中,加载NIF并进行测试。 7. **性能与调试**: - 谈论如何评估NIF的性能,并可能涉及一些基准测试。 - 提供了一些调试NIF的技巧,比如使用`erl_nif_trace`和日志记录。 通过学习Rustler编写...
【Erlang编程语言及其应用】 Erlang是一种并发式、函数式的编程语言,由瑞典电信设备制造商Ericsson开发,...通过实际操练这些课后习题,学习者不仅可以深入理解Erlang语言,还能培养出在实际项目中解决问题的能力。
安装完成后,可以通过RabbitMQ的管理界面或Erlang应用程序来管理和操作消息队列。 总的来说,Erlang在Windows 64位系统上的安装是搭建RabbitMQ等基于Erlang技术栈项目的第一步。理解Erlang语言特性和其与RabbitMQ的...
最后,第三部分通过构建实际项目,演示如何在实际环境中应用Erlang和OTP,涵盖了从系统设计到部署的全过程。 《Erlang程序设计》则更侧重于Erlang语言本身,适合初学者入门。书中会详细解释Erlang的语法和编程范式...
总的来说,“erlang_mysql编译好了”意味着你已经具备了在Erlang应用程序中与MySQL数据库交互的基础。接下来,你可以利用这个库来设计和实现数据密集型的应用,充分利用Erlang的并发特性和MySQL的高性能数据库功能。...
在Erlang开发中,最佳实践包括使用模式匹配、递归、消息传递、进程间通信等。同时要特别注意避免竞态条件和死锁,以及利用Erlang的分布式特性进行设计。 #### 4. 工具介绍 Erlang社区提供了多种工具帮助开发和调试...