理解HTTP之keep-alive

在前面一篇文章中讲了TCP的keepalive,这篇文章再讲讲HTTP层面keep-alive。两种keepalive在拼写上面就是不一样的,只是发音一样,于是乎大家就都迷茫了。HTTP层面的keep-alive是我们接触比较多的,也是大家平时口头上的"keepalive"。下面我们就来谈谈HTTP的keep-alive

短连接&长连接&并行连接

再说keep-alive之前,先说说HTTP的短连接&长连接。

  • 短连接

    所谓短连接,就是每次请求一个资源就建立连接,请求完成后连接立马关闭。每次请求都经过“创建tcp连接->请求资源->响应资源->释放连接”这样的过程

  • 长连接

    所谓长连接(persistent connection),就是只建立一次连接,多次资源请求都复用该连接,完成后关闭。要请求一个页面上的十张图,只需要建立一次tcp连接,然后依次请求十张图,等待资源响应,释放连接。

  • 并行连接

    所谓并行连接(multiple connections),其实就是并发的短连接。

keep-alive

具体client和server要从短连接到长连接最简单演变需要做如下改进:

  1. client发出的HTTP请求头需要增加Connection:keep-alive字段
  2. Web-Server端要能识别Connection:keep-alive字段,并且在http的response里指定Connection:keep-alive字段,告诉client,我能提供keep-alive服务,并且"应允"client我暂时不会关闭socket连接

在HTTP/1.0里,为了实现client到web-server能支持长连接,必须在HTTP请求头里显示指定

Connection:keep-alive

在HTTP/1.1里,就默认是开启了keep-alive,要关闭keep-alive需要在HTTP请求头里显示指定

Connection:close

现在大多数浏览器都默认是使用HTTP/1.1,所以keep-alive都是默认打开的。一旦client和server达成协议,那么长连接就建立好了。

接下来client就给server发送http请求,继续上面的例子:请求十张图片。如果每次"请求->响应"都是独立的,那还好,10张图片的内容都是独立的。但是如果pipeline模式,上一个请求还没响应,下一个请求就发出,这样并发地发出10个请求,对于10个response client要怎么区分呢?而HTTP协议又是没有办法区分的,所以这种情况下必须要求server端地响应是顺序的,通过Conten-Length区分每次请求,这还只是针对静态资源,那对于动态资源无法预知页面大小的情况呢?我还没有深入研究,可以查看https://www.byvoid.com/blog/http-keep-alive-header

另外注意: 指定keep-alive是一种client和server端尽可能需要满足的约定,client和server可以在任意时刻都关闭keep-alive,彼此都不应该受影响。

Nginx keepa-alive配置

具体到Nginx的HTTP层的keepalive配置有

  • keepalive_timeout
    Syntax: keepalive_timeout timeout [header_timeout];Default:    keepalive_timeout 75s;Context:    http, server, location

The first parameter sets a timeout during which a keep-alive client connection will stay open on the server side. The zero value disables keep-alive client connections. The optional second parameter sets a value in the “Keep-Alive: timeout=time” response header field. Two parameters may differ.

  • keepalive_requests
    Syntax: keepalive_requests number;Default:    keepalive_requests 100;Context:    http, server, location

Sets the maximum number of requests that can be served through one keep-alive connection. After the maximum number of requests are made, the connection is closed.

可以看看Nginx的关于 keepalive_timeout 是实现

