一、问题

今天发现有一台服务器的内存飙升,然后有预警,立即排查,发现该服务内存使用达到了 2G ,询问开发,当天是否有活动,被告知没有,登陆 Pinpoint 发现该服务是有两台机器,并且所有的访问都是到那台内存飙升的机器上面。这就很清楚了,是所有请求到一台服务器,导致的,我们查看那台没有收到任何请求的服务器上,发现服务是启动了,端口也在监听的。

启动日志:

2019-11-05 16:07:09.024 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)

二、故障排查

2.1 第一次排查(服务没有正常启动)

启动日志里面也没有任何异常的报错。我就以为服务是已经 启动了,可能是 Nginx 的问题,登陆到 Nginx 服务器进行查看 ,是配置了 fair 插件的,想着是不是 fair 判断 那台服务器内存不够就不把请求转发过去了,我们就把 fair 这个插件去除了。然后 Nginx reload 了一下(16.26这个时间)。不到 一分钟,我 Pinpoint 发现 有访问到这个服务器上了,心想难道真的是这个问题导致的,不可能啊,然后我回到我 控制台(幸好我有个 tail -f ),然后发现下面的,日志。 到底是 fair 导致的还是 启动没有成功导致的。后面查阅昨天发版日志,发现昨天发版后,下面后面那三行日志就一直没打印,也就是一直没启动成功,但是正常的服务的那个服务器是有后面三行日志的。

当时启动打印的
2019-11-05 16:07:09.024 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)
后面打印的
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms

第一次排查结论

基于上面的情况,我们认为问题就是服务没有初始化成功,应该是由于服务器内存不足导致的。也可能是和 Tomcat 启动慢的原因是一致的。

2.2 第二次排查

再次排障后发现这个问题取决于 Nginx 与应用 两者。

场景

我们有另一个服务也部署在两个服务器上,一个服务器上启动后正常提供服务,另外一台服务一直没有接收到请求,也没有处理任何东西,日志如下:

当我们启动 spring boot 框架的服务后。日志出现了

2019-11-05 16:07:09.024 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)

一直停留在这个界面。

然后我们通过 模拟请求,也就是在服务器上通过 curl ip+port, 立马就打印出来日志。

2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms

第二次排查结论

第一就是出现在 Nginx 上,我们 Nginx 上使用了 fair 模块(github链接)。 fair 模块采用的不是负载均衡默认的轮询的均衡算法,而是可以根据页面大小、加载时间长短智能的进行负载均衡。

推测是fair 将其中一台服务器直接屏蔽掉了(也就是我们没有收到请求的机器),然后就把所有的请求发送到另外一台机器了。

怪异之处

屏蔽掉的服务器内存和CPU 都是正常状态(内存还有剩余),为什么会屏蔽掉它,fair模块算法是有什么问题?

-- 去监控下请求返回的时常,对比下另外一台。(对比后无异常,返回都在 1s 内)

  • 为什么启动后接受了请求才会打印类似初始化的日志。
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms

询问开发后: 得到答复:

2019-11-05 16:07:09.024 [main] INFO  o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.061 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-18096"]
2019-11-05 16:07:09.062 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2019-11-05 16:07:09.122 [main] INFO o.s.b.c.e.t.TomcatEmbeddedServletContainer - Tomcat started on port(s): 18096 (http)

上面的日志,就是表明已经启动了,web 容器 Tomcat 已经 ok了。可以正常提供服务。

那么下面那个日志是怎么回事?

2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO  o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2019-11-05 16:26:53.435 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2019-11-05 16:26:53.473 [http-nio-18096-exec-5] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 38 ms

原因是(开发告知): 这个是DispatcherServlet初始化,当第一个请求过来后,它才初始化。

三、总结

上述的故障最后的问题定位于 : Nginx 的 fair插件导致的问题,与服务本身没有任何关系,但是 fair插件的具体的问题没有去细究。

