首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > PowerDesigner >

Nginx SPDY patch兑现

2012-07-28 
Nginx SPDY patch实现前不久Nginx官方放出了SPDY的patch,到目前为止都还未合并进nginx源码,主要还是由于此

Nginx SPDY patch实现

前不久Nginx官方放出了SPDY的patch,到目前为止都还未合并进nginx源码,主要还是由于此patch还远不成熟,代码和功能都还不足够完善。个人感觉spdy patch合并进nginx源码还有些时日。本文是基于目前的patch,初窥一下nginx官方是如何在实现spdy。


Nginx SPDY patch兑现

上图是nginx处理一个请求的大致流程,这里只是绘制了简单的模型,实际过程还是相当的复杂的。图中红色部分即是SPDY patch的主要内容。
针对普通的http请求,nginx是采用了一个状态机来流式的解析http协议,(所谓流式解析就是“收到一个字节就解析一个字节“,不必一定要收齐多少字节才开始解析),最终将请求的所有数据存储到一个request对象中,在接下来的handler模块中,就可以处理这个request对象了。一个请求的处理工作完成后,就开始经过一层一层的filter模块将响应给发出去。
面对一个spdy请求,nginx总体处理流程和http请求一样,主要不同的地方就是请求的解析器变了,但spdy的解析结果也是完全的将数据存储到普通http使用的request对象中,并没有引入一个新的spdy request对象,这就有点像是将spdy请求透明的转化为http请求。也只有将spdy请求转化为http请求,目前的所有handler、filter模块才能够正常的工作。由于经过handler、filter模块后的响应是一个http的响应,所以必须引入一个spdy filter模块将http响应的内容组装成一个spdy的帧消息来应答客户端。
下面再继续看看SPDY解析处理过程的细节,spdy filter模块做的事情比较简单,本文就暂且忽略了。
看过nginx源码的读者应该都知道客户端发送一个请求给nginx时,nginx首先将被调用的一个函数是ngx_http_init_request,在此函数中重点关注如下代码段:

static ngx_int_tngx_http_spdy_process_headers(ngx_http_spdy_connection_t *sc, u_char **pos,    size_t size){    int                         z;    ngx_buf_t                  *buf;    ngx_int_t                   rc;    ngx_uint_t                  last;    ngx_table_elt_t            *h;    ngx_connection_t           *c;    ngx_http_request_t         *r; 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。    sc->processing++;// 这里将要开始执行这个请求了,下面详细看看其过程。    ngx_http_spdy_run_request(r);// 这个frame处理完成后,就重置spdy解析器为frame判断入口回调函数,准备处理下一个frame。    sc->handler = ngx_http_spdy_process_frame;    return NGX_DONE;}static voidngx_http_spdy_run_request(ngx_http_request_t *r){    ngx_uint_t                  i;    ngx_list_part_t            *part;    ngx_table_elt_t            *h;    ngx_connection_t           *fc;    ngx_http_header_t          *hh;    ngx_http_core_main_conf_t  *cmcf;// 根据spdy的请求数据去构造普通http的请求行,这就是前面提到的spdy到http的转化过程。    if (ngx_http_spdy_construct_request_line(r) != NGX_OK) {        ngx_http_spdy_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);        return;    } 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。    r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;// 处理header,也是在转化spdy到http。    if (ngx_http_process_request_header(r) != NGX_OK) {        return;    }    if (r->plain_http) {        ngx_log_error(NGX_LOG_INFO, fc->log, 0,                      "client sent plain HTTP request to HTTPS port");        ngx_http_spdy_finalize_request(r, NGX_HTTP_TO_HTTPS);        return;    }#if (NGX_STAT_STUB)    (void) ngx_atomic_fetch_add(ngx_stat_reading, -1);    r->stat_reading = 0;    (void) ngx_atomic_fetch_add(ngx_stat_writing, 1);    r->stat_writing = 1;#endif    r->write_event_handler = ngx_http_core_run_phases;// 开始执行请求,主要执行所有的phases阶段,这里就开始进入了普通http请求的流程了。// 接下去就是经过所有的handler,filter等模块流程。    ngx_http_core_run_phases(r);    ngx_http_run_posted_requests(fc);}

总结:

spdy patch的实现还是非常的清晰,主要目标就两个:1、是解析spdy frame,2、是转化为了http request。从代码可以看出此patch仅仅是一个初步的实现,还有很多的地方没有完善,后面nginx官网在实现上指不定还有大的调整也不奇怪。当然,spdy的server push等复杂又强大功能在此patch中根本还没有一点实现。

热点排行