情景再现

近期发现网站访问变慢,经常会出现请求无法响应的问题,一个请求长时间没有返回,导致页面出现504(Gateway Timeout),我们使用的nodejs+ngnix(反向代理)。

猜测原因

  服务器内存使用过高,导致服务器处理缓慢?

  并发请求过多导致请求缓慢?

...

定位问题

  查看服务器cpu和内存使用情况:发现服务器的cpu空闲率为95%左右,内存使用率在40%~60%。会不是内存使用过高导致的呢?我们重启了nodejs服务,此时我们观察到内存使用率有所减少在20%~40%左右,结果并没有什么用,访问依旧很慢。

  是不是请求数过多导致的呢?查看服务器日志,发现每分钟的请求量级并没有特别高,应该不是这个问题。

  因为我们使用了nginx反向代理,就像看看是不是nginx服务器的配置问题。经过抓包查看,发现部分请求的时间有几十毫秒还有几十秒的,当达到60秒的时候,服务器出现504错误。(proxy_connect_timeout,proxy_read_timeout,proxy_send_timeout,在nginx中,这些的默认配置是60s,所以一旦请求超过一分钟没有响应,服务器就直接返回504)再三检查nginx配置,没有发现能够改变这个问题。

  查看nodejs服务,检查是否我们代码层的逻辑导致服务器没有响应,触发nginx的超时。经过对代码的测试,发现我们有一个发布上线的逻辑比较耗时,大概时间为5到6秒钟,这个过程需要依赖第三方的服务,所以处理时间长度过长,在用户发送请求时,部分用户需要经历这个过程。此时,访问其他页面的时候,就会出现这种情况。我们的做法是,将发布上线的逻辑,只在编辑的时候使用。普通用户访问的时候,使用上线生成的线上文件。你们一定觉得这样问题就可以解决了,其实这是一个导火索,与另外的一个问题同时导致了线上的pedding问题。

  上面这个问题解决之后,发现向上并没有任何太大的改观。同时发现还有一个请求,依赖其他的服务器,那就是数据库请求。我们重新审查了一下什么原因导致数据库查询请求过慢。我们查看了我们所有的数据库慢查询,发现一个共性,这些慢查询的表数据量都很大,同时我们并没有对这些表建立索引,导致查询很慢。经过简单的本地测试:设置过索引的查询,在一个几十万条数据的表中,查询时间1ms以内;未设置索引的情况下,同一个查询语句需要的时间是200ms左右,结果令人差异,竟然差距这么大。我们对线上的数据库表根据查询需求,设置了索引,结果得到了很大的改观,访问速度有了显著的提高,基本上很快就有了响应。

  此时,线上的问题得到了初步的解决。

思考

  通过上面的探索我们发现,一般出现一个请求pedding或者是504的情况,是因为服务器处理的太慢,无法快速响应,如果服务器再不能并发处理的话,可能就会出现这种情况,所以我们需要优化我们服务端处理的速度。

  针对这种情况,优化我们线上的逻辑:

  优化建表逻辑:考虑主键、外键、索引等情况,优化数据库请求

  优化服务端逻辑:优化发布上线逻辑,不过度依赖第三方服务,如果需要依赖的话,尽量采用子进程完成,不影响主进程的响应;与此同时,完成多服务器同步问题,不需要用户在访问时,再进行生成,导致请求阻塞。

  其他性能优化:资源静态化,资源加载等等问题

参考资料:
https://nodejs.org/api/http.html#http_class_http_agent
http://melon.github.io/blog/2014/12/08/nodejs-agent-and-size-limit-of-get-method/

