转自http://qa.blog.163.com/blog/static/19014700220134771052763/

Keep-Alive即俗称的长连接,使客户端到服务端建立的连接持续有效,当对服务器发起后续请求时,Keep-Alive功能可以复用先前使用过的连接,减少了重新建立连接所需的开销。通常使用HTTP协议采用的是请求应答模式,客户端到服务端的一次请求完成了,它们之间的连接也随之关闭。在某些应用场景下,比如后端RESTful服务,就需要保持住连接,这时就可以启用HTTP Keep-Alive。

下图就是一个比较常见的服务架构。后端服务器提供RESTful服务,需要和前端服务器保持有限的长连接。由于中间架设了代理服务器,即需要前端服务器和代理之间,代理和后端服务器之间都保持连接。另外,最终用户也可以通过浏览器方便地访问后端服务,不过这两者之间就不需要保持连接了。

 

图1:典型实例

下面主要介绍一个实例,其中代理服务器以nginx为例,后端服务器以tomcat为例。在这种情况下,对tomcat来说nginx是它的一个client,因此我们需要配置nginx的upstream模块

upstream backend {

server tomcat_ip:8080;

}

但是很奇怪,我们用ss -s在服务器上观察到了很多closed或者time_wait状态的TCP连接,似乎长连接并没有生效。

在tomcat的监听端口上用tcpdump抓包确认一下

sudo tcpdump tcp -i eth1 -t -s 0 -c 10000 and port 8080 -w tomcat.cap

把tomcat.cap导入到wireshark可以方便我们分析,追踪一个流看看,如下图,红色部分为请求,蓝色为应答,下同

 
图2:from nginx to tomcat TCP stream(keepalive未生效)

从请求和应答都存在HTTP头Connection: Keep-Alive上判断,我们的客户端已经使用了正确的协议。但在这个TCP连接上确实只处理了一次请求,如果Keep-Alive生效,TCP连接上应该存在多次请求应答。下图断开连接后重连的过程也间接说明了这点。

 
 图3:断开后重连过程的TCP报文

类似的,通过在nginx的监听端口上抓包排除了客户端的问题,如下图,在这个TCP连接上处理了多次请求。因此,应该从nginx上去找原因。

 
 图4:from client to nginx TCP stream(keepalive生效)

最终找到是Nginx的upstream模块未配置keepalive的原因,摘录官方文档的说明如下。该参数开启与上游服务器之间的连接池,其数值为每个nginx worker可以保持的最大连接数,默认不设置,即nginx作为客户端时keepalive未生效。

Activates cache of connections to upstream servers

The connections parameter sets the maximum number of idle keepalive connections to upstream servers that are retained in the cache per one worker process. When this number is exceeded, the least recently used connections are closed

设置该参数后

upstream backend {

server tomcat_ip:8080;

keepalive 256;

}

重新测试并验证,结果如下图所示

 
 图5:from nginx to tomcat TCP stream(keepalive生效)

此时继续用ss –s观察服务器的连接状态,仍然会出现连接关闭的情况。这又是什么原因呢?求助google大神,发现还是配置问题。

位置

参数名

默认值

Tomcat

Server.xml

Connector标签下的maxKeepAliveRequests

100

Nginx

Server模块

keepalive_requests

100

表1:keepalive requests配置

两者都是其作为server时生效的配置,即作为server当在一个keepalive的连接上请求次数超过该配置值,server会断开连接,即使它是keepalive的。当然server端判断一个keepalive连接是否需要关闭的依据还有超时时间,这里不详细说明了。

好了,就是这样,看来简单的一个Keep-Alive概念,在实际应用中要用对也是十分不易的。

