Archive

Archive for the ‘Erlang探索’ Category

seq_trace集群消息链跟踪利器

October 3rd, 2011 No comments

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: seq_trace集群消息链跟踪利器

做过网络集群服务器的的同学都知道,集群服务通常由不同的服务器组成,这些不同角色的服务器组合在一起共同完成了特定的服务。一个服务通常需要一个协调者,和不同的工作者。 协调者负责派发任务,接收工作者的完成情况,最终回馈给用户。举个例子来讲,拨打电话:首先需要确认你的号码是在有效的,同时还要看下你的帐号里面有钱不,还要看下你拨打的电话号码是不是由权限,电话打的时候需要扣钱,等等。 这些服务中间的任何一个环节出问题了,服务就不正常了。那么我们在服务出问题的时候,如何定位问题呢?通常的办法是打日志,在所有的参与服务的节点上打开日志记录,之后到所有的节点上收集日志,集中分析日志,相当的麻烦。

这时候seq_trace来救助了,seq_trace的目标就是能够跟踪一条消息经过的所有环节,最终把路径展现给用户。
铺垫材料:
seq_trace工作原理,请参考这里
ttb对seq_trace的支持参考这里
tdbg对seq_trace的支持参考这里
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , , ,

hibernate使用注意事项

October 2nd, 2011 No comments

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: hibernate使用注意事项

hibernate的作用是在进程闲的时候或者内存紧张的时候,通过重新整理进程的堆和栈内存来减少内存的消耗,同时维持进程之前的状态,但是误用会引起些问题,这里我们来展开下。

erlang:hibernate文档参考这里
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: ,

Erlang代码反编译以及查看汇编码

October 2nd, 2011 No comments

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: Erlang代码反编译以及查看汇编码

Erlang的代码是先翻译成abstract_code,再到目标代码的,如果有符号信息很容易恢复源代码,通常我们部署系统的时候需要把符号信息去掉,reltool就可以干这个事情!

我们演示下:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

未公开的gen_tcp:unrecv以及接收缓冲区行为分析

October 1st, 2011 No comments

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: 未公开的gen_tcp:unrecv以及接收缓冲区行为分析

gen_tcp:unrecv是个未公开的函数,作用是往tcp的接收缓冲区里面填入指定的数据。别看这小小的函数,用起来很舒服的。
我们先看下它的代码实现,Erlang代码部分:

%%gen_tcp.erl:L299
unrecv(S, Data) when is_port(S) ->
    case inet_db:lookup_socket(S) of
        {ok, Mod} ->
            Mod:unrecv(S, Data);
        Error ->
            Error
    end.
%%inet_tcp.erl:L58
unrecv(Socket, Data) -> prim_inet:unrecv(Socket, Data).

%%prim_inet.erl:L983
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% UNRECV(insock(), data) -> ok | {error, Reason}
%%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
unrecv(S, Data) ->
    case ctl_cmd(S, ?TCP_REQ_UNRECV, Data) of
        {ok, _} -> ok;
        Error  -> Error
    end.

运行期c代码部分:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , ,

gen_tcp发送进程被挂起起因分析及对策

October 1st, 2011 No comments

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: gen_tcp发送进程被挂起起因分析及对策

最近有同学在gmail上问关于gen_tcp发送进程被挂起的问题,问题描述的非常好,见底下:

第一个问题是关于port_command和gen_tcp:send的。从项目上线至今,我在tcp发送的地方遇到过两次问题,都跟port_command有关系。

起初程序的性能不好,我从各方面尝试分析和优化,还有部分是靠猜测,当初把全服广播消息的地方,换成了port_command,当时参考了hotwheels的代码和您的一遍相关博文。

根据您的分析,port_command应该比直接用gen_tcp:send高效的,并且没有阻塞。但是我却在这个地方遇到了阻塞,具体表现如下(两次,分别出现在项目不同阶段,下面分别描述)

项目上线初期:

当时玩家进程给玩家发消息用的是gen_tcp:send,广播进程为了高效率用了port_command。当活跃玩家到了一定数量以后,玩家无法进入游戏,分析原因,是全局发送广播消息的进程堵住了,从message_queue_len可以看出来,改为广播进程给玩家进程发消息再让玩家进程给玩家自己发消息后,状况排除。

最近一段时间:

这时候玩家进程的tcp发送数据,已经被我替换成了port_command并运行了一段时间都没问题。但是一些流量比较大的游戏服,活跃玩家到了一定数量以后,消息延迟很大(5-6秒),做任何操作都卡,在出现状况期间,服务器CPU、内存、负载各项指标并未异常,ssh连到服务器操作也很正常,没有任何卡顿现象。同服务器的其它游戏服也都正常,但是出问题的游戏服的整个erlang节点都进入一个“很卡”的状态,体现在我进入erlang shell中进行操作时,输入文字延迟很大。

起初我没怀疑过port_command有问题,所以我到处找原因和“优化”代码,这个优化是加了引号的。

但是最后,在一次服务器同样出现状况很卡的时候,我把tcp发送数据的代码改回了gen_tcp:send,并热更新了相关模块,服务器立即恢复正常。

我一直对上面的情况百思不得其解,我之前写的代码如下:

tcp_send (Socket, Bin) ->
try erlang:port_command(Socket, Bin, [force, nosuspend]) of
false ->
exit({game_tcp_send_error, busy});
true ->
true
catch
error : Error ->
exit({game_tcp_send_error, {error, einval, Error}})
end.

希望您能帮忙分析下是什么原因导致整个erlang节点都卡的,我想这对其他的erlang程序员也会有帮助!

关于这个问题我之前写了篇文章,系统的介绍了gen_tcp的行为,gen_tcp:send的深度解刨和使用指南(初稿)见 这里
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: , , ,

Erlang集群未公开特性:IP网段限制

October 1st, 2011 No comments

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: Erlang集群未公开特性:IP网段限制

Erlang集群二个节点之间的通讯是通过一个tcp长连接进行的,而且是全联通的,一旦cookie论证通过了,任何一个节点就获得全集群的访问权,可以参考Erlang分布的核心技术浅析
。erlang的这个授权模式特定搞的这么简单,但是在实际使用中还是有安全性的问题。我们退而求其次,来个IP网段限制,这个功能Erlang是有的只是没有文档化。
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Erlang集群自动化添加节点指南

September 30th, 2011 1 comment

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: Erlang集群自动化添加节点指南

Erlang的集群是由各个节点组成的,一个节点有一个名字来标识,而不管这个节点在网络的物理位置,所以在部署Erlang集群的时候就很方便。只要在集群里新启动一个节点,给个相对固定的引导的节点,让新节点和这个引导节点取得联系,由引导节点把新节点介绍入集群就OK了。
在实践中,新采购的机器上通常配置好IP,以及ssh访问权限。 我们需要在新机器上手工安装Erlang系统,部署新应用,然后启动应用节点,加入集群服务,这个步骤很繁琐。我们希望能够自动化去做这个事情。common_test的ct_系列模块来救助了。
common_test是A framework for automated testing of arbitrary target nodes,它随带的ct_ssh可以透过ssh在远程机器上执行各种各样的shell命令,通过scp传输数据;而ct_slave非常方便的可以连接到远程机器启动一个erlang节点。
pool(www.erlang.org/doc/man/pool.htm)模块也可以远程启动节点,但是它要依赖于操纵系统的ssh工具,需要在机器之间做ssh互信,也就是说ssh targetip这样的不能出现任何的交互,比如说键入密码,很不方便。

我们首先来演示下如何在远程机器上执行ssh命令:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索 Tags: ,