关注LAMP|PHP源代码分析|web架构|PHP扩展|Erlang|服务端架构
  • 5 月珠三角技术沙龙(广州)网游技术专场PPT

    2011-06-10
  • erlang zlib引起的系统崩溃记录

    2010-08-11

    author: 庆亮 (qing.liang.cn@gmail.com /  http://twitter.com/qingliangcn )

    date: 2010-07-12

     

    之前同事遇到一个问题,系统运行一段时间后有大量的port没有正常关闭而导致beam崩溃,经过定位发现是由于zlib引起的。过程很简单,没什么技术含量,记录一下。 Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • Erlang OTP之terminate 深入分析

    2010-08-03

    作者:庆亮 (qing.liang.cn@gmail.com)

    日期:2010-08-03

    环境:centos  5.5  64     erlang 14A

     

    一、terminate简述及问题产生

     

    terminategen_server的一个回调函数,如果一个gen_server进程设置了trap_exittrueprocess_flag(trap_exit, true)),则在该进程结束时会自动调用terminate。利用这个功能,我们可以在进程退出时进行一些善后工作,例如持久化数据、清理等等。但实际上terminate不一定有时间完成所有的任务,在此之前可能已经被系统强制结束了(如果使用init:stop形式结束beam)Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • erlang init stop浅析

    2010-08-03

    作者:庆亮 (qing.liang.cn@gmail.com)

    日期:2010-08-03

     

     

    boot之后关注的自然是stop,直接打开erts-5.7.5/src/init.erl源码看了看:

     

    -spec stop() -> no_return().
    stop() -> init !
    {stop,stop}, ok.

    {stop,Reason} ->
                stop(
    Reason,State); Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • erlang init boot 浅析

    2010-08-03

    说明:遇到一个OTP的问题,疑惑了很久,也就有了这篇文章。

    目的:跟踪Erlang的启动过程

     

    参考这里 http://erlangdisplay.javaeye.com/blog/315497 ,直接从erts-5.7.5/src/init.erl boot/1函数开始(关于这个链接给出的结论以后会继续研究分析):

    Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • erlang shell web版

    2010-08-02

    http://www.tryerlang.org/

    作者:庆亮 | 分类目录:Erlang | 标签:
  • R13B04的Emacs erlang-mode

    2010-05-21

    R13B04的Emacs erlang-mode在编译后少了几个文件,默认%erlang_root%/lib/tools-2.6.5.1/emacs下有如下文件:

     

    -rw-r–r– 1 root root 183741 2010-05-21 11:43 erlang.el

    -rw-r–r– 1 root root  10059 2010-05-21 11:43 erlang-eunit.el

    -rw-r–r– 1 root root   3452 2010-05-21 11:43 erlang-start.el

    -rw-r–r– 1 root root   1611 2010-05-21 11:43 README

    -rw-r–r– 1 root root  12834 2010-05-21 11:43 test.erl.indented

    -rw-r–r– 1 root root  11877 2010-05-21 11:43 test.erl.orig

    直接在emacs中配置指向这里的话,会无法正常使用erlang-mode:

    (setq load-path (cons "/usr/local/erlang/lib/tools-2.6.5.1/emacs" load-path))
     
    需要拷贝源代码目录中的emacs el文件过来,拷贝后如下:
    -r-xr-xr-x 1 root root  45795 2010-05-21 11:54 erlang_appwiz.el*
    -rw-r–r– 1 root root 183741 2010-05-21 11:54 erlang.el
    -rw-r–r– 1 root root  10059 2010-05-21 11:54 erlang-eunit.el
    -r-xr-xr-x 1 root root  55313 2010-05-21 11:54 erlang-skels.el*
    -r-xr-xr-x 1 root root  48006 2010-05-21 11:54 erlang-skels-old.el*
    -rw-r–r– 1 root root   3452 2010-05-21 11:54 erlang-start.el
    -rw-r–r– 1 root root   1611 2010-05-21 11:43 README
    -rw-r–r– 1 root root  12834 2010-05-21 11:43 test.erl.indented
    -rw-r–r– 1 root root  11877 2010-05-21 11:43 test.erl.orig

    作者:庆亮 | 分类目录:Erlang | 标签:
  • mnesia脏读与事物读性能结果

    2010-05-13

    一直知道mnesia的事务比较慢,但慢到什么程度却没有一个数值的概念,今天正好有空测试一下。

    上代码:

    -module(mnesia_read_test).

    -export([start/0, init_data/0, start2/0]).

    -record(r_test, {id, name}).

    start() ->

            statistics(wall_clock),

        statistics(runtime),

            read(),

            {_, Time1} = statistics(wall_clock),

        {_, Time2} = statistics(runtime),

        io:format("times:~p, wall_clock ~p, runtime:~p", [100000, Time1, Time2]).

      Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • gen_server三两话

    2010-04-17

    (最近挺忙,都没时间写点啥)

    gen_serverOTP中的一个重要组成,在开发中出现的频率相当高。弄明白这一块的,对于gen_server的使用有着相当好的帮忙。下面多数为代码。

    start_link开始:

    gen_server.erl

    start_link(NameModArgsOptions) ->

    gen:start(?MODULE, link, NameModArgsOptions).

     

    Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • Erlang中日志管理三两话

    2010-03-10

    日志系统的重要性就不罗嗦了,直接开始吧。

     

    一、基本概念

     

    Erlang中,通过两个概念管理错误事情:事件管理器(event manager)和事件处理句柄(event handles)。通常各种错误、警告和消息事件都会有Erlang运行时系统发送给事件管理器。在Erlang中,默认的事情管理器为error logger,其进程名注册为error_logger。默认情况下error_logger把这些事件直接输出到控制台上。 Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • list comprehensions与list map性能对比

    2010-02-26

    可以使用List comprehensions时不要 使用map或者filter,简单的性能测试对比一下:

    第一组,maplist comprehensions对比,代码如下:

    %%map方式

    -module(map_test).

    -export([start/1]).

    start(N) ->

            statistics(runtime),

            erlang:statistics(wall_clock),

            lists:map(fun (X) -> X*X end, lists:seq(1N)),

            {_T1} = erlang:statistics(runtime),

            {_T2} = erlang:statistics(wall_clock),

            io:format("total times: ~p, load time: ~p (~p)", [NT1T2]).

    %%list comprehensions方式

    -module(list_comp_test).

    -export([start/1]).

    start(N) ->

            statistics(runtime),

            erlang:statistics(wall_clock),

            [X*X || X <- lists:seq(1N)],

            {_T1} = erlang:statistics(runtime),

            {_T2} = erlang:statistics(wall_clock),

            io:format("total times: ~p, load time: ~p (~p)", [NT1T2]).

    测试N1000000时结果对比:

    结果取得是平均值,可以很明显的看出comprehension方式性能要高。

    关于filter,则类似。不再作测试。

    作者:庆亮 | 分类目录:Erlang | 标签:
  • erlang tcp发包速度测试

    2010-02-03

     

    这段时间我们的项目遇到广播包的一些性能问题,想起之前看到yufeng老大提到的1s广播40K包的问题,我也想测试测试我们机器的IO能力。

    这次仅仅测试发包的能力,采用的是一对一的方式。

    测试代码: Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • Erlang中计算16位的MD5字符串

    2010-01-18

     

    erlangbif中自带了md5计算函数,但是结果却是二进制的,即使转成list,也是10进制表示,google了一下得到一段代码用于获得字符串形式的md5结果(16位):

    md5(S) ->        

    Md5_bin =  erlang:md5(S), 

    Md5_list = binary_to_list(Md5_bin), 

    lists:flatten(list_to_hex(Md5_list)). 

     

    list_to_hex(L) -> 

    lists:map(fun(X) -> int_to_hex(XendL). 

     

    int_to_hex(Nwhen N < 256 -> 

    [hex(N div 16), hex(N rem 16)]. 

    hex(Nwhen N < 10 -> 

           $0+N

    hex(Nwhen N >= 10N < 16 ->      

    $a + (N-10).

    英文链接  http://sacharya.com/md5-in-erlang/

    作者:庆亮 | 分类目录:Erlang | 标签:
  • Erlang中粘包处理

    2010-01-13

     

    开始时用的传统思路(循环读取):

    recv(ClientSockPacketLenOldRemain

      when is_integer(PacketLenOldand is_binary(Remain) ->

    case gen_tcp:recv(ClientSock0of

    {ok, B} ->

    Bin = <<Remain/binary, B/binary>>,

    %% read the packet length

    if PacketLenOld =:= 0 andalso erlang:byte_size(Bin) > 2

     -> <<PacketLen:16Remain2/binary>> = Bin;

       true -> Remain2 = BinPacketLen = PacketLenOld

    end,

    ?DEBUG("packet length ~p", [PacketLen]),

    if 

    erlang:byte_size(Remain2) >= PacketLen

      -> {RealDataNext} = split_binary(Remain2PacketLen),

     MainData = decode(RealData),

     {ok, MainData0Next};

    true -> {continue, PacketLenRemain2}

    end;

    {error, closed} ->

    ?DEBUG("socket closed ~p ~n", [ClientSock]),

    {error, closed};

    {error, Reason} ->

    ?ERROR_MSG("socket closed ~p with reason: ~p ~n", [ClientSockReason]),

    {error, Reason}

    end.

    翻了翻文档发现实际上在erlang中没有必要这样麻烦

    The Length argument is only meaningful when the socket is in 

    raw mode and denotes the number of bytes to read. 

    If Length = 0, all available bytes are returned. 

    If Length > 0, exactly Length bytes are returned, or an error;

    recv(ClientSock) ->

    case gen_tcp:recv(ClientSock2of

    {ok, PacketLenBin} -> <<PacketLen:16>> = PacketLenBin,

    case gen_tcp:recv(ClientSockPacketLenof

    {ok, RealData} ->

    ?DEBUG("recv data ~p", [RealData]),

    {ok, decode(RealData)};

    {error, Reason} ->

    ?ERROR_MSG("read packet data failed with reason: ~p", [Reason]),

    {error, Reason}

    end;

    {error, Reason} -> 

    ?ERROR_MSG("read packet length failed with reason: ~p", [Reason]),

    {error, Reason}

    end.

    作者:庆亮 | 分类目录:Erlang | 标签:
  • OTP中supervisor启动过程

    2010-01-02

     

    rabbit_sup模块开始看起:

    rabbit_sup模块的start_link是被rabbit app模块的start/2方法所调用的

    rabbit.erl文件:

    start(normal, []) ->

    {ok, SupPid} = rabbit_sup:start_link(),

    rabbit_sup.erl文件:

    -define(SERVER?MODULE).

    start_link() ->

    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

    这里的?SERVER和?MODULE是一样的值,都为rabbit_sup 。 Read More »

    作者:庆亮 | 分类目录:Erlang | 标签:
  • rabbitmq代码摘录(1)

    2009-12-31

     

    诸多erlang应用都是基于erlang现有的一些applicationrabbitmq也不例外,在rabbitmq中,需要的applicationsaslos_monmnesia。而rabbitmq启动这些application(包括其自身)的代码写的相当的巧妙:(源码基于rabbitmq 1.7.0

    文件 rabbit.erl

    -define(APPS, [os_mon, mnesia, rabbit]).

    start() ->

        try

            ok = prepare(),

            ok = rabbit_misc:start_applications(?APPS

        after

            %%give the error loggers some time to catch up

            timer:sleep(100)

        end.

    stop() ->

        ok = rabbit_misc:stop_applications(?APPS).

    文件 rabbit_misc.erl

    manage_applications(IterateDoUndoSkipErrorErrorTagApps) ->

        Iterate(fun (AppAcc) ->

                        case Do(Appof

                            ok -> [App | Acc];

                            {error, {SkipError_}} -> Acc;

                            {error, Reason} ->

                                lists:foreach(UndoAcc),

                                throw({error, {ErrorTagAppReason}})

                        end

                end, [], Apps),

        ok.

    start_applications(Apps) ->

        manage_applications(fun lists:foldl/3,

                            fun application:start/1,

                            fun application:stop/1,

                            already_started,

                            cannot_start_application,

                            Apps).

    stop_applications(Apps) ->

        manage_applications(fun lists:foldr/3,

                            fun application:stop/1,

                            fun application:start/1,

                            not_started,

                            cannot_stop_application,

                            Apps).

    顺序启动或者关闭几个application,在失败的情况下首先判断操作失败的原因,如果是已经启动或者已经停止,则跳过;如果是启动失败或者停止失败,则先依次停止或者启动之前已经操作成功的application,之后抛出异常结束进程。

    作者:庆亮 | 分类目录:Erlang | 标签: