霸爷,又来请教您啦。老头子在书里有这样一段话,every time we make a registered process, we are creating a potential sequential bottleneck. So, try to avoid the use of registered processes. If you do create a registered process and use it as a server, make sure that it responds to all requests as quickly as possible. 为什么说注册进程是顺序瓶颈呢?那只是注册的时候顺序还是使用过程中也存在潜在的顺序瓶颈?
谢谢您啦
您好,我接触Erlang 有段时间了,也写了一些代码。但对Erlang本身实现一无所知,想进一步学习,想请您给个简单的阅读源码的指导。
1、该从哪部分入手?
2、Erlang源码的基本结构?
本人对Erlang非常喜欢,时间很充裕。想对Erlang做长期研究学习。
谢谢。
[Reply]
Yu Feng Reply:
June 16th, 2013 at 3:15 pm
多阅读优秀的代码,比如说rebar。 然后动手做些项目,比如用mochiweb做点啥。不要上来就想长期研究学习,没有目标容易迷失。
[Reply]
以QQ为例,1亿用户同时在线(建立长连接),假如需要1千个服务器来保持这些连接,是不是每个服务器都得有公网IP?
[Reply]
请霸爷看个rabbitmq的问题
https://groups.google.com/forum/?fromgroups#!topic/rabbitmq-discuss/9hxpE1v1lSg
[Reply]
楼主你好,经常上你的博客,很有收获,谢谢你。
另外想请问一下,你是否知道“多隆”的博客或者微博呢?希望能学习一下,感谢~
[Reply]
Yu Feng Reply:
August 2nd, 2013 at 11:25 am
他貌似木有
[Reply]
霸爷,请问您的博客是自己开发的吗?还是用的现成的模板?
[Reply]
Yu Feng Reply:
August 18th, 2013 at 1:08 pm
现成的模板。
[Reply]
非常感谢。。。。
[Reply]
霸爷,我们联合了不少erlang爱好者想做一个比较正规的类似ruby-china.org的社区,你可以来做负责人吗?
带领我们前进:D
[Reply]
Yu Feng Reply:
August 18th, 2013 at 1:07 pm
不错,我可以帮忙上去灌水。
[Reply]
霸爷,最近在CentOS 6.4下使用systemtap遇到了一个问题。在自定义的函数中,想通过THIS->arg获得参数值,但总是报错,你遇到了没?有啥解决方法?拜谢
[Reply]
Yu Feng Reply:
August 18th, 2013 at 1:06 pm
你参考下systtemtap自己带的stap脚本里面怎么写,可以简单的搜索下“THIS->arg”
[Reply]
WangYing Reply:
August 19th, 2013 at 11:06 am
多谢霸爷回复。我找到原因了:
因为CentOS自带的stap版本是1.8,新的版本中获取参数的方式为STAP_ARG_参数名,
设置返回值的方式是STAP_RETVALUE,stap 1.7或跟老的版本是THIS->参数名和THIS->__retvalue
[Reply]
Yu Feng Reply:
August 19th, 2013 at 11:46 am
帅气!
请教一个问题,如下:
如何使用mnesia:select/4分页查询
%%对事务封装了一下,大致如下,参数个数从2到5个
operater(Op,Table,V1,V2,V3) ->
F = fun() ->
Op(Table,V1,V2,V3)
end,
mnesia:transaction(F).
%%这个是使用select/2查询出的结果:从1到10
(ejabberd@localhost)5> test:operater(fun mnesia:select/2,md,[{{md,’$1′,’_’},[{‘ {atomic,{R1,C1}}=test:operater(fun mnesia:select/4,md,[{{md,’$1′,’_’},[{‘<','$1',10}],['$1']}],5,read).
{atomic,{[6],
{mnesia_select,md,
{tid,10535470,},
ejabberd@localhost,disc_only_copies,
{dets_cont,select,5,
<>,
{141720,148792,<>},
md,,<>},
[],undefined,undefined,
[{{md,’$1′,’_’},[{‘ test:operater(fun mnesia:select/1,C1).
{aborted,wrong_transaction}
[Reply]
博主, 向您咨询一下, http://mysql.taobao.org/index.php/Patch_source_code 在打这些 Patch 时, 有没有顺序? 有没有什么注意的事项?
[Reply]
霸哥,请教下Erlang目录结构的问题:
做个监控的项目,分为中控端和监控端,所以是两个子项目,会依赖于某些Util,那么目录结构怎么样好呢?
是
|– apps
| |– app1
| |– app2
| `– util
`– rebar.config
还是
|– app1
| `– rebar.config
|– app2
| `– rebar.config
`– util
`– rebar.config
两种结构有什么优缺点?有什么结构比较好的多application的开源Erlang项目可以参考吗?
[Reply]
Yu Feng Reply:
October 17th, 2013 at 6:58 pm
这样不好,具体参考leofs:http://www.leofs.org/ 做的最好的。
[Reply]
霸爷,mnesia 能不能只查询一条记录,select和match都会全部查找,我想要查到第一条记录后立即返回,提高效率
[Reply]
Yu Feng Reply:
November 20th, 2013 at 3:16 pm
皓庭 (14:46:18):
mnesia的select和match都依赖于ets的select,而ets的select又依赖于erlang的MatchSpec,针对ets的MatchSpec没有提供结果集条数的导出函数或变量,也没有提供控制流,这就没有办法根据记录数目进行查找和返回。如果希望减少匹配扫描行数,可以在匹配的MatchSpec内加上主键值,或者增加自己维护的索引表进行索引查找
皓庭 (15:06:52):
不过看代码找到这么个函数mnesia:select(Tab, MatchSpec, NObjects, Lock),这个函数可以一次取一定数量的行
褚霸 (15:06:54):
ok
皓庭 (15:15:54):
调用过程:mnesia:select(Tab, MatchSpec, NObjects, Lock)->ets:select(Tab, MatchSpec, Limit)->ets_select3->db_select_chunk回调,db_select_chunk回调包括db_select_chunk_tree|db_select_chunk_hash,这两个回调内部会检查已经匹配的行数是否已经达到limit数量,若达到,就返回,之后的行可以通过mnesia:select(Cont)->ets:select(Continuation)->ets_select1->db_select_continue回调重新取回
[Reply]
vicky Reply:
November 20th, 2013 at 5:50 pm
看来以后得多看源代码,比官方文档容易看很多,谢了~
[Reply]
霸爷,在centos 怎么安装 tsungthrift插件呢,我已经安装了 tsung1.4.2和erlang R15B
[Reply]
我想问下,Erlang的程序如果编译后对外分发的话,该怎样保护源代码呢?有人能成功反编译过不带debug_info的BEAM吗?
[Reply]
Yu Feng Reply:
December 16th, 2013 at 5:09 pm
直接发beam,strip掉debuginfo就好了。rebar就有这个选项。
[Reply]
名字写错了,见谅,哈哈@霸哥
[Reply]
不好意思啊。。我初学者,想请教一下,我在机器上直接用fio的命令+参数就可以运行,而使用了.fio的jobfile之后再用.sh调用fio,就好像什么都没发生一样,不知道为什么,想请您帮帮忙~~~
[Reply]
WeiJian Reply:
January 5th, 2014 at 8:18 pm
这是运行的脚本
QD=64 DISK=/dev/md127 SIZE=15g RECORD_SIZE=4K RUNTIME=100 fio –output test. result –section rand-reak-4K all.fio
这是jobfile
———-all.fio———————
1 [global]
2 iodepth=${QD}
3 #QD=length of waiting queue
4 runtime=${RUNTIME}
5 ioengine=libaio
6 direct=1
7 size=${SIZE}
8 filename=${DISK}
…..
28 [rand-read-4k]
29 rw=randread
30 bs=${RECORD_SIZE}
31 iodepth_batch_submit=1
32 iodepth_batch_complete=1
[Reply]
老大,我遇到个疑难问题!我使用odbcserver模式开发一个与各类数据库打交道的数据交换系统,该系统正常情况没有什么异常,但是时间一长会发生erlang端的socket与c的socket对连接状态判断不一致的情况,造成c的recv返回为0,关闭c的socket后,erlang端的socket却没有向erlang端的进程发送tcp关闭连接消息,不知道老大是否遇到过?如果老大遇到过,我愿意付费请教老大
[Reply]
Yu Feng Reply:
January 18th, 2014 at 8:26 pm
这个应该很好查把。1. 先用wireshark抓包,确认tcp fin包的情况。 2. 用strace看下beam这样的syscall情况,特别是recv或者close之类的系统调用。 3. 结合抓包和strace的信息,查看inet_drv源码。
[Reply]
我心飞翔 Reply:
January 18th, 2014 at 9:07 pm
老大,我已经向你发送了邮件,详细描述了其中的问题!我现在的难处是无法还原现场故障,只能根据大家的经验了
[Reply]
yu大侠:一直关注你的博客,我们用Erlang开发了3个手游项目,虽然产品上线运行,但性能表现不好,单服同时在线1000人就会cpu平均占用80%(32核心机器,32GB内存),经过分析,发现我们对于ets用的过于频繁,最明显的是地图进程(每个地图一个进程,主要负责该地图内所有玩家、Npc、怪物的移动、战斗、AI),我们将地图中所有物件对象(玩家、怪物、Npc、资源等),都封装在每一种record(如mapPlayer、mapMonster等,每一个对象都很大,N多属性,N多list、array被包含在内),然后用ets管理这些对象,因为这些对象的读写都非常频繁,当单地图25vs25战斗pk的时候,会明显卡顿,所以,我们怀疑是ets的lookup和insert的拷贝开销太大,但是对于地图物件的管理或者说MMORPG游戏服务器的逻辑层架构来说,对于Erlang,我们自己实在没把握,想请教一下,我们现在讨论了一个方案:
1.每个玩家一个进程,负责处理网络请求和所有玩家逻辑;
2.N个怪物一个进程,负责处理怪物的所有AI及逻辑;(N的意思是可所有怪物一个进程或每一个怪物一个进程)
3.每个地图一个进程,该地图提供一个public的ets表,管理该地图上所有物件对象的简单的可视化信息(如id、坐标、hp、状态等,不超过20项数据),以提供给玩家进程和怪物进程在需要查询周围对象简单信息时,以ets的select操作方式返回对象列表(例如:玩家进入地图时需要将玩家周围的物件信息收集并发给玩家,此时直接ets:select操作,用对象的x、y坐标筛选出对象列表;再如:玩家的一个范围攻击请求,需要预先判断玩家周围对象哪些可否被攻击到,也是ets:select操作筛选出来)
此方案的疑虑:
1.地图进程的ets表内容需要频繁更新和获取,是否会因为共享读写锁的问题成为瓶颈?
2.如果弃用地图进程的ets,改用玩家进程、怪物进程的读写都使用rpc:call的方式,地图进程将共享数据放在state里或进程字典里,只允许非地图进程call地图进程(防止死锁),这种考虑是否会导致地图进程的消息处理太多而延迟较大,或者说与上一种方式(ets)相比,这种方式的cpu消耗和反应速度,哪个更优?
3.攻击行为流程上,我们非常想实现为:攻击者进程做初步的判断,然后将自己的信息打包,rpc:call到目标进程,目标进程再做判断,计算好伤害,减血,广播消息,然后返回战斗结果。但是此方法无法避免两个对象相互call的死锁问题,所以,目前只能将call改为cast,但是逻辑时序问题会出现,比如:一个技能最多只能伤害3个目标这样的需求将很难实现。如果有什么好的方法也请赐教。
4.如果是每个怪物一个进程(我们特别想实现为这样的框架),峰值时大约将会有30000个进程并发,请问这样设计是否高效合理?
可以看出,我们对于用Erlang实现ARPG游戏时,对实时性要求高,同屏或同地图物件多的情况下,逻辑对象的进程划分和逻辑数据的存放上,我们没有搞清楚,如有同行(做MMORPG的,做回合制或推图类其实很好做),希望交流。
[Reply]
Yu Feng Reply:
January 28th, 2014 at 1:43 pm
整个场景听下来感觉性能瓶颈不在CPU上,而是在锁冲突上,目前方案不是重点。而是先用类似lcnt或者eprof看看锁冲突在哪里,然后再来跟进冲突来调整模型和消息交互流程。
[Reply]
霸爷, 关于最近的whatsapp的事儿, 他们的后台用erlang做的,你能搞些这个资料让大家分享下吗?谢谢~~~还有,我想学erlang, 但经常学段时间忙另外的去了, 回过头来继续学,忘的差不多了~~~请问有啥好方法吗? 做项目吗?还是啥? 求教
[Reply]
Yu Feng Reply:
March 3rd, 2014 at 10:40 am
我博客ppt下载页里面有很多Erlang的东西。最好是从项目驱动开始学习,效果好,有成效。
[Reply]
您好,我是一名在校学生,最近发现对于服务器一点都不了解,请问有没什么好方法或资料可以帮助我学习呢?
谢谢您了。
[Reply]
sunface Reply:
March 8th, 2014 at 12:55 pm
先入行实习吧,这一块是很需要经验的
[Reply]
Yu Feng Reply:
March 9th, 2014 at 2:26 pm
这块学问挺大的。
[Reply]
pzz2011 Reply:
March 15th, 2014 at 4:08 pm
嗯,我知道学问是挺大的,但是还是不知道怎么学习呀? 求指点了~
谢谢回复
pzz2011 Reply:
March 15th, 2014 at 4:10 pm
话说一定要通过实习才可以吗?
[Reply]
Yu Feng Reply:
March 16th, 2014 at 2:41 pm
潜心研究下如nginx这样的服务器吧,很多知识课本上学不来的。
霸爷,请教一个问题,在设置游戏里面玩家客户端的socket的选项的时候,{nodelay, true}, {delay_send, true},这两个难道不会冲突吗?应该是都为true呢,还是{nodelay,false},{delay_send,true}.谢谢啦
[Reply]
sunface Reply:
March 8th, 2014 at 12:54 pm
我查了下,{delay_send,true}是driver控制的,消息要先queue_up,然后才发送;{nodelay,true}是针对socket的行为,消息到了socket层面时候立刻发送,请问霸爷这样理解对吗?
[Reply]
Yu Feng Reply:
March 9th, 2014 at 2:26 pm
是这么理解的。
[Reply]
sunface Reply:
March 23rd, 2014 at 3:27 pm
谢谢霸爷
霸爷(他们这么叫,我也跟着这么叫了),我是erlang的新手,请问游戏里面一些常规设置(如:任务每天可完成次数、复活所需金币、活动的开启时间等),要把它们弄成可配置的,方便策划的同志们直接修改,一般用什么方式?
有人建议用 yrl 文件,但是网上这方面资料比较少(也可能是我不会找),如果要了解这方面的内容,能在哪里找到资料?请给点指引,谢谢。
[Reply]
Yu Feng Reply:
March 11th, 2014 at 10:08 pm
放在application环境变量或者ets表里好啦
[Reply]
Commando Reply:
March 13th, 2014 at 10:26 am
哦,对,我傻了,居然忘记ets了。。。谢谢
[Reply]
霸爷,又来请教您啦。老头子在书里有这样一段话,every time we make a registered process, we are creating a potential sequential bottleneck. So, try to avoid the use of registered processes. If you do create a registered process and use it as a server, make sure that it responds to all requests as quickly as possible. 为什么说注册进程是顺序瓶颈呢?那只是注册的时候顺序还是使用过程中也存在潜在的顺序瓶颈?
谢谢您啦
[Reply]
sunface Reply:
March 23rd, 2014 at 1:03 pm
我的理解是,同一个注册名只能使用一次,所以造成了潜在的顺序瓶颈,因为无法有多个同注册名的进程
[Reply]