Erlang cowboy http request生命周期

翻译自:

http://ninenines.eu/docs/en/cowboy/1.0/guide/http_req_life/

request的生命周期

本章解释服务器response之前的http request的步骤,以及cowboy实现的细节。

Request/response

正如你了解到的,HTTP客户端连接到服务器,发送资源请求(request),服务器发送响应(response),其中包含可以获取到的资源。

在服务器发送资源之前,它需要一些步骤去读请求,找出资源,准备发送资源,还包括其他关联的操作,如写日志等。

在cowboy中,请求按下图路由:

本图显示了默认的处理中间件(middlewares),可以被设置成不同的方式。深绿色(双框)标明了用户可以插入(hook)自己实现的代码点。浅绿色是cowboy代码,可以根据需要设置。

acceptor是服务器的一部分,它接受连接,然后创建一个Erlang进程处理它。

parser接着开始读取socket连接,当请求到来时处理之,直到socket关闭。

在请求的整个周期中,可以在多个地方返回响应。如果cowboy不能解析请求,它会结束处理返回错误。如果路由router不能找到资源,它会返回not found错误。你自己的代码在任何时候都可以返回响应。

当响应被发送,你可以选择修改它,或者在onresponse的回调中实现代码。默认,响应被直接发送给客户端。

And then?

具体的行为依赖采用的协议。

HTTP/1.0 仅仅能一个连接处理一个请求,因此Cowboy在发送响应之后立即关闭连接。

HTTP/1.1 允许客户端请求服务端并保持这个连接。这个机制下面会说明。

SPDY 用于在同一个连接上发送多个异步请求,详见下面。

Keep-alive (HTTP/1.1)

在HTTP/1.1协议中,连接可以一直被打开,并连续发生请求。这种机制称为keep-alive

当客户端发送请求到服务端,它包含一个头,标识是否需要保持连接打开状态。服务端可以接受,也可以不接受,同样在响应的头部中返回它的选择。

对 HTTP/1.1 requests,Cowboy自动在所有响应中包含这个头部。如果你愿意也可关闭socket连接。 当 Cowboy 看到你设置了connection: close头,它不会覆盖你的设置,当响应被发送,就会关闭连接。

下面的代码强迫Cowboy关闭连接:

{ok, Req2} = cowboy_req:reply(200, [
    {<<"connection">>, <<"close">>},
], <<"Closing the socket in 3.. 2.. 1..">>, Req).

Cowboy在同一个连接上仅仅接受一定数目的请求,默认是100个请求。当启动一个HTTP监听时,这个数目可以按下面的方法改变(max_keepalive):

cowboy:start_http(my_http_listener, 100, [{port, 8080}], [
        {env, [{dispatch, Dispatch}]},
        {max_keepalive, 5}
]).

Cowboy通过为所有请求重用同一个进程来实现保活keep-alive。这样Cowboy就可以节省内存。这种方式能够起作用,因为多数代码对后续请求没有副作用。但是同时也意味如果你的代码存在副作用,就必须做清理工作,terminate/3函数就是干这个的。

Pipelining (HTTP/1.1)

HTTP是一种顺序化的协议,客户端发送请求,然后等待服务端响应。由于sockets的工作模式,http不会阻止客户发送更多的请求,不会强迫客户等待响应。服务器仍然按顺序地处理请求,按同样的次序返回响应。

这种机制称为pipelining。当客户在一个时间内请求更多的资源时能减少延时,例如,这种方式被浏览器请求静态文件时使用。

这种模式被服务器自动处理。

异步请求 requests (SPDY)

在SPDY,客户可以在任何时间发送请求,服务也是可以在任何时候返回响应。这意味着客户端不必等待请求被完全发送就可以发另一个请求,这样交织发送请求就成为可能。同样也适合服务端。响应也可以用不同的次序发送。

因为请求和响应是完全异步的,Cowboy为每个请求创建一个新的进程,这些进程被另一个处理连接的进程管理。SPDY服务也可以决定是否在请求之前发送资源给客户,这种方式对发送与HTML页面关联的静态文件特别有用,因为减少了响应延时。但是,当前Cowboy不支持这种机制。