./src/http/ngx_http_request.cstatic void
ngx_http_finalize_connection(ngx_http_request_t *r){
...if (!ngx_terminate&& !ngx_exiting&& r->keepalive&& clcf->keepalive_timeout > 0){ngx_http_set_keepalive(r);return;}
...
}static void
ngx_http_set_keepalive(ngx_http_request_t *r){//如果发现是pipeline请求,判断条件是缓存区里有N和N+1个请求同时存在if (b->pos < b->last) {/* the pipelined request */}// 本次请求已经结束,开始释放request对象资源r->keepalive = 0;ngx_http_free_request(r, 0);c->data = hc;// 如果尝试读取keep-alive的socket返回值不对,可能是客户端close了。那么就关闭socketif (ngx_handle_read_event(rev, 0) != NGX_OK) {ngx_http_close_connection(c);return;}//开始正式处理pipeline...rev->handler = ngx_http_keepalive_handler;...// 设置了一个定时器,触发时间是keepalive_timeout的设置ngx_add_timer(rev, clcf->keepalive_timeout);...}static void
ngx_http_keepalive_handler(ngx_event_t *rev){// 发现超时则关闭socketif (rev->timedout || c->close) {ngx_http_close_connection(c);return;}// 读取keep-alive设置从socketn = c->recv(c, b->last, size);if (n == NGX_AGAIN) {if (ngx_handle_read_event(rev, 0) != NGX_OK) {ngx_http_close_connection(c);return;}...}//此处尚有疑惑?ngx_reusable_connection(c, 0);c->data = ngx_http_create_request(c);// 删除定时器ngx_del_timer(rev);// 重新开始处理请求rev->handler = ngx_http_process_request_line;ngx_http_process_request_line(rev);
}

参考资料

  • http://nginx.org/en/docs/http/ngx_http_core_module.html

转载于:https://www.cnblogs.com/roy-blog/p/8340954.html

理解HTTP之keep-alive(转)相关推荐

  1. linux tcp keepalive,Linux下TCP的Keepalive相关参数学习

    一 基本原理 TCP的Keepalive可以简单理解成为keep tcp alive,用来检测TCP sockets的连接是否正常或是已经断开. Keeplived的原理很简单,当建立一个TCP连接时 ...

  2. 深入理解Ribbon之源码解析

    什么是Ribbon Ribbon是Netflix公司开源的一个负载均衡的项目,它属于上述的第二种,是一个客户端负载均衡器,运行在客户端上.它是一个经过了云端测试的IPC库,可以很好地控制HTTP和TC ...

  3. Activity采用栈式管理的理解

    本文来自:安卓航班网 Android针对Activity的管理使用的是栈,就是说某一个时刻只有一个Activity处在栈顶,当这个Activity被销毁后,下面的Activity才有可能浮到栈顶,或者 ...

  4. 《深入理解Java虚拟机》-----第3章 垃圾收集器与内存分配策略

    Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的人想进去,墙里面的人却想出来. 3.1 概述 说起垃圾收集(Garbage Collection,G ...

  5. 深入理解JVM之二:垃圾收集器概述

    前言 我们知道Java的内存区域分为程序计数器.虚拟机栈.本地方法栈.Java堆和方法区,而且其中的程序计数器.虚拟机栈和本地方法栈都是线程独立的,也就是说这三块内存区域的生命周期与线程是同生共死的. ...

  6. 《深入理解java虚拟机》学习笔记四/垃圾收集器GC学习/一

    Grabage Collection      GC GC要完毕的三件事情: 哪些内存须要回收? 什么时候回收? 怎样回收? 内存运行时区域的各个部分中: 程序计数器.虚拟机栈.本地方法栈这3个区域随 ...

  7. 课时 16 深入理解 etcd:基于原理解析(曾凡松)

    本文将主要分享以下三方面的内容: 第一部分,会为大家介绍 etcd 项目发展的整个历程,从诞生至今 etcd 经历的那些重要的时刻: 第二部分,会为大家介绍 etcd 的技术架构以及其内部的实现机制, ...

  8. 使用java理解程序逻辑 第十二章_Java弱引用的理解与使用

    Java弱引用的理解与使用 WeakReference 前言 看到篇帖子, 国外一个技术面试官在面试senior java developer的时候, 问到一个weak reference相关的问题. ...

  9. Eureka深入理解

    客户端负载均衡Ribbon,声明式的Http Client Feign,那我们回到Eureka上面去,我们对Eureka进行一些补充,对他进行一些更深入的理解,我们来看Eureka的文档Service ...

  10. TCP的FIN_WAIT1状态理解|深入理解TCP

    原文链接: https://blog.csdn.net/dog250/article/details/81697403 近期遇到一个问题,简单点说,主机A上显示一条ESTABLISHED状态的TCP连 ...

最新文章

  1. 您知道为何要采用固定的迭代周期吗
  2. 动态添加跨行表格_手把手教你制作Excel动态统计表格,主管看了都会竖起大拇指!-Office教程...
  3. 算法面试:栈实现队列的方案
  4. MySQL 备份和恢复
  5. Option键用的好,鼠标用的少(这6个你绝对不知道的...)
  6. Python3 从零单排7_模块ossys
  7. 沈向洋、王海峰候选中国工程院院士!计算机领域7位入围增选
  8. TensorFlow tf.data.Dataset
  9. 接口测试——接口测试流程
  10. Linux find xargs rm .orig
  11. 用Java实现修改头像
  12. Redis之连接redis服务命令
  13. 计算机并口被禁用,电脑并口被禁用怎么办
  14. stm32Cubemx USB虚拟串口
  15. 单表(sqlserver不支持)、整库,支持本地和远程备份
  16. 微信视频号视频保存,微信视频号视频下载的方法
  17. 好玩的Canvas射箭小游戏
  18. 运用计算机巧记英语词汇,词根词缀法巧记考研英语词汇:词根graph-(写)
  19. 系统学习NLP(三十一)--基于CNN句子分类
  20. goland + dlv

热门文章

  1. 信创办公--基于WPS的Word最佳实践系列(图文环绕方式)
  2. Smtplib之发邮件模块
  3. java怎么生成apk文件,【连载】聊聊 APK(四) —— 脱离 AS 手工创造 APK 文件
  4. 怎么进入python 的venv文件夹_mac下Python关于venv 的使用
  5. html中怎么把文字环绕圆形,Photoshop如何制作环绕圆形路径文字(章环绕的圆形文字)及使用技巧记录...
  6. 机器学习 --- 刘建平整理
  7. CSDN博客打不开的解决办法
  8. 献上一串Python代码,拿去冲顶百万大奖吧!王思聪周鸿祎这回真要哭晕了
  9. WPS表格奇偶数页打印怎么设置?如何只打印奇数页?
  10. DruidDataSource理解数据库Mysql超时设置