记一次pending请求问题查找过程的更多相关文章

  1. 在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程)

    在浏览器中简单输入一个网址,解密其后发生的一切(http请求的详细过程) 原文链接:http://www.360doc.com/content/14/1117/10/16948208_42571794 ...

  2. 一个http请求的详细过程

    一个http请求的详细过程 我们来看当我们在浏览器输入http://www.mycompany.com:8080/mydir/index.html,幕后所发生的一切. 首先http是一个应用层的协议, ...

  3. HTTP请求响应的过程

    1. TCP/IP协议分层结构 应用层(含括了OSI七层中的上三层,分别为应用层,表示层, 会话层):DNS,  URI,  HTML,  HTTP,  TLS/SSL,  SMTP,   POP,  ...

  4. 记一次mysql请求超时甩锅历程

    今天下午业务找我说是线上环境一个mysql库很慢,请求出现了大量的超时,让帮忙看看,以下为查找过程及甩锅过程. 1. mysql请求超时,ok,我们所有线上mysql都是开启了慢查询日志的,查找慢查询 ...

  5. Asp.net MVC进入请求管道的过程

    Asp.net MVC进入请求管道的过程 Asp.Net MVC 跟AspNet 入口解释 Asp.Net MVC请求处理过程 mvc 请求模型 mvc的原理 mvc模型 NewMVCPipleLin ...

  6. php中include包含文件路径查找过程

    首先,“路径”分为三种: 1.绝对路径,以/开头(unix系统)或c:等盘符开头(windows系统). 2.相对路径,以.开头,有./(当前目录)和../(上级目录). 3.其他路径,不是绝对路径和 ...

  7. AJAX异步请求原理和过程

    AJAX 指异步 JavaScript 及 XML(Asynchronous JavaScript And XML),它不是一种新的编程语言,而是一种使用现有标准的新方法. AJAX 基于 JavaS ...

  8. HiPAC高性能规则匹配算法之查找过程

    收到一封邮件,有位朋友认为我误解了nf-HiPAC.如此的一个高性能算法怎能被什么传统的hash,tree之类的胁迫.是啊.HiPAC是一个非常猛的算法.文档也比較少,这就更加添加了其神奇感,可是这决 ...

  9. Spring MVC 原理探秘 - 一个请求的旅行过程

    1.简介 在前面的文章中,我较为详细的分析了 Spring IOC 和 AOP 部分的源码,并写成了文章.为了让我的 Spring 源码分析系列文章更为丰富一些,所以从本篇文章开始,我将来向大家介绍一 ...

随机推荐

  1. [转] gdb 查看vector, list, map 内容

    转:http://blog.chinaunix.net/uid-13982689-id-34282.html先下载gdb_stl_utils.tar.gz, extract it, and run m ...

  2. Java基础知识强化之IO流笔记01:异常的概述和分类

     IO流操作的时候会出现很多问题,java中叫作异常,所以我们先介绍一下异常: 1. 程序的异常:Throwable(Throwable类是java中所有异常或错误的超类) (1)严重问题:Error ...

  3. 通过yum升级CentOS/RHEL最小化安装

    1.如果你有安装CentOS / RHEL最小服务器安装,您可能有很多麻烦没有安装包 2.有一种方法来安装所有的包,需要一个基本的服务器,使用yum groupinstall命令 3.从最小的安装基本 ...

  4. linux定时任务2-at命令

    定时执行命令: [root@rheltest1 ~]# at now + 1 minute //一分钟后执行下面的任务 at> date >> /tmp/test_date.log ...

  5. Freemarker常用技巧(三)

    freemarker模板解析过程 例如:一个freemarker表达式<body> ${hello} </body>,会被解析成三个部分,分别是<body>${he ...

  6. poj 3671 Dining Cows (Dp)

    /* 一开始并没有想出On的正解 后来发现题解的思路也是十分的巧妙的 还是没能把握住题目的 只有1 2这两个数的条件 dp还带练练啊 ... */ #include<iostream> # ...

  7. Examples_06_02(android)DDMS的data文件中没有显示文件。

    以前这里不显示music.cfg.通过Reset adb,就显示了. 查看虚拟机运行时里面的文件,进入adb.exe目录: E:\TDDOWNLOAD\adt-bundle-windows-x86-2 ...

  8. centos安装redis-3.2.3

    这次介绍的是在虚拟机centos下安装redis-3.2.3 首先进入官网http://redis.io/download

  9. osg三维重建的两种方法剖析:三角面片(osgUtil::DelaunayTriangulator)和四角面片(osg::HeightField) (2)

    // perform very basic sanity-check validation on a heightfield.bool validateHeightField(osg::HeightF ...

  10. Android导入项目时出现红色感叹号

    导入一个新的项目后,丢失android.jar文件 解决方法:在项目名称上单击右键,选择Properties,再选择Android,再在其中选择一个project build target,点击确定之 ...