Erlang cowboy http request生命周期的更多相关文章

  1. node.js WebService异常处理(domain)以及利用domain实现request生命周期的全局变量

    成熟的Web Service技术,例如Fast CGI.J2EE.php,必然会对代码异常有足够的保护,好的Web必然会在出错后给出友好的提示,而不是莫名其妙的等待504超时.而node.js这里比较 ...

  2. SpringMVC request生命周期

    When the request leaves the browser, it carries information about what the user is asking for. At ve ...

  3. javaBean Request生命周期

    request: 在request范围内,JavaBean对象的有效范围为: ① 客户请求访问的当前JSP页面② 和当前JSP页面共享同一个请求的页面,包括<%@ include%>指令以 ...

  4. MVC Request生命周期(综合总结)

    当用户在浏览器输入一个URL地址后,浏览器会发送一个请求到服务器.这时候在服务器上第一个负责处理请求的是IIS.然后IIS再根据请求的URL扩展名将请求分发给不同的处理程序处理. 流程如下: 当请求一 ...

  5. Request和Session的生命周期

    request的生命周期是request请求域,一个请求结束,则request结束 session的生命周期是session会话域,打开一个浏览器请求一个网站的页面后,Session开始,当sessi ...

  6. JAVA CDI 学习(2) - Scope 生命周期

    在上一节中,我们已经知道了如何用@Inject实现基本注入,这一节研究Bean实例注入后的“生命周期”,web application中有几种基本的生命周期(不管哪种编程语言都类似) 1.Applic ...

  7. [原创]java WEB学习笔记47:Servlet 监听器简介, ServletContext(Application 对象), HttpSession (Session 对象), HttpServletRequest (request 对象) 监听器,利用listener理解 三个对象的生命周期

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. Request Session生命周期及struts1 中service的编写

    现在接手的项目是一个早期的struts1框架的项目.同时也是刚开始接触web 以及struts1架构. 在处理多个action时,有一个tab子页面需要每5s自动刷新一次. 然后在测试过程中发现,点击 ...

  9. laravel中的$request对象构造及请求生命周期

    laravel应用程序中index.php是所有请求的入口.当用户提交一个form或者访问一个网页时,首先由kernel捕捉到该session PHP运行环境下的用户数据, 生成一个request对象 ...

随机推荐

  1. Python optparser库详解

    一直以来对optparser不是特别的理解,今天就狠下心,静下心研究了一下这个库.当然了,不敢说理解的很到位,但是足以应付正常的使用了.废话不多说,开始今天的分享吧. 简介 optparse模块主要用 ...

  2. GridView如何适配不同屏幕

    GridView和ListView一样,都是项目中常用的控件之一,那么本篇文章要讲的是GridView如何适应不同大小的屏幕,首先,我们来看一张效果图,如下: 每行为四个item,上下左右间距大概2d ...

  3. Asp.net 在刷新或提交页面后保持滚动条的位置

    网页内容在较长时,每次回传刷新页面或提交网页时都会定位到最顶端,非常不利于用户交互. 将Page.MaintainScrollPositionOnPostBack属性值设置为true即可实现刷新后保持 ...

  4. iOS 10 推送全解析,注意事项

    本文旨在对 iOS 推送进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解.以下是 pikacode 使用 iOS ...

  5. parcel和parcelable

    Parcel 在英文中有两个意思,其一是名词,为包裹,小包的意思: 其二为动词,意为打包,扎包.邮寄快递中的包裹也用的是这个词.Android采用这个词来表示封装消息数据.这个是通过IBinder通信 ...

  6. 05 利用Appliction 传值Activity

    步骤一:新建一个类继承Application必须是public class 不然直接奔溃 步骤二:在清单文件AndroidManifest.xml的application添加name属性 值为com. ...

  7. UNIX网络编程——UDP缺乏流量控制(改进版)

    现在我们查看无任何流量控制的UDP对数据报传输的影响.首先我们把dg_cli函数修改为发送固定数目的数据报,并不再从标准输入读.如下,它写2000个1400字节大小的UDP数据报给服务器. 客户端程序 ...

  8. Xcode中Objc动态调用方法同时避免警告的几个办法

    我们在Xcode中使用objc写代码的时候往往会碰到动态调用方法的时候. 如果是静态调用这很常见,不会有任何问题: [self performSelector:@selector(method)]; ...

  9. 任务定义器——SocketProcessor

    将socket扔进线程池前需要定义好任务,要进行哪些逻辑处理由SocketProcessor定义,根据线程池的约定,作为任务必须扩展Runnable.用如下伪代码表示 protected class ...

  10. 最简单的基于FFmpeg的内存读写的例子:内存播放器

    ===================================================== 最简单的基于FFmpeg的内存读写的例子系列文章列表: 最简单的基于FFmpeg的内存读写的 ...