cowboy是一个用erlang编写的简洁,快速的http server,代码质量很高。
最新版本的代码貌似把原先的网络层socket pool剥离出来,做成了一个新的项目ranch。
所以首先我们先来分析一下ranch。
分析ranch代码首先必须明确三个关键概念:
Listeners:
A listener is a set of processes whose role is to listen on a port for new connections. It manages a pool of acceptor processes, each of them indefinitely accepting connections.
基本上就是为每个监听端口,创建管理一个socket acceptor池,代码中主要涉及ranch_listener_sup, ranch_listener, ranch_acceptor_sup, ranch_acceptor等模块
Transports:
A transport defines the interface to interact with a socket.
主要涉及ranch_transport,ranch_ssl封装ssl模块, ranch_tcp封装gen_tcp模块,统一上层暴露接口。
Protocols:
A protocol handler starts a connection process and defines the protocol logic executed in this process.
呃,可以理解成接收和处理协议逻辑的session= =,实现了ranch_protocol的回调接口的应用层代码的相关模块。
首先我们来看一下,ranch启动一个新监听端口的过程。
启动一个新的ranch_listener_sup,将起挂在ranch_sup监督进程下。
ranch_listener_sup依次启动
ranch_listener:管理tcp的options,监视connection进程的生存状况等。
ranch_conns_sup:所有connection进程的监督进程。
ranch_acceptor_sup:所有acceptor进程的监督进程,启动后,按照传入参数,初始化所有acceptor pool中的ranch_acceptor.
ranch_listener和每个ranch_acceptor在启动过程中,通知到ranch_server。
ranch_server在每次创建一个新的ranch_listener时候,
往ets注册三个表项。分别记录下listener的Pid,acceptor池中的进程,还有连接到该端口的connection的数量,并且在每个listener进程和acceptor进程消亡时,进行修改。
接下来,我们再看一下,当有一个客户端连接该监听端口时的变化
当ranch_acceptor接受到一个新的连接时候,启动一个connection进程,挂在ranch_conn_sup下,
同时通知ranch_listener,将connection纳入其监视下,ranch_server也得到通知,更新相应listener下connections的数量。
图画的比较草,不是很精确,不过大体流程写清楚了,启动ranch端口监听之后,与应用层的耦合点就在于实现了ranch_protocol接口的connection。后面讲述cowboy主体应用的时候,
我再详细的分析一下代码。写完收功= =
Ranch User Guide:http://ninenines.eu/docs/en/ranch/HEAD/guide/introduction