Erlang cowboy http request生命周期

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不支持这种机制。

时间: 2024-11-05 22:45:05

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

javaBean Request生命周期

request: 在request范围内,JavaBean对象的有效范围为: ① 客户请求访问的当前JSP页面② 和当前JSP页面共享同一个请求的页面,包括<%@ include%>指令以及<jsp:forward>标记包含的其他JSP文件.③ 当所有共享同一个客户请求的JSP页面执行完毕并向客户端发回响应时,JavaBean对象结束生命周期. JavaBean对象作为属性保存在了HttpServletRequest对象中,属性名为JavaBean的id,属性值为JavaBean对

JSF教程(8)——生命周期之Apply Request Values Phase

当一个组件树在一个postbacks请求中被恢复之后其中每个组件从request的参数中取得各自的值,这里使用的是processDecodes方法.这个值会保存在本地的每个组件中,在源码中此过程的代码较为简单,因为实现者将取值这个操作全部封装在processDecodes方法中.不过说实话JSF的这部分的实现非常失败,因为在UIViewRoot中有将近两千行代码,这,这,这-- (UIViewRoot.java中的processDecodes方法) public void processDeco

request请求生命周期

request请求生命周期 一.request请求分析 1.1. request数据请求 # views.py from rest_framework.views import APIView from rest_framework.response import Response from django.http.request import QueryDict class BookAPIView(APIView): def get(self, request, *args, **kwargs

servlet和Jsp生命周期解读

一.servlet的工作工程 Servlet是运行在Servlet容器(有时候也叫Servlet引擎,是web服务器和应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于MIME的请求,格式化基于MIME的响应.常用的tomcat.jboss.weblogic都是Servlet容器)中的,其生命周期是由容器来管理. 二.Servlet生命周期 Servlet是运行在Servlet容器(有时候也叫Servlet引擎,是web服务器和应用程序服务器的一部分,用于在发送的请求和响应

Servlet生命周期和工作原理

Servlet生命周期分为三个阶段: 1,初始化阶段  调用init()方法 2,响应客户请求阶段 调用service()方法 3,终止阶段 调用destroy()方法 Servlet初始化阶段: 在下列时刻Servlet容器装载Servlet: 1,Servlet容器启动时自动装载某些Servlet,实现它只需要在web.XML文件中的<Servlet></Servlet>之间添加如下代码: <loadon-startup>1</loadon-startup&g

Servlet学习笔记(一):生命周期

一.Servlet 生命周期: Servlet 生命周期可被定义为从创建直到毁灭的整个过程.以下是 Servlet 遵循的过程:初始化--响应请求--终止--回收 Servlet 通过调用 init () 方法进行初始化. Servlet 调用 service() 方法来处理客户端的请求. Servlet 通过调用 destroy() 方法终止(结束). 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的. 现在让我们详细讨论生命周期的方法. 1.init() 方法: init 方法

【转】.net MVC 生命周期

对于Asp.net MVC,我对它的生命周期还是兴趣很浓,于是提出两个问题: 一个HTTP请求从IIS移交到Asp.net运行时,Asp.net MVC是在什么时机获得了控制权并对请求进行处理呢?处理过程又是怎样的? 以IIS7中asp.net应用程序生命周期为例,下图是来自MSDN的一张HTTP请求处理过程发生事件的简图,后面我列出了一个完整的事件列表.既然Asp.net Mvc还是以Asp.net运行时为基础那么它必然要在Asp.net应用程序的生命周期中对请求进行截获.第一反应当然是去we

服务【启动方式】生命周期 通讯

基本概念 Service通常总是称之为"后台服务",其中"后台"一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件: 1.并不依赖于用户可视的UI界面(当然,这一条其实也不是绝对的,如前台Service就是与Notification界面结合使用的) 2.具有较长时间的运行特性 服务的两(三)种启动方式 1.startService方式启动服务 最核心的一句话:当Client

MyBatis 作用域和生命周期

理解到目前为止所讨论的类的作用域和生命周期是非常重要的.如果使用不当可导致严重的并发性问题. SqlSessionFactoryBuilder  这个类可以在任何时候被实例化.使用和销毁.一旦您创造了SqlSessionFactory 就不需要 再保留它了.所以SqlSessionFactoryBuilder 实例的最好的作用域是方法体内(即一个本地方法 变量).您能重用SqlSessionFactoryBuilder 创建多个SqlSessionFactory 实例,但最好不要把 时间.资源放