你真的用上keepalive了吗的更多相关文章

  1. centos7上keepalived的安装和配置

    1.环境规划1)master:node1,centos7.5,eth0:192.168.1.11,eht1:10.10.1.11,keepalive2)backup:node1,centos7.5,e ...

  2. 上传文件到Ubuntu阿里云服务器(windows到Linux的文件上传)

    上传文件到Ubuntu阿里云服务器(windows到Linux的文件上传) 最近在阿里云上面租了一个轻量级服务器玩玩,学习学习怎么在服务器部署网站.然后嘞,在想要将本地文件上传到服务器的时候,自己研究 ...

  3. vue keep-alive 遇见 vue-router

    keep-alive 遇见 vue-router ·keep-alive 是Vue内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 ·routre-view也是一个组件,如果直接被包在kee ...

  4. 搭建vpn环境:centos7+openvpn

    vpn的含义:virtual private network vpn的作用/使用场景:最常见的一个作用,你通过公网来访问某个局域网里的主机/服务,其实就是搭建一个隧道,用公网传递你的数据包,等数据包到 ...

  5. 非技术1-学期总结&ending 2016

    好久好久没写博客了,感觉动力都不足了--12月只发了一篇博客,好惭愧-- 今天是2016年最后一天,怎么能不写点东西呢!! 学期总结 大学中最关键一年的第一个学期,共4个月.前20天在学网络方面的,当 ...

  6. 遭遇Web print

    一直都知道Web打印还不太成熟,以前IE横行时,普遍都是采用打印相关的ActiveX控件,有些国产厂家做得不错,只是那时还没有付费能力,没有太多关注.而纯粹基于Web标准的打印,浏览器对CSS pri ...

  7. VR技术的探索阶段

    转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 早在1929年,在长期使用教练机训练器(机翼变短,不能产生离开地面所需的足够提升力)进行飞行训练之后,E ...

  8. 浅谈HTTP事务的一个过程

    一个腾讯在职的朋友问道,当我们在浏览器的地址栏输入 www.baidu.com ,然后回车,这一瞬间页面发生了什么?下面以谷歌浏览器一一解释. 一.域名解析 首先Chrome浏览器会解析www.bai ...

  9. C 最熟悉的陌生人 (纪念当年就读的梅州市江南高级中学)

    最熟悉的陌生人 作者:张慧桥 “枪与玫瑰” 我送走了“蝶恋花”,犹有一种身在梦中的感觉,昨晚的宿醉让我只觉得头晕乎乎的很不舒服,想想自己连澡都还没洗呢,便去洗了个冷水澡. 煮了杯浓浓的咖啡喝了下去,我 ...

随机推荐

  1. NOI十连测 第四测 T2

    思路:线段树套可持久化treap,可持久化treap我还是第一次听说.. 改题的时候没看数据范围..乱开数组T_T #include<algorithm> #include<cstd ...

  2. QObject的event函数就可以改写对消息的处理

    一个既自己处理Tab事件又自己处理某些按键事件,然后将其它不需自己处理的事件转发给基类处理: bool MyWidget::event(QEvent *event){ if (event->ty ...

  3. HTTP -> Asp.net (第一篇)

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

  4. ios7 UITableView底线右移

    在ios7上UITableView底线右移了,我们可以通过添加代码来让它铺满整个屏幕的宽,在使用前要加上判断是否有这个方法 if ([_tableView respondsToSelector:@se ...

  5. CSS清除浮动_清除float浮动

    2.clear:both清除浮动为了统一样式,我们新建一个样式选择器CSS命名为“.clear”,并且对应选择器样式为“clear:both”,然后我们在父级“</div>”结束前加此di ...

  6. .NET MySQL的参数化查询

    MySqlConnection conn = new MySqlConnection(SqlConnnectString); MySqlCommand cmd = new MySqlCommand(& ...

  7. iOS框架介绍

    iOS框架介绍      Cocoa Touch   GameKit  实现对游戏中心的支持,让用户能够在线共享他们的游戏相关的信息  iOS设备之间蓝牙数据传输   从iOS7开始过期   局域网游 ...

  8. 【转】获取CID 和 LAC的方法

    原文地址:http://stackoverflow.com/questions/13399659/get-cellid-mcc-mnc-lac-and-network-in-ios-5-1 在iOS5 ...

  9. MVC思想架构的简单自定义UITableViewCell

         在iOS的开发过程中,架构思想是很重要的一部分,目前的主流应该分为MVC与MVVM两种,在这里不做过多的区分,有兴趣的同学可以看看唐巧大神的一篇文章<被误解的MVC和被神化的MVVM& ...

  10. autoresizing代码实现

    主要解决父子控件之间的布局关系: /*     Flexible 灵活的,自由的          typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) ...