记录一次Nginx使用第三方模块fair导致的线上故障排错的更多相关文章

  1. nginx增加第三方模块

    增加第三方模块 ============================================================ 一.概述nginx文件非常小但是性能非常的高效,这方面完胜ap ...

  2. nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下)

    nginx 的第三方模块ngx_http_accesskey_module 来实现下载文件的防盗链步骤(linux系统下),安装Nginx和HttpAccessKeyModule模块(参考LNMP环境 ...

  3. Debian 为nginx增加第三方模块

    为nginx增加第三方模块需要重新编译nginx的,但是debian在安装nginx的时候做了很多事情,比如systemd,/etc/nginx/里的各种文件,所以我们最好在debian源代码包的基础 ...

  4. nginx 安装第三方 模块

    查看nginx在安装时开启了哪些模块 如果你nginx是rpm包安装的,直接用如下命令nginx -V 如果你是源码包编译安装,假如你的安装路径是/usr/local/nginx,那么你可以使用: / ...

  5. nginx安装第三方模块的方法

    nginx第三方模块安装方法: ./configure --prefix=/你的安装目录 --add-module=/第三方模块目录 以安装fair模块实例 下载fair安装包并解压 1.在未安装ng ...

  6. nginx安装第三方模块echo

    要使用第三方模块ngx_echo的功能,请重新配置添加到nginx插件中 ##下载第三方模块 wget https://github.com/openresty/echo-nginx-module/a ...

  7. yum安装的Nginx添加第三方模块支持tcp

    需求:生产有个接口是通过socket通信.nginx1.9开始支持tcp层的转发,通过stream实现的,而socket也是基于tcp通信. 实现方法:Centos7.2下yum直接安装的nginx, ...

  8. nginx 安装第三方模块(lua)并热升级

    需求: nginx上将特定请求拒绝,并返回特定值. 解决办法: 使用lua脚本,实现效果. 操作步骤: 安装Luajit环境 重新编译nginx(目标机器上nginx -V 配置一致,并新增两个模块n ...

  9. nginx安装第三方模块

    原已经安装好的nginx,现在需要添加一个未被编译安装的模块 举例说明:安装第三方的ngx_cache_purge模块(用于清除指定URL的缓存) nginx的模块是需要重新编译nginx,而不是像a ...

随机推荐

  1. VMware 14 激活密钥

    VMware 14 激活密钥 FF31K-AHZD1-H8ETZ-8WWEZ-WUUVA CV7T2-6WY5Q-48EWP-ZXY7X-QGUWD

  2. [Linux kali] linux kali [KDE]一些软件切换输入法无效

    #开始 今天最终是在实体机安装了Kali Kali的默认桌面是GNOME桌面 但是用久了windows桌面用这个实在是不习惯 然后看到了kali有自带KDE版本的 然后就下载了一个尝尝鲜 之前在Deb ...

  3. Euler Sums系列(一)

    \[\Large\sum_{n=1}^{\infty} \frac{H_{n}}{2^nn^4}\] \(\Large\mathbf{Solution:}\) Let \[\mathcal{S}=\s ...

  4. 吴裕雄 PYTHON 神经网络——TENSORFLOW 单隐藏层自编码器设计处理MNIST手写数字数据集并使用TensorBord描绘神经网络数据

    import os import numpy as np import tensorflow as tf import matplotlib.pyplot as plt from tensorflow ...

  5. Jmeter之cookie处理的2中方法

    不添加cookie会出现什么结果呢? 举例:1)登录 2)手机充值 2.登录HTTP请求 3.充值 4.查看结果树,登录是成功的,但是充值不成功,提示请先登录. 如何解决这个问题呢?添加Cookie管 ...

  6. mui下拉刷新 ios click事件无法响应问题

    使用mui的事件监听事件 tap mui("#pullrefresh").on('tap', '.ulDiv', function (event) {this.click();}) ...

  7. 【STM32H7教程】第58章 STM32H7的硬件JPEG应用之图片解码显示

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第58章       STM32H7的硬件JPEG应用之图片解 ...

  8. Vue如何用虚拟dom进行渲染view的

    前提 vue版本:v2.5.17-beta.0 触发render vue在数据更新后会自动触发view的render工作,其依赖于数据驱动:在数据驱动的工作下,每一个vue的data属性都被监听,并且 ...

  9. Fluent_Python_Part2数据结构,03-dict-set,字典和集合

    字典和集合 dict和set都基于hash table实现 1. 大纲: 常见的字典方法 如何处理查找不到的键 标准库中dict类型的变种 set和fronzenset类型 Hash table的工作 ...

  10. 13 DFT变换的性质

    DFT变换的性质 线性性质 \[ \begin{aligned} y[n]&=ax[n]+bw[n]\xrightarrow{DFT}Y[k]=\sum_{n=0}^{N-1}(ax[n]+ ...