zoukankan      html  css  js  c++  java
  • 【erlang 网络编程学习】 分析cowboy acceptor实现

    http://www.tuicool.com/articles/vuymei

    不知道为什么就看了cowboy代码,就继续看了下去了。

    分析一下吧,主要写写cowboy 的acceptor pool 的实现

    cowboy的源码比mochiweb的更简洁, acceptor pool是通用的,cowboy提供了tcp的协议实现。而应用层协议也是通用的,cowboy提供了http协议的实现。 

    一、循例分析一下 cowboy 的线程树结构,从它启动的。入手 (现在先列出来cowboy启动的流程,等下说工作流程时候再串联起来。 ) 

    想用appmon和observer截图cowboy 的线程树了。但是不太好看,太多了。(主要是创建的acceptor线程太多)。我就文字说说吧。

    application:start(crypto),
      application:start(public_key),
      application:start(ssl),
      application:start(cowboy).


    之后会创建一个cowboy_clock的worker。 同时根据配置文件,去选择要不要启动eprof来统计执行时间。

    然后application的启动就结束了,然后到启动listener的代码。如下

    Dispatch = [
        {'_', [
          {[<<"websocket">>], websocket_handler, []},
          {[<<"eventsource">>], eventsource_handler, []},
          {[<<"eventsource">>, <<"live">>], eventsource_emitter, []},
          {'_', default_handler, []}
        ]}
      ],
      cowboy:start_listener(my_http_listener, 100,
        cowboy_tcp_transport, [{port, 8080}],
        cowboy_http_protocol, [{dispatch, Dispatch}]
      ).

    这次就依照tcp的连接池和http的应用层协议来讲吧

    cowboy:start_listener  其实就做了一件事, 把cowboy_listener_sup  作为supervisor 动态添加到cowboy_sup下 

    然后cowboy_listener_sup 会创建三个子线程,cowboy_listener 是worker ,还有cowboy_requests_sup是supervisor , cowboy_acceptors_sup也是supervisor

    cowboy_listener 用了gen_server模式,这个文件是实现了连接池的算法。

    cowboy_requests_sup 是声明了 simple_one_for_one 。 顾名思义,这文件是响应请求的worker线程的supervisor。    (插话说simple_one_for_one 使用最经典场景就是网络编程中新建工作线程来处理请求了。)

    cowboy_acceptor_sup 会有两个动作

    调用cowboy_tcp_transport:listen,里面其实就是调用gen_tcp:listen

    创建一堆cowboy_acceptor 的worker 线程

    启动就到这里了。现在开始说它的工作流程。

    二、cowboy acceptor pool工作模式

     

    cowboy_acceptor 文件:

    初始化时候,cowboy_acceptor是创建线程来监听accept

    cowboy_acceptor 的工作步骤有几个:

    1),调用gen_tcp:accept ,默认是2秒超时

    2),假如超时后,他会坚持配置参数是否更新了,然后再重新监听

    3)如果accept到有信息,它就会在cowboy_request_sup下面创建worker

        cowboy_request 线程会调用指定的协议处理文件。 
        这时候会跳转到对应的http协议实现里面去处理这个请求。(这里我不跟进去了)

    4)调用绑定socket和pid 的controlling_process()

    5)调用cowboy_listener:add_connection 来更新连接池里面的动态。

    cowboy_listener 所维护的池是怎样工作的呢?我们继续看下去。

    首先会调用add_pid ,里面做了几件事

        首先会monitor创建的request工作线程

       然后发一个 shoot信息过去,确认socket的控制权给到了http协议。

       然后池内连接数加1.再存到ets里面。

    add_pid之后它会对比使用的配置是否更新了

    代码很浅白,我想说的是, queue:in 那里,它会吧这个记录保存在一个队列里面。为什么这样做呢? 在remove_connecttion时候就会用到

    当工作做完,要断开连接时候,cowboy_listener是这样工作的:

    调用remove_pid 

       从ets里面取出池状态

       移除monitor

       连接数+1

         然后 queue:out出来,通知 http协议可以socket控制权已经移交回来。

       

      

      -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

    这次是后记,描述得不是很好,而且功夫还未到家。见笑了。下次写cowboy的协议扩展。

    all  by dp~~ 

  • 相关阅读:
    Visual Studio 2008中文正式版
    属性控制类
    PowerDesigner11技巧
    OPENXML用法
    .net下载文件
    Merge Into 语句代替Insert/Update在Oracle中的应用实战
    PowerDesigner中使用vbscript访问对象进行批量操作
    转:SubSonic介绍和相关文章
    C# 多线程控制控件实例(例程简单,注释详细)
    学习SubSonic的笔记 Version 2.1
  • 原文地址:https://www.cnblogs.com/fvsfvs123/p/4136800.html
Copyright © 2011-2022 走看看