理解TCP之Keepalive
理解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要从短连接到长连接最简单演变需要做如下改进:
- client发出的HTTP请求头需要增加Connection:keep-alive字段
- 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.c
static 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了。那么就关闭socket
if (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){
// 发现超时则关闭socket
if (rev->timedout || c->close) {
ngx_http_close_connection(c);
return;
}
// 读取keep-alive设置从socket
n = 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);
}
参考资料
from: http://www.firefoxbug.com/index.php/archives/2805/
理解TCP之Keepalive的更多相关文章
- 理解HTTP之keep-alive
理解HTTP之keep-alive 在前面一篇文章中讲了TCP的keepalive,这篇文章再讲讲HTTP层面keep-alive.两种keepalive在拼写上面就是不一样的,只是发音一样,于是乎大 ...
- 理解HTTP之keep-alive(转)
理解HTTP之keep-alive 在前面一篇文章中讲了TCP的keepalive,这篇文章再讲讲HTTP层面keep-alive.两种keepalive在拼写上面就是不一样的,只是发音一样,于是乎大 ...
- 浅谈Http长连接和Keep-Alive以及Tcp的Keepalive
原文:https://blog.csdn.net/weixin_37672169/article/details/80283935 Keep-Alive模式: 我们知道Http协议采用“请求-应答”模 ...
- 结合Wireshark捕获分组深入理解TCP/IP协议栈
摘要: 本文剖析了浏览器输入URL到整个页面显示的整个过程,以百度首页为例,结合Wireshark俘获分组进行详细分析整个过程,从而更好地了解TCP/IP协议栈. 一.俘获分组 1.1 准 ...
- TCP的keepalive和应用层的heart
从长链接说起 TCP是长链接的,也就是说连接建立后,及时数年没有通信连接仍然存在.这样做的好处是:免去了DNS解析的时间,连接建立等时间,大大加快了请求的速度,同时也有利于接受服务器的实时消息.但前提 ...
- 简单理解TCP/IP协议
一.什么是TCP/IP TCP/IP是一个协议族,是因为TCP/IP协议包括TCP.IP.UDP.ICMP.RIP.TELNETFTP.SMTP.ARP.TFTP等许多协议,这些协议一起称为TCP/I ...
- 如何理解TCP的三次握手协议?
• TCP是一个面向链接的协议,任何一个面向连接的协议,我们都可以将其类比为我们最熟悉的打电话模型. 如何类比呢?我们可以从建立和销毁两个阶段分别来看这件事情. 建立连接阶段 首先,我们来看看TCP中 ...
- 深入理解TCP建立和关闭连接
建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...
- TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗?
大家好,我是小林. TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗? 这是个好问题,应该有不少人都会搞混,因为这两个东西看上去太像了,很容易误以为是同一个东西. ...
随机推荐
- h5新API之WebStorage解决页面数据通信问题
localStorage相信大家都不陌生,今天我们要讨论的不是怎么存储数据,获取数据.而是看看WebStorage的一些妙用,相信大家在开发中遇到过这样一个场景,一个页面中嵌套一个iframe,ifr ...
- java中一个Map要找到值Value最小的那个元素的方法
import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map ...
- 错误/异常:java.io.FileNotFoundException: .\src\db.properties (系统找不到指定的路径。);的解决方法
1.异常视图 2.解决方法 与之相关的部分代码: static{ try { //读取db.properties Properties props = new Properties(); FileIn ...
- Java内存泄漏问题
1:java中垃圾回收机制主要完成下面两件事情: 跟踪并监控每个java对象,当某个对象处于不可达状态时,回收该对象所占的内存 清理内存分配,回收过程中产生的内存碎片 2:对于JVM的垃圾回收机制来说 ...
- cf1108e 线段树区间更新+扫描线
/* 有点像扫描线 思路:从左到右枚举每个点,枚举到点i时,把所有以i为起点的区间的影响删去 再加上以i-1为结尾的区间的影响 */ #include<bits/stdc++.h> usi ...
- python 全栈开发,Day128(创建二维码,扫码,创建玩具的基本属性)
昨日内容回顾 1.app播放音乐 plus.audio.createPlayer(文件路径/URL) player.play() 播放音乐 player.pause() 暂停播放 player.res ...
- OSGI命令
OSGi的一些支离破碎的知识 以下命令说明内容来自于Eclipse的OSGi框架Equinox. ---Controlling the OSGi framework---launch - start ...
- javafx基于使用fxml布局的tableview数据绑定用法
来个简单明了的 fxml的tableview数据绑定和java代码方式的数据绑定很像,不同的在于要有一到映射 首先看个目录 1.界面文件Sample.fxml <?xml version=&qu ...
- 在django中使用FormView,success_url死活不能生效的问题
真的不知道是怎么回事, 以前都是手动的, form使用modelform. view使用createview. 今天写新系统时,为了更灵活. form使用form,(这样一来,可以在form是随便按数 ...
- 046 hiveserver2以及beeline客户端的使用
一:开启服务 1.启动前端的hiveserver2 按住ctrl+c就可以结束这个服务. 2.怎么知道已经开启的服务 如果进程在后台,可以查出来,kill这些进程. 3.后端开启服务 二:beelin ...