美文网首页
ranch浅析

ranch浅析

作者: kyo1992 | 来源:发表于2020-07-06 10:19 被阅读0次

    文章参考自:
    https://www.cnblogs.com/tudou008/p/5484911.html
    https://www.cnblogs.com/fvsfvs123/p/4178117.html
    https://blog.csdn.net/eeeggghit/article/details/83507563
    https://blog.csdn.net/huang1196/article/details/38401197
    版本: release 1.3.2


    Part 1: 进程结构和启动流程

    作为独立application启动后,进程结构图如下:

    进程标识:

    • <0.97.0>: ranch_app
    • <0.103.0>: ranch_listerner_sup
    • <0.104.0>: ranch_conn_sup
    • <0.105.0>: ranch_acceptors_sup
    image.png

    作为独立application启动流程:

    1. ranch_app:start()
    2. ranch_sup:init()
    3. ranch_server:start_link()
    4. ranch_server

    然后在application中调用

    1. ranch:start_listener() => ranch_sup 创建 ranch_listener_sup
    2. ranch_listener_sup 创建 ranch_conns_sup 和 ranch_acceptors_sup
    3. ranch_acceptors_sup(启动NumAcceptors个ranch_acceptors监听listen_socket).

    需要了解的api:

    • supervisor:start_link() 启动一个监督进程
    • supervisor:start_child() 在指定监督进程下,启动一个子进程
    • gen_tcp:controlling_process() 将指定socket的控制权转移给指定的进程

    Part2: 代码细节

    1. gen_tcp:accept 得到socket的active 属性是 {active, false}, 这种情况下要接收socket的消息, 方法只有手动调用 gen_tcp:recv 阻塞等待消息到来. (tcp_echo例子), 要么 inet:setopt(Socket, [{active, once}]. 这样每当有消息到来,就会通知进程(仅一次, 处理完消息后,下次仍需手动设置为 [{active,once}]).

    2. tcp_reverse例子中,当有新的网络连接到来, 会通知ranch_conns_sup启动reverse_protocol, 而reverse_porotocol是gen_server行为, gen_server:start_link, 本质是调用proc_lib:start_link启动进程, 需要等到Mod:init调用完毕后, 才会给父进程发送子进程id,表示子进程启动完毕,但是在Mod:init中调用了 ranch:accept_ack, 子进程会处于一直等待shoot消息,而shoot消息需要reverse_protocol进程启动者 – ranch_conn_sup发送,但ranch_conn_sup又无法获取到reverse_protocol_pid,所以不能发送消息,两个进程处于互相等待状态 .
      所以官方给出解决方法是 Mod:start_link函数体内,使用 proc_lib:spawn_link 启动reverse_protocol进程,该函数可以马上返回pid到父进程ranch_conn_sup, 而子进程调用Mod:init函数后,等待shoot消息到来,收到ranch_conn_sup发送的shoot消息后,再调用 gen_server:enter_loop , 子进程状态进入gen_server:loop函数中,表现与正常的gen_server一样.

    3. tcp_reverse例子中, 消息处理完毕后,返回结果第三个参数传入超时时间,这样5秒后进程无消息到达则会收到 timeout 消息,返回 {stop, normal, State} 进入关闭进程处理.

    4. ranch_server进程本质上是一个管理各个连接实例Ref的角色,拥有一张Ets表,存储的信息有
      ①. {conns_sup, Ref}: 实例的ranch_conns_sup进程Pid
      ②. {addr, Ref}: 实例的inet:sockname(ListenSocket)信息
      ③. {max_conns, Ref}: 实例的最大连接数
      ④. {opts, Ref}: 实例的传输层参数(TransOpt}.
      实例启动和停止都会涉及ranch_server信息修改, 有了ranch_server这些基础工作,ranch才能实现多实例管理.

    5. 应用到自己的项目,注意要修改Opts参数,主要是 {port,max_connections} 这两个参数.
      ranch_tcp的opt的所有可选参数在 ranch_tcp文件头部可见,ranch_ssl的opt则在ranch_ssl文件头部可见.

    相关文章

      网友评论

          本文标题:ranch浅析

          本文链接:https://www.haomeiwen.com/subject/dmqwqktx.html