Ranch浅析

文章参考自:
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

version: release 1.3.2

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

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

进程标识:

  1. <0.97.0>: ranch_app
  2. <0.103.0>: ranch_listerner_sup
  3. <0.104.0>: ranch_conn_sup
  4. <0.105.0>: ranch_acceptors_sup
    在这里插入图片描述

作为独立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:

  1. supervisor:start_link() 启动一个监督进程
  2. supervisor:start_child() 在指定监督进程下,启动一个子进程
  3. 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文件头部可见.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值