背景是一次线上故障

项目类型vue ssr

与server的数据交互用的http内网域名方案

在5月发生了一次线上CPU100%的问题,直接导致了NodeServer 500。

最终解决办法是:

1、请求超时时间timeout 5s->1s

2、开启Keep-Alive。

问题排查

首先我们重启服务短暂解决了不可访问的问题,既然是线上问题,一定不能忽视,我们开始通过一些手段复现问题。

查看nginx log

通过log分析我们发现,有些接口耗时是比较长的,而node ssr server是需要等待这些接口返回数据后才能把计算好的渲染结果返回给用户,跟相关后端同学商量,提升接口质量,同时我们把timeout从5s改为1s

qps

简单的qps测试,我们发现随着qps上升服务器cpu上涨特别快,相比较timeout修改之前已有了明显提升,但是明显感觉服务还是不够用,具体qps数值暂不透露。

分析服务器请求连接数

通过一些命令我们发现请求连接数竟然有6k+,很可怕的一个数字,而我们的qps是远远小于6k的,猜测很可能是每次请求都建立了新的链接,那就开始着手优化吧,就想到了Keep-Alive。

Keep-Alive模式

HTTP协议采用“请求-应答”模式,不开启KeepAlive模式时,每个req/res客户端和服务端都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);当开启Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

Keep-Alive优点

从上面的分析来看,启用Keep-Alive模式肯定更高效,性能更高。因为避免了建立/释放连接的开销。下面是RFC 2616上的总结:

  1. By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts.
  2. HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time.

    Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network.
  3. Latency on subsequent requests is reduced since there is no time spent in TCP's connection opening handshake.
  4. HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old semantics after an error is reported.

RFC 2616(P47)还指出:单用户客户端与任何服务器或代理之间的连接数不应该超过2个。一个代理与其它服务器或代码之间应该使用超过2 * N的活跃并发连接。这是为了提高HTTP响应时间,避免拥塞(冗余的连接并不能代码执行性能的提升)。

在项目中开启

上面大概介绍了Http Keep-Alive模式和优点,接下来就是怎么在项目里引用了,因为我们用axios作为请求库,它支持httpAgent,只需设置这个参数即可,Keep-Alive选用的agentkeepalive,接入项目非常简单。部分事例代码如下:

const Agent = require('agentkeepalive')

const keepaliveAgent = new Agent({
maxSockets: 100,
maxFreeSockets: 10,
timeout: 60000,
freeSocketKeepAliveTimeout: 30000 // free socket keepalive for 30 seconds
})
...
$axios.defaults.httpAgent = keepaliveAgent

结论

在调整请求超时时间和开启Keep-Alive后,cpu100%的问题没有再次出现,qps压测的数值也让人相当放心。

关于KeepAlive还有TCP和HTTP的区别,具体不在本文详述,感兴趣的同学可以自行网上搜索学习。

浅谈HTTP Keep-Alive的更多相关文章

  1. TODO:浅谈pm2基本工作原理

    TODO:浅谈pm2基本工作原理 要谈Node.js pm2的工作原理,需要先来了解撒旦(Satan)和上帝(God)的关系. 撒旦(Satan),主要指<圣经>中的堕天使(也称堕天使撒旦 ...

  2. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  3. 浅谈 LayoutInflater

    浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...

  4. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  5. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  6. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  7. 浅谈angular2+ionic2

    浅谈angular2+ionic2   前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别.   1. 项目所用:angular2+ionic2 ...

  8. iOS开发之浅谈MVVM的架构设计与团队协作

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

  9. Linux特殊符号浅谈

    Linux特殊字符浅谈 我们经常跟键盘上面那些特殊符号比如(?.!.~...)打交道,其实在Linux有其独特的含义,大致可以分为三类:Linux特殊符号.通配符.正则表达式. Linux特殊符号又可 ...

  10. 浅谈Angular的 $q, defer, promise

    浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00  博客园-原创精华区 原文  http://www.cnblogs.com/big-snow/ ...

随机推荐

  1. iptables命令提取总结,包含扩展模块<取自朱双印博客>

    以下内容只是一些命令相关的,以朱双印博客中的iptables的教程提取出来的.纯粹只是命令的总结,如果需要看理论的知识,建议去看朱老师的博客,目前还没有看到写得比这个好的了. <http://w ...

  2. Numpy 创建数组

    ndarray 数组除了可以使用底层 ndarray 构造器来创建外, 也可以通过以下几种方式来创建. numpy.empty numpy.empty 方法用来创建一个指定形状(shape),数据类型 ...

  3. python3 第二十五章 - comprehensions(推导式)

    推导式(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的数据序列的结构体. 共有三种推导,在Python2和3中都有支持: 列表(list)推导式 字典(dict) ...

  4. s3c2440 nandflash 初始化

    1.什么是 nandflash ? FLASH闪存 闪存的英文名称是"Flash Memory",一般简称为"Flash",它属于内存器件的一种,是一种非易失性 ...

  5. jquery基础知识随笔

    <html> <head> <script type="text/javascript" src="/jquery/jquery.js&qu ...

  6. H5新特性---SVG--椭圆--直线--文本--滤镜(高斯滤镜--模糊)--地理定位

    今天的目标 3.1:h5新特性--SVG--椭圆 <ellipse rx="" ry=""  cx="" cy="" ...

  7. 去掉"You are running Vue in development mode"提示

    vue项目中报错: You are running Vue in development mode.Make sure to turn on production mode when deployin ...

  8. Codeforces 873 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 传送门 A题 传送门 题意: 一个人要做nnn件事,时间花费分别为a1,a2,...,an,a1≤a2≤a3≤...≤ana_1,a_2,...,a_n, ...

  9. BJOI2018 简要题解

    二进制 序列上线段树维护DDP好题. 题解可以看这篇 代码: #include<bits/stdc++.h> #define ri register int using namespace ...

  10. C#在SharePoint文档库下动态新增文件夹

    /// <summary> /// 在创建SP文库库下动态新增文件夹 /// </summary> /// <param name="spList"& ...